You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2019/12/16 11:38:40 UTC
[myfaces] branch master updated: MYFACES-4314 Introduce quarkus
extension
This is an automated email from the ASF dual-hosted git repository.
tandraschko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/master by this push:
new 76fc6e5 MYFACES-4314 Introduce quarkus extension
76fc6e5 is described below
commit 76fc6e5de249c679eabcf8fd3e81e4b8fbf52f03
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Mon Dec 16 12:38:32 2019 +0100
MYFACES-4314 Introduce quarkus extension
---
extensions/pom.xml | 43 +++
extensions/quarkus/deployment/pom.xml | 85 ++++++
.../deployment/ManagedPropertyBuildStep.java | 77 +++++
.../quarkus/deployment/MyFacesProcessor.java | 337 +++++++++++++++++++++
extensions/quarkus/pom.xml | 59 ++++
extensions/quarkus/runtime/faces-config.NavData | 6 +
extensions/quarkus/runtime/pom.xml | 102 +++++++
.../quarkus/runtime/MyFacesRecorder.java | 68 +++++
.../quarkus/runtime/QuarkusFacesInitilializer.java | 60 ++++
.../runtime/application/QuarkusApplication.java | 59 ++++
.../application/QuarkusApplicationFactory.java | 50 +++
.../runtime/exception/QuarkusExceptionHandler.java | 58 ++++
.../exception/QuarkusExceptionHandlerFactory.java | 37 +++
.../producer/ManagedPropertyBeanCreator.java | 48 +++
.../runtime/scopes/QuarkusFacesScopeContext.java | 90 ++++++
.../runtime/scopes/QuarkusFlowScopedContext.java | 91 ++++++
.../runtime/scopes/QuarkusViewScopeContext.java | 90 ++++++
.../scopes/QuarkusViewTransientScopeContext.java | 91 ++++++
.../runtime/spi/QuarkusAnnotationProvider.java | 52 ++++
.../quarkus/runtime/spi/QuarkusCdiELResolver.java | 125 ++++++++
.../runtime/spi/QuarkusELResolverBuilder.java | 45 +++
.../runtime/spi/QuarkusFacesFlowProvider.java | 38 +++
.../runtime/spi/QuarkusFactoryFinderProvider.java | 103 +++++++
.../spi/QuarkusFactoryFinderProviderFactory.java | 34 +++
.../runtime/spi/QuarkusInjectionProvider.java | 50 +++
.../src/main/resources/META-INF/faces-config.xml | 30 ++
.../org.apache.myfaces.spi.AnnotationProvider | 1 +
.../org.apache.myfaces.spi.FacesFlowProvider | 1 +
extensions/quarkus/showcase/pom.xml | 137 +++++++++
.../quarkus/showcase/StartupListener.java | 33 ++
.../core/extensions/quarkus/showcase/view/Car.java | 120 ++++++++
.../quarkus/showcase/view/CarService.java | 102 +++++++
.../quarkus/showcase/view/InputController.java | 46 +++
.../quarkus/showcase/view/LazyCarDataModel.java | 112 +++++++
.../quarkus/showcase/view/LazySorter.java | 48 +++
.../extensions/quarkus/showcase/view/LazyView.java | 67 ++++
.../showcase/view/MethodHandleELResolverBean.java | 88 ++++++
.../quarkus/showcase/view/MyBacking.java | 53 ++++
.../quarkus/showcase/view/MyCollection.java | 26 ++
.../quarkus/showcase/view/MyCollectionModel.java | 39 +++
.../quarkus/showcase/view/MyConverter.java | 39 +++
.../quarkus/showcase/view/MyConverterManaged.java | 39 +++
.../quarkus/showcase/view/MyValidator.java | 42 +++
.../quarkus/showcase/view/SocketView.java | 65 ++++
.../resources/demo/images/car/Audi-big.gif | Bin 0 -> 5512 bytes
.../META-INF/resources/demo/images/car/Audi.gif | Bin 0 -> 4585 bytes
.../META-INF/resources/demo/images/car/BMW-big.gif | Bin 0 -> 6900 bytes
.../META-INF/resources/demo/images/car/BMW.gif | Bin 0 -> 5425 bytes
.../resources/demo/images/car/Fiat-big.gif | Bin 0 -> 8993 bytes
.../META-INF/resources/demo/images/car/Fiat.gif | Bin 0 -> 5656 bytes
.../resources/demo/images/car/Ford-big.gif | Bin 0 -> 5400 bytes
.../META-INF/resources/demo/images/car/Ford.gif | Bin 0 -> 4960 bytes
.../resources/demo/images/car/Honda-big.gif | Bin 0 -> 4371 bytes
.../META-INF/resources/demo/images/car/Honda.gif | Bin 0 -> 4199 bytes
.../resources/demo/images/car/Jaguar-big.gif | Bin 0 -> 9160 bytes
.../META-INF/resources/demo/images/car/Jaguar.gif | Bin 0 -> 3971 bytes
.../resources/demo/images/car/Mercedes-big.gif | Bin 0 -> 6109 bytes
.../resources/demo/images/car/Mercedes.gif | Bin 0 -> 4662 bytes
.../resources/demo/images/car/Renault-big.gif | Bin 0 -> 4955 bytes
.../META-INF/resources/demo/images/car/Renault.gif | Bin 0 -> 5052 bytes
.../resources/demo/images/car/Volkswagen-big.gif | Bin 0 -> 7743 bytes
.../resources/demo/images/car/Volkswagen.gif | Bin 0 -> 5580 bytes
.../resources/demo/images/car/Volvo-big.gif | Bin 0 -> 6909 bytes
.../META-INF/resources/demo/images/car/Volvo.gif | Bin 0 -> 5430 bytes
.../main/resources/META-INF/resources/index.xhtml | 64 ++++
.../main/resources/META-INF/resources/issue4.xhtml | 23 ++
.../resources/methodHandleELResolver.xhtml | 40 +++
.../main/resources/META-INF/resources/socket.xhtml | 60 ++++
.../main/resources/META-INF/resources/val.xhtml | 31 ++
.../src/main/resources/application.properties | 3 +
pom.xml | 1 +
71 files changed, 3208 insertions(+)
diff --git a/extensions/pom.xml b/extensions/pom.xml
new file mode 100644
index 0000000..c0f77bf
--- /dev/null
+++ b/extensions/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-core-project</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-extensions</artifactId>
+ <name>Apache MyFaces Core 3.0 - Extensions</name>
+ <description>
+ Apache MyFaces Core related extensions.
+ </description>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>quarkus</module>
+ </modules>
+
+</project>
diff --git a/extensions/quarkus/deployment/pom.xml b/extensions/quarkus/deployment/pom.xml
new file mode 100644
index 0000000..4709527
--- /dev/null
+++ b/extensions/quarkus/deployment/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.apache.myfaces.core.extensions</groupId>
+ <artifactId>myfaces-quarkus</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
+ <artifactId>myfaces-quarkus-deployment</artifactId>
+ <name>Apache MyFaces Core 3.0 - Extensions - Quarkus - Deployment</name>
+ <description>
+ Apache MyFaces Core deployment extension for Quarkus.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-core-deployment</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-arc-deployment</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-undertow-deployment</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-jsonp-deployment</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
+ <artifactId>myfaces-quarkus-runtime</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/ManagedPropertyBuildStep.java b/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/ManagedPropertyBuildStep.java
new file mode 100644
index 0000000..98c1d3a
--- /dev/null
+++ b/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/ManagedPropertyBuildStep.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.deployment;
+
+import java.util.UUID;
+
+import javax.faces.annotation.ManagedProperty;
+
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.AnnotationValue;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.Type;
+
+import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
+import io.quarkus.arc.processor.BuildExtension;
+import io.quarkus.arc.processor.BuiltinScope;
+import io.quarkus.arc.processor.InjectionPointInfo;
+import io.quarkus.deployment.annotations.BuildProducer;
+import org.apache.myfaces.core.extensions.quarkus.runtime.producer.ManagedPropertyBeanCreator;
+
+public class ManagedPropertyBuildStep
+{
+
+ public static void build(BeanRegistrationPhaseBuildItem beanRegistrationPhase,
+ BuildProducer<BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem> beanConfigurators)
+ {
+ for (InjectionPointInfo injectionPoint : beanRegistrationPhase.getContext()
+ .get(BuildExtension.Key.INJECTION_POINTS))
+ {
+ if (injectionPoint.hasDefaultedQualifier())
+ {
+ // Defaulted qualifier means no @ManagedProperty
+ continue;
+ }
+
+ AnnotationInstance managedProperty = injectionPoint.getRequiredQualifier(
+ DotName.createSimple(ManagedProperty.class.getName()));
+ if (managedProperty != null)
+ {
+ AnnotationValue value = managedProperty.value("value");
+ if (value == null)
+ {
+ continue;
+ }
+
+ Type requiredType = injectionPoint.getRequiredType();
+
+ beanConfigurators.produce(new BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem(
+ beanRegistrationPhase.getContext()
+ .configure(requiredType.name())
+ .qualifiers(managedProperty)
+ .scope(BuiltinScope.DEPENDENT.getInfo())
+ .types(requiredType)
+ .creator(ManagedPropertyBeanCreator.class)
+ .name(UUID.randomUUID().toString().replace("-", ""))
+ .defaultBean()
+ .param(ManagedPropertyBeanCreator.EXPRESSION, value.asString())));
+ }
+ }
+ }
+}
diff --git a/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/MyFacesProcessor.java b/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/MyFacesProcessor.java
new file mode 100644
index 0000000..5e76db9
--- /dev/null
+++ b/extensions/quarkus/deployment/src/main/java/org/apache/myfaces/core/extensions/quarkus/deployment/MyFacesProcessor.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.deployment;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.faces.application.ProjectStage;
+import javax.faces.application.StateManager;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.behavior.FacesBehavior;
+import javax.faces.convert.FacesConverter;
+import javax.faces.flow.FlowScoped;
+import javax.faces.flow.builder.FlowDefinition;
+import javax.faces.model.FacesDataModel;
+import javax.faces.push.PushContext;
+import javax.faces.render.FacesBehaviorRenderer;
+import javax.faces.render.FacesRenderer;
+import javax.faces.validator.FacesValidator;
+import javax.faces.view.ViewScoped;
+import javax.faces.view.facelets.FaceletsResourceResolver;
+import javax.faces.webapp.FacesServlet;
+
+import org.apache.myfaces.cdi.FacesScoped;
+import org.apache.myfaces.cdi.JsfApplicationArtifactHolder;
+import org.apache.myfaces.cdi.JsfArtifactProducer;
+import org.apache.myfaces.cdi.config.FacesConfigBeanHolder;
+import org.apache.myfaces.cdi.model.FacesDataModelManager;
+import org.apache.myfaces.cdi.view.ViewScopeBeanHolder;
+import org.apache.myfaces.cdi.view.ViewTransientScoped;
+import org.apache.myfaces.config.MyfacesConfig;
+import org.apache.myfaces.config.annotation.CdiAnnotationProviderExtension;
+import org.apache.myfaces.config.element.NamedEvent;
+import org.apache.myfaces.flow.cdi.FlowBuilderFactoryBean;
+import org.apache.myfaces.flow.cdi.FlowScopeBeanHolder;
+import org.apache.myfaces.push.cdi.PushContextFactoryBean;
+import org.apache.myfaces.push.cdi.WebsocketApplicationBean;
+import org.apache.myfaces.push.cdi.WebsocketChannelTokenBuilderBean;
+import org.apache.myfaces.push.cdi.WebsocketSessionBean;
+import org.apache.myfaces.push.cdi.WebsocketViewBean;
+import org.apache.myfaces.webapp.StartupServletContextListener;
+import org.eclipse.microprofile.config.Config;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.jboss.jandex.AnnotationInstance;
+import org.jboss.jandex.AnnotationValue;
+import org.jboss.jandex.DotName;
+
+import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
+import io.quarkus.arc.deployment.BeanDefiningAnnotationBuildItem;
+import io.quarkus.arc.deployment.BeanRegistrarBuildItem;
+import io.quarkus.arc.deployment.BeanRegistrationPhaseBuildItem;
+import io.quarkus.arc.deployment.ContextRegistrarBuildItem;
+import io.quarkus.arc.processor.ContextRegistrar;
+import io.quarkus.deployment.annotations.BuildProducer;
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.annotations.ExecutionTime;
+import io.quarkus.deployment.annotations.Record;
+import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+import org.apache.myfaces.core.extensions.quarkus.runtime.MyFacesRecorder;
+import org.apache.myfaces.core.extensions.quarkus.runtime.QuarkusFacesInitilializer;
+import org.apache.myfaces.core.extensions.quarkus.runtime.scopes.QuarkusFacesScopeContext;
+import org.apache.myfaces.core.extensions.quarkus.runtime.scopes.QuarkusFlowScopedContext;
+import org.apache.myfaces.core.extensions.quarkus.runtime.scopes.QuarkusViewScopeContext;
+import org.apache.myfaces.core.extensions.quarkus.runtime.scopes.QuarkusViewTransientScopeContext;
+import org.apache.myfaces.core.extensions.quarkus.runtime.spi.QuarkusInjectionProvider;
+import io.quarkus.runtime.LaunchMode;
+import io.quarkus.runtime.configuration.ProfileManager;
+import io.quarkus.undertow.deployment.ListenerBuildItem;
+import io.quarkus.undertow.deployment.ServletBuildItem;
+import io.quarkus.undertow.deployment.ServletInitParamBuildItem;
+
+class MyFacesProcessor
+{
+
+ private static final Class[] BEAN_CLASSES =
+ {
+ JsfApplicationArtifactHolder.class,
+
+ JsfArtifactProducer.class,
+
+ FacesConfigBeanHolder.class,
+
+ FacesDataModelManager.class,
+
+ ViewScopeBeanHolder.class,
+
+ CdiAnnotationProviderExtension.class,
+
+ PushContextFactoryBean.class,
+ WebsocketChannelTokenBuilderBean.class,
+ WebsocketSessionBean.class,
+ WebsocketViewBean.class,
+ WebsocketApplicationBean.class,
+
+ FlowBuilderFactoryBean.class,
+ FlowScopeBeanHolder.class
+ };
+
+ private static final String[] BEAN_DEFINING_ANNOTATION_CLASSES =
+ {
+ FacesComponent.class.getName(),
+ FacesBehavior.class.getName(),
+ FacesConverter.class.getName(),
+ FacesValidator.class.getName(),
+ FacesRenderer.class.getName(),
+ NamedEvent.class.getName(),
+ FacesBehaviorRenderer.class.getName(),
+ FaceletsResourceResolver.class.getName(),
+ FlowDefinition.class.getName()
+ };
+
+ @BuildStep
+ void buildFeature(BuildProducer<FeatureBuildItem> feature) throws IOException
+ {
+ feature.produce(new FeatureBuildItem("myfaces"));
+ }
+
+ @BuildStep
+ void buildServlet(BuildProducer<FeatureBuildItem> feature,
+ BuildProducer<ServletBuildItem> servlet,
+ BuildProducer<ListenerBuildItem> listener) throws IOException
+ {
+ servlet.produce(ServletBuildItem.builder("Faces Servlet", FacesServlet.class.getName())
+ .addMapping("*.xhtml")
+ .build());
+
+ // sometimes Quarkus doesn't scan web-fragments?! lets add it manually
+ listener.produce(new ListenerBuildItem(StartupServletContextListener.class.getName()));
+ }
+
+ @BuildStep
+ void buildCdiBeans(BuildProducer<AdditionalBeanBuildItem> additionalBean,
+ BuildProducer<BeanDefiningAnnotationBuildItem> beanDefiningAnnotation) throws IOException
+ {
+ for (Class<?> clazz : BEAN_CLASSES)
+ {
+ additionalBean.produce(AdditionalBeanBuildItem.unremovableOf(clazz));
+ }
+
+ for (String clazz : BEAN_DEFINING_ANNOTATION_CLASSES)
+ {
+ beanDefiningAnnotation.produce(new BeanDefiningAnnotationBuildItem(DotName.createSimple(clazz)));
+ }
+
+ }
+
+ @BuildStep
+ void buildCdiScopes(BuildProducer<ContextRegistrarBuildItem> contextRegistrar) throws IOException
+ {
+ contextRegistrar.produce(new ContextRegistrarBuildItem(new ContextRegistrar()
+ {
+ @Override
+ public void register(ContextRegistrar.RegistrationContext registrationContext)
+ {
+ registrationContext.configure(ViewScoped.class)
+ .normal()
+ .contextClass(QuarkusViewScopeContext.class)
+ .done();
+ registrationContext.configure(FacesScoped.class)
+ .normal()
+ .contextClass(QuarkusFacesScopeContext.class)
+ .done();
+ registrationContext.configure(ViewTransientScoped.class)
+ .normal()
+ .contextClass(QuarkusViewTransientScopeContext.class)
+ .done();
+ registrationContext.configure(FlowScoped.class)
+ .normal()
+ .contextClass(QuarkusFlowScopedContext.class)
+ .done();
+ }
+ }));
+ }
+
+ @BuildStep
+ void buildInitParams(BuildProducer<ServletInitParamBuildItem> initParam) throws IOException
+ {
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.INJECTION_PROVIDER, QuarkusInjectionProvider.class.getName()));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.FACES_INITIALIZER, QuarkusFacesInitilializer.class.getName()));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.SUPPORT_JSP, "false"));
+ }
+
+ @BuildStep
+ void buildRecommendedInitParams(BuildProducer<ServletInitParamBuildItem> initParam) throws IOException
+ {
+ // user config
+ Config config = ConfigProvider.getConfig();
+
+ Optional<String> projectStage = resolveProjectStage(config);
+ initParam.produce(new ServletInitParamBuildItem(ProjectStage.PROJECT_STAGE_PARAM_NAME, projectStage.get()));
+
+ Optional<String> enableWebsocketsEndpoint = config.getOptionalValue(
+ PushContext.ENABLE_WEBSOCKET_ENDPOINT_PARAM_NAME,
+ String.class);
+ if (enableWebsocketsEndpoint.isPresent())
+ {
+ initParam.produce(new ServletInitParamBuildItem(PushContext.ENABLE_WEBSOCKET_ENDPOINT_PARAM_NAME,
+ enableWebsocketsEndpoint.get()));
+ }
+
+ // common
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.LOG_WEB_CONTEXT_PARAMS, "false"));
+ initParam.produce(new ServletInitParamBuildItem(
+ StateManager.STATE_SAVING_METHOD_PARAM_NAME, StateManager.STATE_SAVING_METHOD_SERVER));
+ initParam.produce(new ServletInitParamBuildItem(
+ StateManager.SERIALIZE_SERVER_STATE_PARAM_NAME, "false"));
+
+ // perf
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.CHECK_ID_PRODUCTION_MODE, "false"));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.EARLY_FLUSH_ENABLED, "true"));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.CACHE_EL_EXPRESSIONS, "alwaysRecompile"));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.COMPRESS_STATE_IN_SESSION, "false"));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.NUMBER_OF_VIEWS_IN_SESSION, "15"));
+ initParam.produce(new ServletInitParamBuildItem(
+ MyfacesConfig.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION, "3"));
+
+ // MyFaces uses default 0, which means always recompile
+ if (ProjectStage.valueOf(projectStage.get()) == ProjectStage.Development)
+ {
+ initParam.produce(new ServletInitParamBuildItem(
+ ViewHandler.FACELETS_REFRESH_PERIOD_PARAM_NAME, "1"));
+ }
+
+ // primefaces perf
+ initParam.produce(new ServletInitParamBuildItem(
+ "primefaces.SUBMIT", "partial"));
+ initParam.produce(new ServletInitParamBuildItem(
+ "primefaces.MOVE_SCRIPTS_TO_BOTTOM", "true"));
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.STATIC_INIT)
+ void buildAnnotationProviderIntegration(MyFacesRecorder recorder, CombinedIndexBuildItem combinedIndex)
+ throws IOException
+ {
+ for (String clazz : BEAN_DEFINING_ANNOTATION_CLASSES)
+ {
+ combinedIndex.getIndex()
+ .getAnnotations(DotName.createSimple(clazz))
+ .stream()
+ .forEach(annotation -> recorder.registerAnnotatedClass(annotation.name().toString(),
+ annotation.target().asClass().name().toString()));
+ }
+ }
+
+ private Optional<String> resolveProjectStage(Config config)
+ {
+ Optional<String> projectStage = config.getOptionalValue(ProjectStage.PROJECT_STAGE_PARAM_NAME,
+ String.class);
+ if (!projectStage.isPresent())
+ {
+ projectStage = Optional.of(ProjectStage.Production.name());
+ if (LaunchMode.DEVELOPMENT.getDefaultProfile().equals(ProfileManager.getActiveProfile()))
+ {
+ projectStage = Optional.of(ProjectStage.Development.name());
+ }
+ else if (LaunchMode.TEST.getDefaultProfile().equals(ProfileManager.getActiveProfile()))
+ {
+ projectStage = Optional.of(ProjectStage.SystemTest.name());
+ }
+ }
+ return projectStage;
+ }
+
+ @BuildStep
+ void buildMangedPropertyProducers(BeanRegistrationPhaseBuildItem beanRegistrationPhase,
+ BuildProducer<BeanRegistrationPhaseBuildItem.BeanConfiguratorBuildItem> beanConfigurators)
+ throws IOException
+ {
+ ManagedPropertyBuildStep.build(beanRegistrationPhase, beanConfigurators);
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.STATIC_INIT)
+ void buildFacesDataModels(MyFacesRecorder recorder,
+ BuildProducer<BeanRegistrarBuildItem> beanConfigurators,
+ CombinedIndexBuildItem combinedIndex) throws IOException
+ {
+ for (AnnotationInstance ai : combinedIndex.getIndex()
+ .getAnnotations(DotName.createSimple(FacesDataModel.class.getName())))
+ {
+ AnnotationValue forClass = ai.value("forClass");
+ if (forClass != null)
+ {
+ recorder.registerFacesDataModel(
+ ai.target().asClass().name().toString(),
+ forClass.asClass().name().toString());
+ }
+ }
+ }
+
+ @BuildStep
+ @Record(ExecutionTime.STATIC_INIT)
+ void buildFlowScopedMapping(MyFacesRecorder recorder,
+ CombinedIndexBuildItem combinedIndex) throws IOException
+ {
+ for (AnnotationInstance ai : combinedIndex.getIndex()
+ .getAnnotations(DotName.createSimple(FlowScoped.class.getName())))
+ {
+ AnnotationValue flowId = ai.value("value");
+ if (flowId != null && flowId.asString() != null)
+ {
+ AnnotationValue definingDocumentId = ai.value("definingDocumentId");
+ recorder.registerFlowReference(ai.target().asClass().name().toString(),
+ definingDocumentId == null ? "" : definingDocumentId.asString(),
+ flowId.asString());
+ }
+ }
+ }
+}
diff --git a/extensions/quarkus/pom.xml b/extensions/quarkus/pom.xml
new file mode 100644
index 0000000..0d5a387
--- /dev/null
+++ b/extensions/quarkus/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-extensions</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.myfaces.core.extensions</groupId>
+ <artifactId>myfaces-quarkus</artifactId>
+ <name>Apache MyFaces Core 3.0 - Extensions - Quarkus</name>
+ <description>
+ Apache MyFaces Core extension for Quarkus.
+ </description>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>deployment</module>
+ <module>runtime</module>
+ </modules>
+
+ <properties>
+ <quarkus.version>1.1.0.CR1</quarkus.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <excludes>**/*$$accessor.java</excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/extensions/quarkus/runtime/faces-config.NavData b/extensions/quarkus/runtime/faces-config.NavData
new file mode 100644
index 0000000..187ec92
--- /dev/null
+++ b/extensions/quarkus/runtime/faces-config.NavData
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scene Scope="Project" version="2">
+ <Scope Scope="Faces Configuration Only"/>
+ <Scope Scope="Project"/>
+ <Scope Scope="All Faces Configurations"/>
+</Scene>
diff --git a/extensions/quarkus/runtime/pom.xml b/extensions/quarkus/runtime/pom.xml
new file mode 100644
index 0000000..82f8117
--- /dev/null
+++ b/extensions/quarkus/runtime/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.apache.myfaces.core.extensions</groupId>
+ <artifactId>myfaces-quarkus</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
+ <artifactId>myfaces-quarkus-runtime</artifactId>
+ <name>Apache MyFaces Core 3.0 - Extensions - Quarkus - Runtime</name>
+ <description>
+ Apache MyFaces Core runtime extension for Quarkus.
+ </description>
+
+ <dependencies>
+
+ <!-- MyFaces -->
+ <dependency>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- EL implementation -->
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-jasper-el</artifactId>
+ <version>9.0.29</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-core</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-undertow</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-undertow-websockets</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-jsonp</artifactId>
+ <version>${quarkus.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-bootstrap-maven-plugin</artifactId>
+ <version>${quarkus.version}</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <annotationProcessorPaths>
+ <path>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-extension-processor</artifactId>
+ <version>${quarkus.version}</version>
+ </path>
+ </annotationProcessorPaths>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/MyFacesRecorder.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/MyFacesRecorder.java
new file mode 100644
index 0000000..381a285
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/MyFacesRecorder.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime;
+
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.faces.model.DataModel;
+
+import org.apache.myfaces.flow.FlowReference;
+import org.apache.myfaces.util.lang.ClassUtils;
+
+import io.quarkus.runtime.annotations.Recorder;
+
+@Recorder
+public class MyFacesRecorder
+{
+ public static final Map<Class<? extends Annotation>, Set<Class<?>>> ANNOTATED_CLASSES = new LinkedHashMap<>();
+ public static final Map<Class<? extends DataModel>, Class<?>> FACES_DATA_MODELS = new LinkedHashMap<>();
+ public static final Map<Class, FlowReference> FLOW_REFERENCES = new ConcurrentHashMap<Class, FlowReference>();
+
+ @SuppressWarnings("unchecked") //cast to (Class<? extends Annotation>)
+ public void registerAnnotatedClass(String annotationName, String clazzName)
+ {
+ Class<? extends Annotation> annotation =
+ (Class<? extends Annotation>) ClassUtils.simpleClassForName(annotationName);
+ Class<?> clazz = ClassUtils.simpleClassForName(clazzName);
+
+ Set<Class<?>> classes = ANNOTATED_CLASSES.computeIfAbsent(annotation, $ -> new HashSet<>());
+ classes.add(clazz);
+ }
+
+ @SuppressWarnings("unchecked") //cast to (Class<? extends DataModel>)
+ public void registerFacesDataModel(String clazzName, String forClassName)
+ {
+ Class<? extends DataModel> clazz = ClassUtils.simpleClassForName(clazzName);
+ Class<?> forClass = ClassUtils.simpleClassForName(forClassName);
+
+ FACES_DATA_MODELS.put(clazz, forClass);
+ }
+
+ public void registerFlowReference(String clazzName, String definingDocumentId, String flowId)
+ {
+ Class<?> clazz = ClassUtils.simpleClassForName(clazzName);
+
+ FLOW_REFERENCES.put(clazz, new FlowReference(definingDocumentId, flowId));
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/QuarkusFacesInitilializer.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/QuarkusFacesInitilializer.java
new file mode 100644
index 0000000..e665fc0
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/QuarkusFacesInitilializer.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime;
+
+import java.util.Map;
+
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.annotation.FacesConfig;
+import javax.faces.model.DataModel;
+import javax.servlet.ServletContext;
+
+import org.apache.myfaces.cdi.config.FacesConfigBeanHolder;
+import org.apache.myfaces.cdi.model.FacesDataModelManager;
+import org.apache.myfaces.spi.FactoryFinderProviderFactory;
+import org.apache.myfaces.webapp.FaceletsInitilializer;
+
+import org.apache.myfaces.core.extensions.quarkus.runtime.spi.QuarkusFactoryFinderProviderFactory;
+
+/**
+ * Custom FacesInitializer to execute our integration code, always before MyFaces starts.
+ * With ServletListeners or other ways, we would have order/priority problems.
+ */
+public class QuarkusFacesInitilializer extends FaceletsInitilializer
+{
+
+ @Override
+ public void initFaces(ServletContext servletContext)
+ {
+ FacesConfigBeanHolder facesConfigBeanHolder = CDI.current().select(FacesConfigBeanHolder.class).get();
+ facesConfigBeanHolder.setFacesConfigVersion(FacesConfig.Version.JSF_2_3);
+
+ FactoryFinderProviderFactory.setInstance(new QuarkusFactoryFinderProviderFactory());
+
+ // see FacesDataModelExtension
+ FacesDataModelManager facesDataModelManager = CDI.current().select(FacesDataModelManager.class).get();
+ for (Map.Entry<Class<? extends DataModel>, Class<?>> typeInfo : MyFacesRecorder.FACES_DATA_MODELS.entrySet())
+ {
+ facesDataModelManager.addFacesDataModel(typeInfo.getValue(), typeInfo.getKey());
+ }
+ facesDataModelManager.init();
+
+ super.initFaces(servletContext);
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplication.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplication.java
new file mode 100644
index 0000000..3048080
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplication.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.application;
+
+import javax.el.CompositeELResolver;
+import javax.el.ELResolver;
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationWrapper;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.config.MyfacesConfig;
+import org.apache.myfaces.config.RuntimeConfig;
+
+import org.apache.myfaces.core.extensions.quarkus.runtime.spi.QuarkusELResolverBuilder;
+
+public class QuarkusApplication extends ApplicationWrapper
+{
+ private CompositeELResolver elResolver;
+
+ private final RuntimeConfig runtimeConfig;
+ private final MyfacesConfig myfacesConfig;
+
+ public QuarkusApplication(Application delegate)
+ {
+ super(delegate);
+
+ runtimeConfig = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance());
+ myfacesConfig = MyfacesConfig.getCurrentInstance(FacesContext.getCurrentInstance());
+ }
+
+ @Override
+ public final ELResolver getELResolver()
+ {
+ if (elResolver == null)
+ {
+ elResolver = new CompositeELResolver();
+ new QuarkusELResolverBuilder(runtimeConfig, myfacesConfig).build(elResolver);
+ }
+
+ return elResolver;
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplicationFactory.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplicationFactory.java
new file mode 100644
index 0000000..d4f3b38
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/application/QuarkusApplicationFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.application;
+
+import javax.faces.application.Application;
+import javax.faces.application.ApplicationFactory;
+
+public class QuarkusApplicationFactory extends ApplicationFactory
+{
+ private Application application;
+
+ public QuarkusApplicationFactory(ApplicationFactory delegate)
+ {
+ super(delegate);
+ }
+
+ @Override
+ public Application getApplication()
+ {
+ if (application == null)
+ {
+ application = new QuarkusApplication(getWrapped().getApplication());
+ }
+
+ return application;
+ }
+
+ @Override
+ public void setApplication(Application application)
+ {
+ this.application = new QuarkusApplication(application);
+ getWrapped().setApplication(application);
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandler.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandler.java
new file mode 100644
index 0000000..1c48a2c
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandler.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.exception;
+
+import java.util.Iterator;
+
+import javax.faces.FacesException;
+import javax.faces.application.ProjectStage;
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.ExceptionQueuedEvent;
+
+/**
+ * Custom {@link ExceptionHandler} to log exceptions in development mode.
+ */
+public class QuarkusExceptionHandler extends ExceptionHandlerWrapper
+{
+ public QuarkusExceptionHandler(ExceptionHandler wrapped)
+ {
+ super(wrapped);
+ }
+
+ @Override
+ public void handle() throws FacesException
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ if (context.isProjectStage(ProjectStage.Development))
+ {
+ Iterator<ExceptionQueuedEvent> iterator = getUnhandledExceptionQueuedEvents().iterator();
+ while (iterator.hasNext())
+ {
+ ExceptionQueuedEvent event = iterator.next();
+
+ event.getContext().getException().printStackTrace();
+ }
+ }
+
+ getWrapped().handle();
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandlerFactory.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandlerFactory.java
new file mode 100644
index 0000000..82b1b8e
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/exception/QuarkusExceptionHandlerFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.exception;
+
+import javax.faces.context.ExceptionHandler;
+import javax.faces.context.ExceptionHandlerFactory;
+
+public class QuarkusExceptionHandlerFactory extends ExceptionHandlerFactory
+{
+ public QuarkusExceptionHandlerFactory(ExceptionHandlerFactory wrapped)
+ {
+ super(wrapped);
+ }
+
+ @Override
+ public ExceptionHandler getExceptionHandler()
+ {
+ return new QuarkusExceptionHandler(getWrapped().getExceptionHandler());
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/producer/ManagedPropertyBeanCreator.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/producer/ManagedPropertyBeanCreator.java
new file mode 100644
index 0000000..4b75df3
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/producer/ManagedPropertyBeanCreator.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.producer;
+
+import java.util.Map;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import io.quarkus.arc.BeanCreator;
+
+public class ManagedPropertyBeanCreator implements BeanCreator<Object>
+{
+ public static final String EXPRESSION = "expression";
+
+ @Override
+ public Object create(CreationalContext<Object> cc, Map<String, Object> map)
+ {
+ String expression = (String) map.get(EXPRESSION);
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (facesContext == null)
+ {
+ throw new FacesException("@ManagedProperty(\"" + expression
+ + "\") can only be resolved in a JSF request!");
+ }
+
+ return facesContext.getApplication().evaluateExpressionGet(facesContext, expression, Object.class);
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFacesScopeContext.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFacesScopeContext.java
new file mode 100644
index 0000000..79fe590
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFacesScopeContext.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.scopes;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.CDI;
+
+import org.apache.myfaces.cdi.FacesScopeContextImpl;
+import org.apache.myfaces.cdi.FacesScoped;
+
+import io.quarkus.arc.InjectableContext;
+
+public class QuarkusFacesScopeContext implements InjectableContext
+{
+ private FacesScopeContextImpl wrapped;
+
+ public QuarkusFacesScopeContext()
+ {
+ }
+
+ public FacesScopeContextImpl getWrapped()
+ {
+ if (wrapped == null)
+ {
+ wrapped = new FacesScopeContextImpl(CDI.current().getBeanManager());
+ }
+ return wrapped;
+ }
+
+ @Override
+ public void destroy()
+ {
+
+ }
+
+ @Override
+ public void destroy(Contextual<?> contextual)
+ {
+ getWrapped().destroy(contextual);
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return FacesScoped.class;
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual, CreationalContext<T> cc)
+ {
+ return getWrapped().get(contextual, cc);
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual)
+ {
+ return getWrapped().get(contextual);
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return getWrapped().isActive();
+ }
+
+ @Override
+ public ContextState getState()
+ {
+ return null;
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFlowScopedContext.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFlowScopedContext.java
new file mode 100644
index 0000000..10cc681
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusFlowScopedContext.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.scopes;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.flow.FlowScoped;
+
+import org.apache.myfaces.flow.cdi.FlowScopedContextImpl;
+
+import io.quarkus.arc.InjectableContext;
+import org.apache.myfaces.core.extensions.quarkus.runtime.MyFacesRecorder;
+
+public class QuarkusFlowScopedContext implements InjectableContext
+{
+ private FlowScopedContextImpl wrapped;
+
+ public QuarkusFlowScopedContext()
+ {
+ }
+
+ public FlowScopedContextImpl getWrapped()
+ {
+ if (wrapped == null)
+ {
+ wrapped = new FlowScopedContextImpl(CDI.current().getBeanManager(), MyFacesRecorder.FLOW_REFERENCES);
+ }
+ return wrapped;
+ }
+
+ @Override
+ public void destroy()
+ {
+
+ }
+
+ @Override
+ public void destroy(Contextual<?> contextual)
+ {
+ getWrapped().destroy(contextual);
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return FlowScoped.class;
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual, CreationalContext<T> cc)
+ {
+ return getWrapped().get(contextual, cc);
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual)
+ {
+ return getWrapped().get(contextual);
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return getWrapped().isActive();
+ }
+
+ @Override
+ public InjectableContext.ContextState getState()
+ {
+ return null;
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewScopeContext.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewScopeContext.java
new file mode 100644
index 0000000..5f1b4f0
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewScopeContext.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.scopes;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.view.ViewScoped;
+
+import org.apache.myfaces.cdi.view.ViewScopeContextImpl;
+
+import io.quarkus.arc.InjectableContext;
+
+public class QuarkusViewScopeContext implements InjectableContext
+{
+ private ViewScopeContextImpl wrapped;
+
+ public QuarkusViewScopeContext()
+ {
+ }
+
+ public ViewScopeContextImpl getWrapped()
+ {
+ if (wrapped == null)
+ {
+ wrapped = new ViewScopeContextImpl(CDI.current().getBeanManager());
+ }
+ return wrapped;
+ }
+
+ @Override
+ public void destroy()
+ {
+
+ }
+
+ @Override
+ public void destroy(Contextual<?> contextual)
+ {
+ getWrapped().destroy(contextual);
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return ViewScoped.class;
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual, CreationalContext<T> cc)
+ {
+ return getWrapped().get(contextual, cc);
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual)
+ {
+ return getWrapped().get(contextual);
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return getWrapped().isActive();
+ }
+
+ @Override
+ public ContextState getState()
+ {
+ return null;
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewTransientScopeContext.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewTransientScopeContext.java
new file mode 100644
index 0000000..be30b03
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/scopes/QuarkusViewTransientScopeContext.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.scopes;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.CDI;
+
+import org.apache.myfaces.cdi.view.ViewTransientScopeContextImpl;
+import org.apache.myfaces.cdi.view.ViewTransientScoped;
+
+import io.quarkus.arc.InjectableContext;
+
+public class QuarkusViewTransientScopeContext implements InjectableContext
+{
+ private ViewTransientScopeContextImpl wrapped;
+
+ public QuarkusViewTransientScopeContext()
+ {
+ }
+
+ public ViewTransientScopeContextImpl getWrapped()
+ {
+ if (wrapped == null)
+ {
+ wrapped = new ViewTransientScopeContextImpl(CDI.current().getBeanManager());
+ }
+ return wrapped;
+ }
+
+ @Override
+ public void destroy()
+ {
+
+ }
+
+ @Override
+ public void destroy(Contextual<?> contextual)
+ {
+ getWrapped().destroy(contextual);
+ }
+
+ @Override
+ public Class<? extends Annotation> getScope()
+ {
+ return ViewTransientScoped.class;
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual, CreationalContext<T> cc)
+ {
+ return getWrapped().get(contextual, cc);
+ }
+
+ @Override
+ public <T> T get(Contextual<T> contextual)
+ {
+ return getWrapped().get(contextual);
+ }
+
+ @Override
+ public boolean isActive()
+ {
+ return getWrapped().isActive();
+ }
+
+ @Override
+ public ContextState getState()
+ {
+ return null;
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusAnnotationProvider.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusAnnotationProvider.java
new file mode 100644
index 0000000..366be80
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusAnnotationProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.spi.AnnotationProvider;
+
+import org.apache.myfaces.core.extensions.quarkus.runtime.MyFacesRecorder;
+
+/**
+ * AnnotationProvider which uses the collected classes from the Quarkus Deployment-time.
+ */
+public class QuarkusAnnotationProvider extends AnnotationProvider
+{
+
+ @Override
+ public Map<Class<? extends Annotation>, Set<Class<?>>> getAnnotatedClasses(ExternalContext ctx)
+ {
+ return MyFacesRecorder.ANNOTATED_CLASSES;
+ }
+
+ @Override
+ public Set<URL> getBaseUrls(ExternalContext ctx) throws IOException
+ {
+ return Collections.emptySet();
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusCdiELResolver.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusCdiELResolver.java
new file mode 100644
index 0000000..d4b1c7b
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusCdiELResolver.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.CDI;
+import javax.faces.FacesException;
+
+/**
+ * Custom {@link ELResolver} for CDI as {@link BeanManager#getELResolver} is not supported on Quarkus.
+ * Currently @Dependent is not supported.
+ */
+public class QuarkusCdiELResolver extends ELResolver
+{
+ private BeanManager beanManager;
+ private Map<String, Optional<Object>> cachedProxies;
+
+ public QuarkusCdiELResolver()
+ {
+ beanManager = CDI.current().getBeanManager();
+ cachedProxies = new ConcurrentHashMap<>();
+ }
+
+ @Override
+ public Class<?> getCommonPropertyType(ELContext arg0, Object arg1)
+ {
+ return null;
+ }
+
+ @Override
+ public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext arg0, Object arg1)
+ {
+ return null;
+ }
+
+ @Override
+ public Class<?> getType(ELContext arg0, Object arg1, Object arg2) throws ELException
+ {
+ return null;
+ }
+
+ @Override
+ public Object getValue(ELContext context, Object base, Object property) throws ELException
+ {
+ //we only check root beans
+ if (base != null)
+ {
+ return null;
+ }
+
+ String beanName = (String) property;
+
+ Optional<Object> contextualInstance = cachedProxies.computeIfAbsent(beanName, s -> resolveProxy(s));
+ if (contextualInstance.isPresent())
+ {
+ context.setPropertyResolved(true);
+ return contextualInstance.get();
+ }
+
+ return null;
+ }
+
+ protected Optional<Object> resolveProxy(String beanName)
+ {
+ Object contextualInstance = null;
+
+ Set<Bean<?>> beans = beanManager.getBeans(beanName);
+ if (beans != null && !beans.isEmpty())
+ {
+ Bean<?> bean = beanManager.resolve(beans);
+
+ if (bean.getScope().equals(Dependent.class))
+ {
+ throw new FacesException("@Dependent on beans used in EL are currently not supported! "
+ + " Class: " + bean.getBeanClass().toString());
+ }
+
+ CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
+ contextualInstance = beanManager.getReference(bean, Object.class, creationalContext);
+ }
+
+ return contextualInstance == null ? Optional.empty() : Optional.of(contextualInstance);
+ }
+
+ @Override
+ public boolean isReadOnly(ELContext arg0, Object arg1, Object arg2) throws ELException
+ {
+ return false;
+ }
+
+ @Override
+ public void setValue(ELContext arg0, Object arg1, Object arg2, Object arg3) throws ELException
+ {
+
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusELResolverBuilder.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusELResolverBuilder.java
new file mode 100644
index 0000000..b974e92
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusELResolverBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import javax.el.ELResolver;
+
+import org.apache.myfaces.config.MyfacesConfig;
+import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.el.ELResolverBuilderForFaces;
+
+/**
+ * Custom {@link org.apache.myfaces.el.ELResolverBuilder} which only works with EL3.x+
+ * and replaces the {@link javax.enterprise.inject.spi.BeanManager#getELResolver()}
+ * with our own {@link QuarkusCdiELResolver}
+ */
+public class QuarkusELResolverBuilder extends ELResolverBuilderForFaces
+{
+
+ public QuarkusELResolverBuilder(RuntimeConfig runtimeConfig, MyfacesConfig myfacesConfig)
+ {
+ super(runtimeConfig, myfacesConfig);
+ }
+
+ @Override
+ protected ELResolver getCDIELResolver()
+ {
+ return new QuarkusCdiELResolver();
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFacesFlowProvider.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFacesFlowProvider.java
new file mode 100644
index 0000000..33fa6a6
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFacesFlowProvider.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import java.util.Iterator;
+
+import javax.enterprise.inject.spi.CDI;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.faces.context.FacesContext;
+import javax.faces.flow.Flow;
+import javax.faces.flow.builder.FlowDefinition;
+
+import org.apache.myfaces.flow.cdi.DefaultCDIFacesFlowProvider;
+
+public class QuarkusFacesFlowProvider extends DefaultCDIFacesFlowProvider
+{
+ @Override
+ public Iterator<Flow> getAnnotatedFlows(FacesContext facesContext)
+ {
+ return CDI.current().select(Flow.class, new AnnotationLiteral<FlowDefinition>(){ }).stream().iterator();
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProvider.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProvider.java
new file mode 100644
index 0000000..b3a47bd
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProvider.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.FacesException;
+
+import org.apache.myfaces.spi.FactoryFinderProvider;
+import org.apache.myfaces.util.lang.ClassUtils;
+
+/**
+ * Custom FactoryFinder, as the original FactoryFinder cares to much about ClassLoaders,
+ * which doesn't work with Quarkus native.
+ * As Quarkus == 1 webapp, we can simple handle everything as static.
+ */
+public class QuarkusFactoryFinderProvider implements FactoryFinderProvider
+{
+ private final HashMap<String, List<String>> classes = new HashMap<>();
+ private final HashMap<String, Object> instances = new HashMap<>();
+
+ @Override
+ public Object getFactory(String factoryName) throws FacesException
+ {
+ Object instance = instances.get(factoryName);
+
+ if (instance == null)
+ {
+ try
+ {
+ List<String> impls = classes.computeIfAbsent(factoryName, k -> new ArrayList<>(3));
+
+ Iterator<String> implsIterator = impls.iterator();
+ while (implsIterator.hasNext())
+ {
+ Class implClass = ClassUtils.classForName(implsIterator.next());
+
+ for (Constructor<?> constructor : implClass.getConstructors())
+ {
+ if (constructor.getParameterTypes().length == 1)
+ {
+ instance = constructor.newInstance(new Object[] { instance });
+ }
+ }
+
+ if (instance == null)
+ {
+ for (Constructor<?> constructor : implClass.getConstructors())
+ {
+ if (constructor.getParameterTypes().length == 0)
+ {
+ instance = constructor.newInstance();
+ }
+ }
+ }
+ }
+
+ instances.put(factoryName, instance);
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ return instance;
+ }
+
+ @Override
+ public void releaseFactories() throws FacesException
+ {
+ instances.clear();
+ }
+
+ @Override
+ public void setFactory(String factoryName, String implName)
+ {
+ List<String> impls = classes.computeIfAbsent(factoryName, k -> new ArrayList<>(3));
+ impls.add(implName);
+
+ instances.remove(factoryName);
+ }
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProviderFactory.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProviderFactory.java
new file mode 100644
index 0000000..0b6fb6a
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusFactoryFinderProviderFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import org.apache.myfaces.spi.FactoryFinderProvider;
+import org.apache.myfaces.spi.FactoryFinderProviderFactory;
+
+public class QuarkusFactoryFinderProviderFactory extends FactoryFinderProviderFactory
+{
+ private static final QuarkusFactoryFinderProvider FACTORY_FINDER_PROVIDER = new QuarkusFactoryFinderProvider();
+
+ @Override
+ public FactoryFinderProvider getFactoryFinderProvider()
+ {
+ return FACTORY_FINDER_PROVIDER;
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusInjectionProvider.java b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusInjectionProvider.java
new file mode 100644
index 0000000..a180cbb
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/java/org/apache/myfaces/core/extensions/quarkus/runtime/spi/QuarkusInjectionProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.runtime.spi;
+
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+
+/**
+ * Needs to be implemented to support injection in JSF artifacts:
+ * https://github.com/quarkusio/quarkus/blob/master/extensions/arc/deployment/
+ * src/main/java/io/quarkus/arc/deployment/ArcTestResourceProvider.java#L21-L54
+ * https://github.com/quarkusio/quarkus/issues/2378
+ */
+public class QuarkusInjectionProvider extends InjectionProvider
+{
+ @Override
+ public Object inject(Object instance) throws InjectionProviderException
+ {
+ return instance;
+ }
+
+ @Override
+ public void postConstruct(Object instance, Object creationMetaData) throws InjectionProviderException
+ {
+
+ }
+
+ @Override
+ public void preDestroy(Object instance, Object creationMetaData) throws InjectionProviderException
+ {
+
+ }
+
+}
diff --git a/extensions/quarkus/runtime/src/main/resources/META-INF/faces-config.xml b/extensions/quarkus/runtime/src/main/resources/META-INF/faces-config.xml
new file mode 100644
index 0000000..a2a182d
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/resources/META-INF/faces-config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<faces-config version="2.2"
+ xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
+
+ <factory>
+ <application-factory>org.apache.myfaces.core.extensions.quarkus.runtime.application.QuarkusApplicationFactory</application-factory>
+ <exception-handler-factory>org.apache.myfaces.core.extensions.quarkus.runtime.exception.QuarkusExceptionHandlerFactory</exception-handler-factory>
+ </factory>
+
+</faces-config>
diff --git a/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.AnnotationProvider b/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.AnnotationProvider
new file mode 100644
index 0000000..dcd29e3
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.AnnotationProvider
@@ -0,0 +1 @@
+org.apache.myfaces.core.extensions.quarkus.runtime.spi.QuarkusAnnotationProvider
\ No newline at end of file
diff --git a/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.FacesFlowProvider b/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.FacesFlowProvider
new file mode 100644
index 0000000..373abe1
--- /dev/null
+++ b/extensions/quarkus/runtime/src/main/resources/META-INF/services/org.apache.myfaces.spi.FacesFlowProvider
@@ -0,0 +1 @@
+org.apache.myfaces.core.extensions.quarkus.runtime.spi.QuarkusFacesFlowProvider
diff --git a/extensions/quarkus/showcase/pom.xml b/extensions/quarkus/showcase/pom.xml
new file mode 100644
index 0000000..0d99a1b
--- /dev/null
+++ b/extensions/quarkus/showcase/pom.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-myfaces-showcase</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <name>Quarkus - MyFaces - Showcase</name>
+
+ <properties>
+ <quarkus.version>1.1.0.CR1</quarkus.version>
+ <myfaces.version>3.0.0-SNAPSHOT</myfaces.version>
+ <failsafe.version>2.22.0</failsafe.version>
+ <surefire.version>2.22.0</surefire.version>
+
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-bom</artifactId>
+ <version>${quarkus.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <!-- MyFaces -->
+ <dependency>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-api</artifactId>
+ <version>${myfaces.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-impl</artifactId>
+ <version>${myfaces.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
+ <artifactId>myfaces-quarkus-deployment</artifactId>
+ <version>${myfaces.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
+ <artifactId>myfaces-quarkus-runtime</artifactId>
+ <version>${myfaces.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.primefaces</groupId>
+ <artifactId>primefaces</artifactId>
+ <version>7.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.validation</groupId>
+ <artifactId>validation-api</artifactId>
+ <version>2.0.1.Final</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>${surefire.version}</version>
+ <configuration>
+ <systemProperties>
+ <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-maven-plugin</artifactId>
+ <version>${quarkus.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>build</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>native</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-maven-plugin</artifactId>
+ <version>${quarkus.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>native-image</goal>
+ </goals>
+ <configuration>
+ <enableHttpUrlHandler>true</enableHttpUrlHandler>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>${failsafe.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ <configuration>
+ <systemProperties>
+ <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
+ </systemProperties>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/StartupListener.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/StartupListener.java
new file mode 100644
index 0000000..dd09650
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/StartupListener.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebListener;
+
+@WebListener
+public class StartupListener implements ServletContextListener {
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ sce.getServletContext().setInitParameter("primefaces.THEME", "luna-amber");
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/Car.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/Car.java
new file mode 100644
index 0000000..e3e8e0d
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/Car.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.io.Serializable;
+
+public class Car implements Serializable {
+
+ public String id;
+ public String brand;
+ public int year;
+ public String color;
+ public int price;
+ public boolean sold;
+
+ public Car() {
+ }
+
+ public Car(String id, String brand, int year, String color) {
+ this.id = id;
+ this.brand = brand;
+ this.year = year;
+ this.color = color;
+ }
+
+ public Car(String id, String brand, int year, String color, int price, boolean sold) {
+ this.id = id;
+ this.brand = brand;
+ this.year = year;
+ this.color = color;
+ this.price = price;
+ this.sold = sold;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getBrand() {
+ return brand;
+ }
+
+ public void setBrand(String brand) {
+ this.brand = brand;
+ }
+
+ public int getYear() {
+ return year;
+ }
+
+ public void setYear(int year) {
+ this.year = year;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public int getPrice() {
+ return price;
+ }
+
+ public void setPrice(int price) {
+ this.price = price;
+ }
+
+ public boolean isSold() {
+ return sold;
+ }
+
+ public void setSold(boolean sold) {
+ this.sold = sold;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Car other = (Car) obj;
+ if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/CarService.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/CarService.java
new file mode 100644
index 0000000..692af75
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/CarService.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Named;
+
+@Named("carService")
+@ApplicationScoped
+public class CarService {
+
+ private final static String[] colors;
+
+ private final static String[] brands;
+
+ static {
+ colors = new String[10];
+ colors[0] = "Black";
+ colors[1] = "White";
+ colors[2] = "Green";
+ colors[3] = "Red";
+ colors[4] = "Blue";
+ colors[5] = "Orange";
+ colors[6] = "Silver";
+ colors[7] = "Yellow";
+ colors[8] = "Brown";
+ colors[9] = "Maroon";
+
+ brands = new String[10];
+ brands[0] = "BMW";
+ brands[1] = "Mercedes";
+ brands[2] = "Volvo";
+ brands[3] = "Audi";
+ brands[4] = "Renault";
+ brands[5] = "Fiat";
+ brands[6] = "Volkswagen";
+ brands[7] = "Honda";
+ brands[8] = "Jaguar";
+ brands[9] = "Ford";
+ }
+
+ public List<Car> createCars(int size) {
+ List<Car> list = new ArrayList<Car>();
+ for (int i = 0; i < size; i++) {
+ list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState()));
+ }
+
+ return list;
+ }
+
+ private String getRandomId() {
+ return UUID.randomUUID().toString().substring(0, 8);
+ }
+
+ private int getRandomYear() {
+ return (int) (Math.random() * 50 + 1960);
+ }
+
+ private String getRandomColor() {
+ return colors[(int) (Math.random() * 10)];
+ }
+
+ private String getRandomBrand() {
+ return brands[(int) (Math.random() * 10)];
+ }
+
+ private int getRandomPrice() {
+ return (int) (Math.random() * 100000);
+ }
+
+ private boolean getRandomSoldState() {
+ return Math.random() > 0.5;
+ }
+
+ public List<String> getColors() {
+ return Arrays.asList(colors);
+ }
+
+ public List<String> getBrands() {
+ return Arrays.asList(brands);
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/InputController.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/InputController.java
new file mode 100644
index 0000000..4afef5e
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/InputController.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.io.Serializable;
+import javax.enterprise.context.SessionScoped;
+import javax.faces.annotation.ManagedProperty;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Named
+@SessionScoped
+public class InputController implements Serializable{
+
+ @Inject
+ @ManagedProperty(value = "#{carService}")
+ private CarService carService;
+
+ private String val;
+
+ public String getVal() {
+ System.err.println("carService: " + carService);
+ return val;
+ }
+
+ public void setVal(String val) {
+ this.val = val;
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyCarDataModel.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyCarDataModel.java
new file mode 100644
index 0000000..56bb78f
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyCarDataModel.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.primefaces.model.LazyDataModel;
+import org.primefaces.model.SortOrder;
+
+/**
+ * Dummy implementation of LazyDataModel that uses a list to mimic a real datasource like a database.
+ */
+public class LazyCarDataModel extends LazyDataModel<Car> {
+
+ private List<Car> datasource;
+
+ public LazyCarDataModel(List<Car> datasource) {
+ this.datasource = datasource;
+ }
+
+ @Override
+ public Car getRowData(String rowKey) {
+ for (Car car : datasource) {
+ if (car.getId().equals(rowKey)) {
+ return car;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Object getRowKey(Car car) {
+ return car.getId();
+ }
+
+ @Override
+ public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
+ List<Car> data = new ArrayList<Car>();
+
+ //filter
+ for (Car car : datasource) {
+ boolean match = true;
+
+ if (filters != null) {
+ for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
+ try {
+ String filterProperty = it.next();
+ Object filterValue = filters.get(filterProperty);
+ String fieldValue = String.valueOf(car.getClass().getField(filterProperty).get(car));
+
+ if (filterValue == null || fieldValue.startsWith(filterValue.toString())) {
+ match = true;
+ }
+ else {
+ match = false;
+ break;
+ }
+ }
+ catch (Exception e) {
+ match = false;
+ }
+ }
+ }
+
+ if (match) {
+ data.add(car);
+ }
+ }
+
+ //sort
+ if (sortField != null) {
+ Collections.sort(data, new LazySorter(sortField, sortOrder));
+ }
+
+ //rowCount
+ int dataSize = data.size();
+ this.setRowCount(dataSize);
+
+ //paginate
+ if (dataSize > pageSize) {
+ try {
+ return data.subList(first, first + pageSize);
+ }
+ catch (IndexOutOfBoundsException e) {
+ return data.subList(first, first + (dataSize % pageSize));
+ }
+ }
+ else {
+ return data;
+ }
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazySorter.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazySorter.java
new file mode 100644
index 0000000..36bf76b
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazySorter.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.util.Comparator;
+import org.primefaces.model.SortOrder;
+
+public class LazySorter implements Comparator<Car> {
+
+ private String sortField;
+ private SortOrder sortOrder;
+
+ public LazySorter(String sortField, SortOrder sortOrder) {
+ this.sortField = sortField;
+ this.sortOrder = sortOrder;
+ }
+
+ @Override
+ public int compare(Car car1, Car car2) {
+ try {
+ Object value1 = Car.class.getField(this.sortField).get(car1);
+ Object value2 = Car.class.getField(this.sortField).get(car2);
+
+ int value = ((Comparable) value1).compareTo(value2);
+
+ return SortOrder.ASCENDING.equals(sortOrder) ? value : -1 * value;
+ }
+ catch(Exception e) {
+ throw new RuntimeException();
+ }
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyView.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyView.java
new file mode 100644
index 0000000..9d8b664
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/LazyView.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.io.Serializable;
+import javax.annotation.PostConstruct;
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.primefaces.event.SelectEvent;
+import org.primefaces.model.LazyDataModel;
+
+@Named("dtLazyView")
+@ViewScoped
+public class LazyView implements Serializable {
+
+ private LazyDataModel<Car> lazyModel;
+
+ private Car selectedCar;
+
+ @Inject
+ private CarService service;
+
+ @PostConstruct
+ public void init() {
+ lazyModel = new LazyCarDataModel(service.createCars(200));
+ }
+
+ public LazyDataModel<Car> getLazyModel() {
+ return lazyModel;
+ }
+
+ public Car getSelectedCar() {
+ return selectedCar;
+ }
+
+ public void setSelectedCar(Car selectedCar) {
+ this.selectedCar = selectedCar;
+ }
+
+ public void setService(CarService service) {
+ this.service = service;
+ }
+
+ public void onRowSelect(SelectEvent event) {
+ FacesMessage msg = new FacesMessage("Car Selected", ((Car) event.getObject()).getId());
+ FacesContext.getCurrentInstance().addMessage(null, msg);
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MethodHandleELResolverBean.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MethodHandleELResolverBean.java
new file mode 100644
index 0000000..1c4a5aa
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MethodHandleELResolverBean.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.io.Serializable;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.ApplicationScoped;
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Named
+@ApplicationScoped
+public class MethodHandleELResolverBean implements Serializable, PhaseListener {
+
+ @Inject
+ private CarService service;
+
+ private List<Car> cars;
+
+ private int test;
+ private String test2;
+
+ private long start;
+
+ @PostConstruct
+ public void init() {
+ cars = service.createCars(20000);
+ }
+
+ public List<Car> getCars() {
+ return cars;
+ }
+
+ public void setCars(List<Car> cars) {
+ this.cars = cars;
+ }
+
+ public int getTest() {
+ return test;
+ }
+
+ public void setTest(int test) {
+ this.test = test;
+ }
+
+ public String getTest2() {
+ return test2;
+ }
+
+ public void setTest2(String test2) {
+ this.test2 = test2;
+ }
+
+ @Override
+ public void afterPhase(PhaseEvent event) {
+ System.err.println((System.currentTimeMillis() - start) + "ms");
+ }
+
+ @Override
+ public void beforePhase(PhaseEvent event) {
+ start = System.currentTimeMillis();
+ }
+
+ @Override
+ public PhaseId getPhaseId() {
+ return PhaseId.RENDER_RESPONSE;
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyBacking.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyBacking.java
new file mode 100644
index 0000000..67842a8
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyBacking.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Named
+@RequestScoped
+public class MyBacking {
+
+ @Inject private CarService carService;
+
+ private MyCollection<Car> cars;
+
+ @PostConstruct
+ public void init()
+ {
+ cars = new MyCollection<>();
+ for (Car car : carService.createCars(100))
+ {
+ cars.add(car);
+ }
+ }
+
+ public MyCollection<Car> getCars() {
+ return cars;
+ }
+
+ public void setCars(MyCollection<Car> cars) {
+ this.cars = cars;
+ }
+
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollection.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollection.java
new file mode 100644
index 0000000..ea011ab
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollection.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.util.ArrayList;
+
+public class MyCollection<T> extends ArrayList<T>
+{
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollectionModel.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollectionModel.java
new file mode 100644
index 0000000..839705d
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyCollectionModel.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.util.List;
+import javax.faces.model.FacesDataModel;
+import javax.faces.model.ListDataModel;
+
+@FacesDataModel(forClass = MyCollection.class)
+public class MyCollectionModel<E> extends ListDataModel<E> {
+
+ public MyCollectionModel()
+ {
+ super();
+ System.err.println("+++++++++++++++");
+ }
+
+ public MyCollectionModel(List<E> list)
+ {
+ super(list);
+ System.err.println("+++++++++++++++2");
+ }
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverter.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverter.java
new file mode 100644
index 0000000..902f985
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.convert.FacesConverter;
+
+@FacesConverter(managed = false, value = "myConverter")
+public class MyConverter implements Converter<Object>{
+ @Override
+ public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverterManaged.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverterManaged.java
new file mode 100644
index 0000000..90cf63a
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyConverterManaged.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+import javax.faces.convert.FacesConverter;
+
+@FacesConverter(managed = true, value = "myConverterManaged")
+public class MyConverterManaged implements Converter<Object>{
+ @Override
+ public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+ @Override
+ public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException {
+ throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyValidator.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyValidator.java
new file mode 100644
index 0000000..5d00659
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/MyValidator.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.FacesValidator;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+import javax.inject.Inject;
+
+@FacesValidator(value = "myVal", managed = true)
+public class MyValidator implements Validator<String>{
+
+ @Inject private CarService carService;
+
+ public MyValidator()
+ {
+ }
+
+ @Override
+ public void validate(FacesContext context, UIComponent component, String value) throws ValidatorException {
+ System.err.println("############### validate: " + value + " (carService=" + carService + ")");
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/SocketView.java b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/SocketView.java
new file mode 100644
index 0000000..8b44c09
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/java/org/apache/myfaces/core/extensions/quarkus/showcase/view/SocketView.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.core.extensions.quarkus.showcase.view;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.faces.push.Push;
+import javax.faces.push.PushContext;
+import javax.faces.view.ViewScoped;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@ViewScoped
+@Named
+public class SocketView implements Serializable {
+
+ private static final Logger LOG = Logger.getLogger(SocketView.class.getName());
+
+ @Inject
+ @Push
+ PushContext helloChannel;
+
+ String message;
+
+ public void sendMessage() {
+ LOG.log(Level.INFO, "send push message");
+ this.sendPushMessage("hello");
+ }
+
+ private void sendPushMessage(Object message) {
+ helloChannel.send("" + message + " at " + LocalDateTime.now());
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public void sendMessage2() {
+ LOG.log(Level.INFO, "send push message from input box::" + this.message);
+ this.sendPushMessage(this.message);
+ }
+
+}
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi-big.gif
new file mode 100644
index 0000000..70ef35a
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi.gif
new file mode 100644
index 0000000..01b5e91
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Audi.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW-big.gif
new file mode 100644
index 0000000..eaf5a81
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW.gif
new file mode 100644
index 0000000..12b532d
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/BMW.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat-big.gif
new file mode 100644
index 0000000..f58cefd
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat.gif
new file mode 100644
index 0000000..2f0a31c
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Fiat.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford-big.gif
new file mode 100644
index 0000000..4f07120
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford.gif
new file mode 100644
index 0000000..830cb30
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Ford.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda-big.gif
new file mode 100644
index 0000000..cff74c7
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda.gif
new file mode 100644
index 0000000..58e7a4f
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Honda.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar-big.gif
new file mode 100644
index 0000000..dfb5e92
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar.gif
new file mode 100644
index 0000000..c1853da
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Jaguar.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes-big.gif
new file mode 100644
index 0000000..dabf97c
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes.gif
new file mode 100644
index 0000000..76e11f9
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Mercedes.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault-big.gif
new file mode 100644
index 0000000..a5cd2e7
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault.gif
new file mode 100644
index 0000000..6b79d67
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Renault.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen-big.gif
new file mode 100644
index 0000000..7162aae
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen.gif
new file mode 100644
index 0000000..1ae4175
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volkswagen.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo-big.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo-big.gif
new file mode 100644
index 0000000..ad504be
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo-big.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo.gif b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo.gif
new file mode 100644
index 0000000..00af6b6
Binary files /dev/null and b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/demo/images/car/Volvo.gif differ
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/index.xhtml b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/index.xhtml
new file mode 100644
index 0000000..f48f6ce
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/index.xhtml
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:p="http://primefaces.org/ui">
+
+ <f:view contentType="text/html">
+ <h:head>
+ </h:head>
+
+ <h:body>
+ <p:growl>
+ <p:autoUpdate />
+ </p:growl>
+
+ <h:form id="form">
+ <p:dataTable var="car" value="#{dtLazyView.lazyModel}" paginator="true" rows="10"
+ paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
+ rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{dtLazyView.selectedCar}" id="carTable" lazy="true">
+ <p:ajax event="rowSelect" listener="#{dtLazyView.onRowSelect}" update=":form:carDetail" oncomplete="PF('carDialog').show()" />
+ <p:column headerText="Id" sortBy="#{car.id}" filterBy="#{car.id}">
+ <h:outputText value="#{car.id}" />
+ </p:column>
+ <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}">
+ <h:outputText value="#{car.year}" />
+ </p:column>
+ <p:column headerText="Brand" sortBy="#{car.brand}" filterBy="#{car.brand}">
+ <h:outputText value="#{car.brand}" />
+ </p:column>
+ <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
+ <h:outputText value="#{car.color}" />
+ </p:column>
+ </p:dataTable>
+
+ <p:dialog header="Car Detail" widgetVar="carDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false">
+ <p:outputPanel id="carDetail" style="text-align:center;">
+ <p:panelGrid columns="2" rendered="#{not empty dtLazyView.selectedCar}" columnClasses="label,value">
+ <f:facet name="header">
+ <p:graphicImage name="demo/images/car/#{dtLazyView.selectedCar.brand}-big.gif"/>
+ </f:facet>
+
+ <h:outputText value="Id:" />
+ <h:outputText value="#{dtLazyView.selectedCar.id}" />
+
+ <h:outputText value="Year" />
+ <h:outputText value="#{dtLazyView.selectedCar.year}" />
+
+ <h:outputText value="Color:" />
+ <h:outputText value="#{dtLazyView.selectedCar.color}" style="color:#{dtLazyView.selectedCar.color}"/>
+
+ <h:outputText value="Price:" />
+ <h:outputText value="#{dtLazyView.selectedCar.price}">
+ <f:convertNumber type="currency" currencySymbol="$" />
+ </h:outputText>
+ </p:panelGrid>
+ </p:outputPanel>
+ </p:dialog>
+ </h:form>
+ </h:body>
+
+ </f:view>
+</html>
+
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/issue4.xhtml b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/issue4.xhtml
new file mode 100644
index 0000000..972a861
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/issue4.xhtml
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:p="http://primefaces.org/ui">
+
+ <f:view contentType="text/html">
+ <h:head>
+ </h:head>
+
+ <h:body>
+ <h:form id="form">
+ <p:commandButton value="property action listener">
+ <f:setPropertyActionListener value="true"
+ target="#{facesContext.externalContext.flash.keepMessages}"/>
+ </p:commandButton>
+ </h:form>
+ </h:body>
+
+ </f:view>
+</html>
+
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/methodHandleELResolver.xhtml b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/methodHandleELResolver.xhtml
new file mode 100644
index 0000000..9f580bd
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/methodHandleELResolver.xhtml
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:p="http://primefaces.org/ui">
+
+ <f:view contentType="text/html">
+
+ <f:metadata>
+ <f:phaseListener binding="#{methodHandleELResolverBean}" />
+ </f:metadata>
+
+ <h:head>
+ </h:head>
+
+ <h:body>
+ <h:form id="form">
+
+ Setter & Getter test:
+ <h:inputText value="#{methodHandleELResolverBean.test}" />
+ <h:inputText value="#{methodHandleELResolverBean.test2}" />
+ <p:commandButton process="@form" update="@form" value="Process and Update" />
+ <p:commandButton process="@this" update="@form" value="Update only" />
+
+ </h:form>
+
+ <br />
+
+ <ui:repeat var="car" value="#{methodHandleELResolverBean.cars}">
+ <h:outputText value="#{car.id}" />
+ <h:outputText value="#{car.year}" />
+ <h:outputText value="#{car.brand}" />
+ <h:outputText value="#{car.color}" />
+ </ui:repeat>
+ </h:body>
+
+ </f:view>
+</html>
+
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/socket.xhtml b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/socket.xhtml
new file mode 100644
index 0000000..6170a0b
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/socket.xhtml
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en"
+ xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:jsf="http://xmlns.jcp.org/jsf"
+ xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
+ xmlns:f="http://xmlns.jcp.org/jsf/core"
+ xmlns:h="http://xmlns.jcp.org/jsf/html"
+ >
+ <h:head>
+ <title>JSF 2.3: Websocket Sample</title>
+ <script>
+ function onMessage(message, channel, event) {
+ console.log('jsf push message::' + message + ", channel ::" + channel + ", event::" + event);
+ document.getElementById("message").innerHTML = message;
+ }
+ </script>
+ </h:head>
+ <h:body>
+ <h1>JSF 2.3: Hello Websocket </h1>
+ <div id="message" />
+ <hr />
+ <h:form id="form">
+ <div>
+ <h:commandButton
+ id="sendMessage"
+ type="submit"
+ action="#{socketView.sendMessage()}" value="Send Message">
+ <f:ajax />
+ </h:commandButton>
+ </div>
+ <div>
+ <h:outputLabel for="messageInput" value="Say hi to JSF Websocket" />
+ <h:inputText
+ id="messageInput"
+ value="#{socketView.message}"/>
+
+ </div>
+ <h:panelGroup layout="block" id="messageFromInputBox">
+ Input text is :: #{socketView.message}
+ </h:panelGroup>
+ <div>
+ <h:commandButton
+ id="sendMessage2"
+ action="#{socketView.sendMessage2()}"
+ value="Send Message from Input Box">
+ <f:ajax execute="@form" render="messageFromInputBox" />
+ </h:commandButton>
+ </div>
+ <div>
+ <button
+ jsf:id="sendMessage3"
+ jsf:action="#{socketView.sendMessage2()}" >
+ Send Message from Input Box(HTML 5 Button)
+ <f:ajax execute="@form" render="messageFromInputBox" />
+ </button>
+ </div>
+ </h:form>
+ <f:websocket channel="helloChannel" onmessage="onMessage" />
+ </h:body>
+</html>
diff --git a/extensions/quarkus/showcase/src/main/resources/META-INF/resources/val.xhtml b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/val.xhtml
new file mode 100644
index 0000000..3c8a7a8
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/META-INF/resources/val.xhtml
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:p="http://primefaces.org/ui">
+
+ <f:view contentType="text/html">
+ <h:head>
+ </h:head>
+
+ <h:body>
+ <p:growl>
+ <p:autoUpdate />
+ </p:growl>
+
+ <h:form id="form">
+ <h:inputText value="#{inputController.val}" validator="myVal" />
+ <p:commandButton process="@form" update="@form" value="Submit" />
+
+
+ <h:dataTable value="#{myBacking.cars}" var="car">
+ <h:column>#{car.id}</h:column>
+ </h:dataTable>
+
+ </h:form>
+ </h:body>
+
+ </f:view>
+</html>
+
diff --git a/extensions/quarkus/showcase/src/main/resources/application.properties b/extensions/quarkus/showcase/src/main/resources/application.properties
new file mode 100644
index 0000000..7839794
--- /dev/null
+++ b/extensions/quarkus/showcase/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+quarkus.log.console.format=%s%n
+javax.faces.PROJECT_STAGE = Production
+javax.faces.ENABLE_WEBSOCKET_ENDPOINT=true
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3d17bf0..269d5e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,7 @@
<!--
<module>integration-tests</module>
-->
+ <module>extensions</module>
</modules>
<build>