From 01dc80c4fd620ff11b2046a800a8561098f5b6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20Lindstr=C3=B6m?= Date: Mon, 15 Jun 2026 01:49:02 +0300 Subject: [PATCH 1/4] feat: Create Vaadin 7 EM/Jakarta version of CDI-4 (WIP) --- .gitignore | 7 + .project | 11 + .travis-settings.xml | 9 - .travis.after_success.sh | 8 - .travis.yml | 19 - .vscode/settings.json | 3 + README.md | 84 ++- assembly/MANIFEST.MF | 7 + assembly/assembly.xml | 44 ++ checkstyle/header | 10 + checkstyle/vaadin-checkstyle.xml | 261 +++++++++ pom.xml | 18 +- vaadin-cdi/.project | 11 + vaadin-cdi/README.md | 152 ----- vaadin-cdi/pom.xml | 519 ++++++++++++++---- vaadin-cdi/src/license/header.txt | 8 + vaadin-cdi/src/license/license.txt | 3 + .../java/com/vaadin/cdi/AfterViewChange.java | 46 ++ .../java/com/vaadin/cdi/CDINavigator.java | 101 ++++ .../src/main/java/com/vaadin/cdi/CDIUI.java | 23 +- .../java/com/vaadin/cdi/CDIUIProvider.java | 239 ++++---- .../src/main/java/com/vaadin/cdi/CDIView.java | 60 +- .../java/com/vaadin/cdi/CDIViewProvider.java | 258 +++------ .../java/com/vaadin/cdi/NormalUIScoped.java | 23 +- .../java/com/vaadin/cdi/NormalViewScoped.java | 23 +- .../main/java/com/vaadin/cdi/UIScoped.java | 23 +- .../main/java/com/vaadin/cdi/URLMapping.java | 21 +- .../com/vaadin/cdi/VaadinSessionScoped.java | 34 ++ .../main/java/com/vaadin/cdi/ViewScoped.java | 23 +- .../com/vaadin/cdi/access/AccessControl.java | 23 +- .../vaadin/cdi/access/JaasAccessControl.java | 29 +- .../cdi/internal/AbstractVaadinContext.java | 277 ---------- .../vaadin/cdi/internal/AnnotationUtil.java | 29 +- .../java/com/vaadin/cdi/internal/CDIUtil.java | 75 --- .../vaadin/cdi/internal/ContextDeployer.java | 47 +- .../vaadin/cdi/internal/ContextWrapper.java | 40 +- .../com/vaadin/cdi/internal/Conventions.java | 22 +- .../InconsistentDeploymentException.java | 30 +- .../java/com/vaadin/cdi/internal/UIBean.java | 132 ----- .../com/vaadin/cdi/internal/UIContextual.java | 93 ---- .../internal/UIContextualStorageManager.java | 91 +++ .../vaadin/cdi/internal/UIScopedContext.java | 115 +--- .../cdi/internal/VaadinContextualStorage.java | 55 +- .../vaadin/cdi/internal/VaadinExtension.java | 151 +++-- .../internal/VaadinSessionDestroyEvent.java | 32 -- .../internal/VaadinSessionScopedContext.java | 88 +++ .../cdi/internal/VaadinUICloseEvent.java | 37 -- .../VaadinViewChangeCleanupEvent.java | 35 -- .../cdi/internal/VaadinViewChangeEvent.java | 44 -- .../cdi/internal/VaadinViewCreationEvent.java | 41 -- .../com/vaadin/cdi/internal/ViewBean.java | 143 ----- .../cdi/internal/ViewContextStrategies.java | 83 +++ .../internal/ViewContextStrategyProvider.java | 72 +++ .../vaadin/cdi/internal/ViewContextual.java | 70 --- .../ViewContextualStorageManager.java | 128 +++++ .../cdi/internal/ViewScopedContext.java | 180 +----- .../vaadin/cdi/server/VaadinCDIServlet.java | 21 +- .../cdi/server/VaadinCDIServletService.java | 83 +-- .../ViewContextByName.java | 37 ++ .../ViewContextByNameAndParameters.java | 40 ++ .../ViewContextByNavigation.java | 36 ++ .../ViewContextStrategy.java | 80 +++ .../ViewContextStrategyQualifier.java | 32 ++ .../src/main/resources/META-INF/beans.xml | 7 +- ...> jakarta.enterprise.inject.spi.Extension} | 0 .../cdi/AbstractCDIIntegrationTest.java | 43 +- .../AbstractManagedCDIIntegrationTest.java | 67 +-- .../vaadin/cdi/AbstractViewStrategyTest.java | 122 ++++ .../java/com/vaadin/cdi/ArchiveProvider.java | 63 +-- ...egrationWithConflictingDeploymentTest.java | 22 +- ...IIntegrationWithConflictingUIPathTest.java | 33 -- ...DIIntegrationWithCustomDeploymentTest.java | 22 +- ...IIntegrationWithDefaultDeploymentTest.java | 54 +- .../com/vaadin/cdi/CDIUIProviderTest.java | 67 ++- .../cdi/CDIUIProviderViewDetectionTest.java | 79 +++ .../com/vaadin/cdi/ClusterTestCategory.java | 14 + .../vaadin/cdi/ConsistentInjectionTest.java | 10 + .../com/vaadin/cdi/CrossInjectionTest.java | 10 + .../com/vaadin/cdi/DeploymentTestSuiteIT.java | 21 +- .../InappropriateCDIViewInDeploymentTest.java | 31 -- .../cdi/InappropriateDeploymentTest.java | 96 ++++ ...ropriateNestedServletInDeploymentTest.java | 47 -- .../java/com/vaadin/cdi/InjectionTest.java | 15 +- .../cdi/MultipleAccessIsolationTest.java | 17 +- .../com/vaadin/cdi/MultipleRootUIsTest.java | 22 +- .../com/vaadin/cdi/MultipleSessionTest.java | 13 +- .../vaadin/cdi/NonPassivatingBeanTest.java | 11 +- .../java/com/vaadin/cdi/NoneTestCategory.java | 14 + .../com/vaadin/cdi/ProxiedClusteringTest.java | 171 ++++++ .../vaadin/cdi/QualifiedInjectionTest.java | 10 + .../vaadin/cdi/RootViewAtContextRootTest.java | 10 + .../com/vaadin/cdi/ScopedInstancesTest.java | 42 +- .../com/vaadin/cdi/ScopedProducerTest.java | 13 +- .../com/vaadin/cdi/SessionContextTest.java | 75 +++ .../vaadin/cdi/SessionReplicationTest.java | 79 +++ .../java/com/vaadin/cdi/UIDestroyTest.java | 52 +- .../com/vaadin/cdi/UINormalDestroyTest.java | 11 - .../vaadin/cdi/ViewDestroyNormalUITest.java | 11 - .../java/com/vaadin/cdi/ViewDestroyTest.java | 67 ++- .../com/vaadin/cdi/ViewNavigationTest.java | 118 ++++ .../vaadin/cdi/ViewStrategiesUiInitTest.java | 48 ++ .../vaadin/cdi/ViewStrategyAlwaysTest.java | 72 +++ .../com/vaadin/cdi/ViewStrategyCallTest.java | 104 ++++ .../ViewStrategyViewNameAndParamsTest.java | 70 +++ .../vaadin/cdi/ViewStrategyViewNameTest.java | 74 +++ .../java/com/vaadin/cdi/internal/Alpha.java | 12 +- .../com/vaadin/cdi/internal/AlphaBean.java | 10 + .../java/com/vaadin/cdi/internal/Beta.java | 12 +- .../com/vaadin/cdi/internal/BetaBean.java | 10 + .../cdi/internal/ClusterIncTestLayout.java | 75 +++ .../vaadin/cdi/internal/ConventionsTest.java | 22 +- .../java/com/vaadin/cdi/internal/Counter.java | 12 +- .../vaadin/cdi/internal/CounterFilter.java | 18 +- .../cdi/internal/CrossInjectingBean.java | 12 +- .../java/com/vaadin/cdi/internal/MyBean.java | 10 + .../cdi/internal/NonPassivatingBean.java | 10 + .../com/vaadin/cdi/internal/Preferred.java | 12 +- .../com/vaadin/cdi/internal/ProducedBean.java | 12 +- .../com/vaadin/cdi/internal/UIScopedBean.java | 10 + .../vaadin/cdi/internal/ViewScopedBean.java | 10 + .../cdi/shiro/AbstractShiroTestView.java | 10 + .../java/com/vaadin/cdi/shiro/AdminView.java | 12 +- .../java/com/vaadin/cdi/shiro/GuestView.java | 10 + .../java/com/vaadin/cdi/shiro/LoginPane.java | 10 + .../vaadin/cdi/shiro/ShiroAccessControl.java | 14 +- .../java/com/vaadin/cdi/shiro/ShiroTest.java | 26 +- .../com/vaadin/cdi/shiro/ShiroWebFilter.java | 14 +- .../vaadin/cdi/shiro/ShiroWebListener.java | 12 +- .../java/com/vaadin/cdi/shiro/ViewerView.java | 12 +- .../cdi/uis/AnotherPathCollisionUI.java | 22 +- .../java/com/vaadin/cdi/uis/Boundary.java | 23 +- .../vaadin/cdi/uis/CDIUINotExtendingUI.java | 18 + .../com/vaadin/cdi/uis/CDIUIWrongScope.java | 25 + .../java/com/vaadin/cdi/uis/ConcurrentUI.java | 14 +- .../com/vaadin/cdi/uis/ConflictingRootUI.java | 22 +- .../vaadin/cdi/uis/ConsistentInjectionUI.java | 14 +- .../com/vaadin/cdi/uis/ConventionalUI.java | 10 + .../com/vaadin/cdi/uis/CustomMappingUI.java | 26 +- .../java/com/vaadin/cdi/uis/DanglingView.java | 26 +- .../cdi/uis/DependentCDIEventListener.java | 28 +- .../com/vaadin/cdi/uis/DestroyNormalUI.java | 9 - .../java/com/vaadin/cdi/uis/DestroyUI.java | 59 +- .../vaadin/cdi/uis/DestroyViewNormalUI.java | 9 - .../com/vaadin/cdi/uis/DestroyViewUI.java | 106 ++-- .../com/vaadin/cdi/uis/EnterpriseLabel.java | 26 +- .../java/com/vaadin/cdi/uis/EnterpriseUI.java | 26 +- .../java/com/vaadin/cdi/uis/InjectionUI.java | 14 +- .../cdi/uis/InstrumentedInterceptor.java | 28 +- .../com/vaadin/cdi/uis/InstrumentedUI.java | 38 +- .../com/vaadin/cdi/uis/InstrumentedView.java | 28 +- .../com/vaadin/cdi/uis/InterceptedBean.java | 24 +- .../com/vaadin/cdi/uis/InterceptedUI.java | 28 +- .../com/vaadin/cdi/uis/MultipleSessionUI.java | 26 +- .../com/vaadin/cdi/uis/NavigatableUI.java | 24 +- .../cdi/uis/NoViewProviderNavigationUI.java | 72 --- .../com/vaadin/cdi/uis/NonPassivatingUI.java | 25 +- .../com/vaadin/cdi/uis/NotExistingUI.java | 22 +- .../cdi/uis/ParameterizedNavigationUI.java | 35 +- .../com/vaadin/cdi/uis/PathCollisionUI.java | 22 +- .../vaadin/cdi/uis/PlainAlternativeUI.java | 27 +- .../cdi/uis/PlainColidingAlternativeUI.java | 28 +- .../test/java/com/vaadin/cdi/uis/PlainUI.java | 26 +- .../java/com/vaadin/cdi/uis/ProducerUI.java | 16 +- .../vaadin/cdi/uis/QualifierInjectionUI.java | 12 +- .../com/vaadin/cdi/uis/RestrictedView.java | 26 +- .../test/java/com/vaadin/cdi/uis/RootUI.java | 26 +- .../cdi/uis/ScopedInstrumentedView.java | 22 +- .../java/com/vaadin/cdi/uis/SecondUI.java | 36 +- .../vaadin/cdi/uis/SessionReplicationUI.java | 89 +++ .../java/com/vaadin/cdi/uis/SessionUI.java | 97 ++++ .../test/java/com/vaadin/cdi/uis/SubUI.java | 21 +- .../test/java/com/vaadin/cdi/uis/TestUI.java | 10 + .../com/vaadin/cdi/uis/UIScopedIncUI.java | 49 ++ .../cdi/uis/UIWithCDIDependentListener.java | 28 +- .../vaadin/cdi/uis/UIWithCDISelfListener.java | 30 +- .../vaadin/cdi/uis/UIWithNestedServlet.java | 12 +- .../java/com/vaadin/cdi/uis/UnsecuredUI.java | 24 +- .../com/vaadin/cdi/uis/ViewNavigationUI.java | 217 ++++++++ .../com/vaadin/cdi/uis/ViewScopedIncUI.java | 82 +++ .../vaadin/cdi/uis/ViewStrategyCallUI.java | 148 +++++ .../vaadin/cdi/uis/ViewStrategyInitUI.java | 83 +++ .../com/vaadin/cdi/uis/ViewStrategyUI.java | 224 ++++++++ .../vaadin/cdi/uis/ViewWithoutAnnotation.java | 22 +- .../cdi/uis/WithAnnotationRegisteredView.java | 22 +- .../cdi/views/AbstractNavigatableView.java | 10 + .../views/AbstractScopedInstancesView.java | 10 + .../java/com/vaadin/cdi/views/BeanView.java | 14 +- .../vaadin/cdi/views/CDIViewDependent.java | 27 + .../cdi/views/CDIViewNotImplementingView.java | 10 + .../vaadin/cdi/views/ConventionalView.java | 16 +- .../vaadin/cdi/views/CrossInjectingView.java | 12 +- .../java/com/vaadin/cdi/views/MainView.java | 10 + .../cdi/views/NonPassivatingContentView.java | 65 +-- .../cdi/views/OneAndOnlyViewWithPath.java | 22 +- .../cdi/views/OneAndOnlyViewWithoutPath.java | 22 +- ...neAndOnlyViewWithoutPathAndAnnotation.java | 22 +- .../java/com/vaadin/cdi/views/RootView.java | 14 +- .../java/com/vaadin/cdi/views/SubView.java | 10 + .../java/com/vaadin/cdi/views/TestView.java | 10 + .../com/vaadin/cdi/views/UIScopedView.java | 35 +- .../com/vaadin/cdi/views/ViewScopedView.java | 48 +- vaadin-cdi/src/test/resources/arquillian.xml | 66 ++- .../resources/tomeecluster/conf/server1.xml | 49 ++ .../resources/tomeecluster/conf/server2.xml | 49 ++ 204 files changed, 6115 insertions(+), 3465 deletions(-) delete mode 100644 .travis-settings.xml delete mode 100755 .travis.after_success.sh delete mode 100644 .travis.yml create mode 100644 .vscode/settings.json create mode 100644 assembly/MANIFEST.MF create mode 100644 assembly/assembly.xml create mode 100644 checkstyle/header create mode 100644 checkstyle/vaadin-checkstyle.xml delete mode 100644 vaadin-cdi/README.md create mode 100644 vaadin-cdi/src/license/header.txt create mode 100644 vaadin-cdi/src/license/license.txt create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/AfterViewChange.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/CDINavigator.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/VaadinSessionScoped.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AbstractVaadinContext.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/CDIUtil.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIBean.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextual.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextualStorageManager.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionDestroyEvent.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionScopedContext.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinUICloseEvent.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeCleanupEvent.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeEvent.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewCreationEvent.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewBean.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategies.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategyProvider.java delete mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextual.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextualStorageManager.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByName.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNameAndParameters.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNavigation.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategy.java create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategyQualifier.java rename vaadin-cdi/src/main/resources/META-INF/services/{javax.enterprise.inject.spi.Extension => jakarta.enterprise.inject.spi.Extension} (100%) create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractViewStrategyTest.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingUIPathTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderViewDetectionTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ClusterTestCategory.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateCDIViewInDeploymentTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateDeploymentTest.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateNestedServletInDeploymentTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/NoneTestCategory.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ProxiedClusteringTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/SessionContextTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/SessionReplicationTest.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/UINormalDestroyTest.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyNormalUITest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategiesUiInitTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyAlwaysTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyCallTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameAndParamsTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameTest.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ClusterIncTestLayout.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUINotExtendingUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUIWrongScope.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyNormalUI.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewNormalUI.java delete mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NoViewProviderNavigationUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionReplicationUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIScopedIncUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewScopedIncUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyCallUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyInitUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyUI.java create mode 100644 vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewDependent.java create mode 100644 vaadin-cdi/src/test/resources/tomeecluster/conf/server1.xml create mode 100644 vaadin-cdi/src/test/resources/tomeecluster/conf/server2.xml diff --git a/.gitignore b/.gitignore index aff244f5..f3659868 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,10 @@ nbactions.xml .iml *.iml *.log +*.class +/build +# Package Files # +*.jar +*.war +*.ear +target/ diff --git a/.project b/.project index 2214b913..de4f0be6 100644 --- a/.project +++ b/.project @@ -14,4 +14,15 @@ org.eclipse.m2e.core.maven2Nature + + + 1781474857981 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/.travis-settings.xml b/.travis-settings.xml deleted file mode 100644 index 3f8341fb..00000000 --- a/.travis-settings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - vaadin-snapshots - ${env.SONATYPE_USERNAME} - ${env.SONATYPE_PASSWORD} - - - diff --git a/.travis.after_success.sh b/.travis.after_success.sh deleted file mode 100755 index e230db03..00000000 --- a/.travis.after_success.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_SECURE_ENV_VARS" = "true" ] -then - cd vaadin-cdi - mvn deploy --settings ../.travis-settings.xml -DrepositoryId=vaadin-snapshots -DaltDeploymentRepository=vaadin-snapshots::default::https://oss.sonatype.org/content/repositories/vaadin-snapshots/ -DskipTests=true -DskipITs -B -fi - diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c3448c1d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -language: java -jdk: oraclejdk8 -after_success: "./.travis.after_success.sh" -sudo: required -dist: trusty -branches: - only: - - master - - 2.0 - - 1.0 -cache: - directories: - - "$HOME/.m2" -before_cache: -- rm -rf $HOME/.m2/repository/com/vaadin -env: - global: - - secure: CWB5FABZ+HtT2YxpQgZVNjjG1zAX1fu/U+oS9lsiNMmm/WtP5UWZwT1w5jV97+gZNxN3c4GdKMrqDJDzfOfluSmd9VQ3VbTFjB/v2sIKpSrTVMOrteIsQyddcgBXZFnGnPlxDiPWFQ5JW6NMqDOQATEMzismamvKIDai8c2S1ck= - - secure: OvfkT2hyFw0i71Lexyc8Dm3bojbeX9qo1OOQuzSYUDl82rYjqvvfho0gKLCKsqfdGp4SmLZKBD6P+oo+uVVIrxfMTNDZ6d9+tN0QUd25Otd9mS81bhgPRH8dsxd5DA84e3g44y5IwcIstTlStgHrb1+86UHyxc75gl3j9TVYWxY= diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..c5f3f6b9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/README.md b/README.md index 770f38f4..a2f315a3 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,71 @@ -Vaadin CDI -====================== +[![Published on Vaadin Directory](https://img.shields.io/badge/Vaadin%20Directory-published-00b4f0.svg)](https://vaadin.com/directory/component/vaadin-cdi) +[![Stars on Vaadin Directory](https://img.shields.io/vaadin-directory/star/vaadin-cdi.svg)](https://vaadin.com/directory/component/vaadin-cdi) -Vaadin CDI is the official CDI integration for [Vaadin Framework](https://github.com/vaadin/framework). -This branch is Vaadin Framework 7 compatible. See other branches for other framework versions: -* master for Vaadin 10 +# Vaadin CDI + +This is the official CDI integration for [Vaadin Flow](https://github.com/vaadin/flow). + +This branch is compatible with upcoming Vaadin platform versions. See other branches for other Vaadin versions: + +* 16.1 for Vaadin 25.2 +* 16.0 for Vaadin 25.0 and 25.1 +* 15.2 for Vaadin 24.8 +* 15.1 for Vaadin 24.4 +* 15.0 for Vaadin 24 +* 14.1 for Vaadin 23.3 +* 13.1 for Vaadin 22.1 +* 11.3 for Vaadin 14.10 +* 10.0 for Vaadin 10 +* 4.0 for Vaadin 8 Extended Maintenance with Jakarta * 3.0 for Vaadin 8.2+ * 2.0 for Vaadin Framework 8.0...8.1 versions +* 1.9 for Vaadin Framework 7 Extended Maintenance with Jakarta * 1.0 for Vaadin Framework 7 versions -Download release ----- +## Using with Vaadin + +To use CDI with Vaadin, you need to add the following dependency to your pom.xml: +```xml + + com.vaadin + vaadin-cdi + 15.2.0 + +``` + +Since the current release version is a prerelease, you need to also include the prerelease Maven repository: + +```xml + + + Vaadin prereleases + https://maven.vaadin.com/vaadin-prereleases + + +``` + +## Getting started + +**NOTE: This is still WIP.** The easiest way for starting a project is to go to [vaadin.com/start](https://vaadin.com/start) and select the _Project Base with CDI_ to get an empty project with everything setup ready for you. + +**NOTE: This is still WIP.** There is a tutorial also available in https://github.com/vaadin/flow-cdi-tutorial that helps you get started with Vaadin 10 and CDI. + +## Building the project -Official releases of this add-on are available at Vaadin Directory. For Maven instructions, download and reviews, go to https://vaadin.com/addon/vaadin-cdi. +Execute `mvn clean install -DskipTests` in the root directory to build vaadin-cdi. -Building the project ----- -Execute `mvn clean install` in the root directory to build vaadin-cdi. +## Run integration tests -Issue tracking ----- -If you find an issue, please report it in the GitHub issue tracker: https://github.com/vaadin/cdi/issues +Execute `mvn -pl vaadin-cdi -Pwildfly verify` in the root directory to run integration tests. -Contributions ----- -Contributions to the project can be done through pull requests in GitHub. +Test can be executed against the following containers, activating the specific profile: +* Wildfly Jakarta EE 10: `-Pwidfly` -Copyright 2012-2017 Vaadin Ltd. +## Issue tracking -Licensed 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 +If you find an issue, please report it in the [GitHub issue tracker](https://github.com/vaadin/cdi/issues). -http://www.apache.org/licenses/LICENSE-2.0 +## Contributions -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. +The contributing docs can be found here: https://vaadin.com/docs-beta/latest/guide/contributing/overview/ \ No newline at end of file diff --git a/assembly/MANIFEST.MF b/assembly/MANIFEST.MF new file mode 100644 index 00000000..74bab89f --- /dev/null +++ b/assembly/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Vaadin-Package-Version: 1 +Vaadin-Addon: ${Vaadin-Addon} +Vaadin-License-Title: ${Vaadin-License-Title} +Implementation-Vendor: ${Implementation-Vendor} +Implementation-Title: ${Implementation-Title} +Implementation-Version: ${Implementation-Version} diff --git a/assembly/assembly.xml b/assembly/assembly.xml new file mode 100644 index 00000000..ad369c59 --- /dev/null +++ b/assembly/assembly.xml @@ -0,0 +1,44 @@ + + + addon + + + + + zip + + + + false + + + + . + + license-*.txt + licensing.txt + + + + target + + + *.jar + *.pdf + + + + + + + + assembly/MANIFEST.MF + META-INF + true + + + \ No newline at end of file diff --git a/checkstyle/header b/checkstyle/header new file mode 100644 index 00000000..76f577cb --- /dev/null +++ b/checkstyle/header @@ -0,0 +1,10 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ \ No newline at end of file diff --git a/checkstyle/vaadin-checkstyle.xml b/checkstyle/vaadin-checkstyle.xml new file mode 100644 index 00000000..b2855792 --- /dev/null +++ b/checkstyle/vaadin-checkstyle.xml @@ -0,0 +1,261 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index af183a7a..3e03e0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,10 +1,11 @@ - + 4.0.0 + com.vaadin vaadin-cdi-main - 1.0-SNAPSHOT + 1.9-SNAPSHOT pom vaadin-cdi-main @@ -12,15 +13,20 @@ Vaadin Ltd - http://vaadin.com + https://vaadin.com + + 21 + 21 + 21 + maven-deploy-plugin - 2.5 + 3.1.4 true @@ -28,7 +34,7 @@ org.apache.maven.plugins maven-assembly-plugin - 2.2.1 + 3.8.0 true diff --git a/vaadin-cdi/.project b/vaadin-cdi/.project index 93aeb5bf..21dd7c77 100644 --- a/vaadin-cdi/.project +++ b/vaadin-cdi/.project @@ -33,4 +33,15 @@ org.eclipse.wst.common.project.facet.core.nature org.eclipse.jdt.core.javanature + + + 1781259607826 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/vaadin-cdi/README.md b/vaadin-cdi/README.md deleted file mode 100644 index 7cb9be1c..00000000 --- a/vaadin-cdi/README.md +++ /dev/null @@ -1,152 +0,0 @@ -vaadin-cdi -========== - -Vaadin-CDI is the official CDI integration for Vaadin framework version 7. - -Changes in 1.0.4 ------------------------ - -- Fix closed UI cleanup -- Open CDIViewProvider methods getViewBean() and parseViewName() for extension - - -Changes in 1.0.3 ------------------------ - -- Upgrade DeltaSpike to 1.4.1 -- Update Vaadin dependendency - -Note: some compatibility issues have been reported when using GlassFish -and Vaadin CDI together with some third party CDI related add-ons. -If this happens, add an explicit dependency to DeltaSpike version 1.3.0 -in the project POM, overriding any transitive dependencies. - -Changes in 1.0.2 ------------------------ - -- Accept beans that do not implement PassivationCapable (#15243) - -Changes in 1.0.1 ------------------------ - -- Upgrade DeltaSpike to version 1.0.3 for GlassFish 4.1 compatibility - -Changes in 1.0.0 ------------------------ - -No changes since 1.0.0.rc1. - -Changes in 1.0.0.rc1 ------------------------ - -- moved the classes VaadinCDIServlet and VaadinCDIServletService to the - package com.vaadin.cdi.servlet -- do not add hyphens within all caps abbreviations in automatic UI/view names, - e.g. MyCDIUI becomes my-cdi and MyCDITestView becomes my-cdi-test -- added check at deployment time: classes with @CDIView must implement View -- added check at deployment time: if a servlet class is nested in a UI with - @CDIUI, it must extend VaadinCDIServlet - -Changes in 1.0.0.beta4 ------------------------ - -- removed the blocking of injecting Vaadin components in normal scopes - that was introduced in 1.0.0.beta3 - -While it is now possible to inject Vaadin components in normal scopes -(including @NormalUIScoped and @NormalViewScoped), it is not recommended -as the proxies generated by CDI implementations may cause complications e.g. -with Java collections. Please report any such issues in the Vaadin framework -as tickets at http://dev.vaadin.com/newticket . - -For components injected in normal scopes, interceptors and decorators should -only be used for methods that are not called directly by the framework. - -See also the notes for earlier releases below. - -Changes in 1.0.0.beta3 ------------------------ - -- breaking change: @UIScoped and @ViewScoped are no longer @NormalScope - - added corresponding @NormalUIScoped and @NormalViewScoped -- breaking change: NormalScopes (including @NormalUIScoped and - @NormalViewScoped) are not supported classes implementing - com.vaadin.ui.Component -- See http://dev.vaadin.com/query?status=closed&status=released&milestone=Vaadin+CDI+1.0.0.beta3 - for the complete list of changes. - -See also the notes for earlier releases below. - -Changes in 1.0.0.beta2 ------------------------ - -- @UIScoped and @ViewScoped can be used on methods - (producer methods, setter injection, constructor injection) -- Dependency on Guava eliminated -- Various fixes including - - UI and View are now correctly included in their own scopes - - Sub-views with slash in view name are now handled correctly -- See http://dev.vaadin.com/query?status=closed&status=released&milestone=Vaadin+CDI+1.0.0.beta2 - for the complete list of changes. - -See also the notes for earlier releases below. - -Changes in 1.0.0.beta1 ------------------------ - -Note: Vaadin CDI 1.0.0.beta1 and later requires Vaadin 7.3.1 or later. -Injection of beans other than components also works with earlier Vaadin -versions. - -See also the changes in 1.0.0.alpha3 below for a breaking change (view and UI -name mappings) when upgrading from earlier versions. - -- @ViewScoped context -- @UIScoped and @ViewScoped use @NormalScope, supporting interceptors etc. -- Better support for server push (including WebSockets) and operations in - background threads (within UI.access()) -- DeltaSpike library is used internally by the add-on -- Various fixes and small enhancements -- See http://dev.vaadin.com/query?status=closed&status=released&milestone=Vaadin+CDI+1.0.0.beta1 - for the complete list of changes. - -If any VaadinServlet is explicitly configured either with @WebServlet or -with web.xml, automatic deployment of a CDI servlet will not take place. -In such cases, you should register a VaadinCDIServlet either for "/*" or -for "/mypath/*" and "/VAADIN/*" - -To use a custom servlet class, it is recommended to inherit VaadinCDIServlet. -Overriding createServletService() is possible, in which case the service -should inherit VaadinCDIServletService if possible or duplicate its -functionality otherwise. - -Changes in 1.0.0.alpha3 ------------------------ - -- Reintroduce conventions for mapping of views and UIs - - This requires updating @CDIUI and @CDIView parameter values in existing - applications. - - see http://dev.vaadin.com/ticket/12385 for details -- @UIScoped is inherited by subclasses of an annotated UI -- Support non-JEE containers with Weld (BeanManager look-up) -- Use BeanManager.resolve() to support @Alternative UIs -- Partial passivation support -- Automatically injected servlet has async-supported enabled -- Reduced unnecessary logging -- See http://dev.vaadin.com/query?&status=released&milestone=Vaadin+CDI+1.0.0.alpha3 - for the complete list of changes. - - -Copyright 2012-2017 Vaadin Ltd. - -Licensed 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. diff --git a/vaadin-cdi/pom.xml b/vaadin-cdi/pom.xml index f9f9ec95..b8d9d34b 100644 --- a/vaadin-cdi/pom.xml +++ b/vaadin-cdi/pom.xml @@ -1,55 +1,146 @@ - + 4.0.0 - - com.vaadin - vaadin-parent - 1.1.0 - + + com.vaadin + vaadin-parent + 3.0.0 + + com.vaadin vaadin-cdi - 1.0-SNAPSHOT + 1.9-SNAPSHOT jar UTF-8 UTF-8 - - - 7.7.7 - 1.7.2 + 2026 + + 21 + 21 + 21 + + 7.7.52 + 2.0.0 + 11.0.0 - 2.53.0 - 1.3.2 - 1.1.11.Final + 4.21.0 + 2.1.0 + 1.9.1.Final ${project.version} Vaadin CDI ${project.organization.name} - Apache License 2.0 + Vaadin Commercial License and Service Terms vaadin-cdi-${project.version}.jar + - - - vaadin-snapshots - Vaadin snapshot repository - http://oss.sonatype.org/content/repositories/vaadin-snapshots/ - - + + + + jakarta.platform + jakarta.jakartaee-bom + ${jakarta.ee.version} + pom + import + + + org.jboss.arquillian + arquillian-bom + ${arquillian.version} + import + pom + + + org.seleniumhq.selenium + selenium-bom + ${selenium.version} + pom + import + + + org.wildfly + wildfly-dist + 35.0.1.Final + zip + + + org.apache.shiro + shiro-bom + ${shiro.version} + import + pom + + + com.google.inject + guice + 7.0.0 + + + + + + + + central + https://repo.maven.apache.org/maven2 + + false + + + + vaadin-prereleases + + https://maven.vaadin.com/vaadin-prereleases/ + + + true + + + + + Vaadin Directory + https://maven.vaadin.com/vaadin-addons + + false + + + + + + + + central + https://repo.maven.apache.org/maven2 + + false + + + + vaadin-prereleases + + https://maven.vaadin.com/vaadin-prereleases/ + + + true + + + vaadin-cdi - http://vaadin.com + https://vaadin.com Provides CDI integration for Vaadin projects Vaadin Ltd - http://vaadin.com + https://vaadin.com https://github.com/vaadin/cdi @@ -58,7 +149,7 @@ trac - http://dev.vaadin.com/ + https://dev.vaadin.com/ @@ -77,11 +168,14 @@ Juuso Valli + + Patrik Lindström + - Apache License version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.html + Vaadin Commercial License and Terms + https://vaadin.com/commercial-license-and-service-terms repo @@ -94,7 +188,64 @@ org.apache.maven.plugins maven-source-plugin - 2.1.2 + 3.4.0 + + true + + + + package + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.12.0 + + + package + + jar + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.8.0 + + false + + assembly/assembly.xml + + false + + + + + single + + install + + + + + + + + + prerelease + + + + org.apache.maven.plugins + maven-source-plugin + 3.4.0 true @@ -110,7 +261,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9 + 3.12.0 package @@ -123,7 +274,7 @@ org.apache.maven.plugins maven-assembly-plugin - 2.2.1 + 3.8.0 false @@ -144,32 +295,75 @@ + org.apache.tomee arquillian-tomee-embedded 7.0.2 test - - javax + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + + + + + tomee-cluster + + + org.apache.tomee + arquillian-tomee-remote + 7.0.2 + test + + + org.apache.tomee + apache-tomee + 7.0.2 + webprofile + zip + test + + + jakarta javaee-api - 6.0 + 7.0 provided + + + + org.apache.maven.plugins + maven-surefire-plugin + + always + + tomee-cluster + + com.vaadin.cdi.ClusterTestCategory + com.vaadin.cdi.NoneTestCategory + + + + + --> + + + + wildfly + + + org.wildfly.arquillian + wildfly-arquillian-container-managed + 5.1.0.Final + test + + + org.jboss.threads + jboss-threads + 2.4.0.Final + test + + + org.jboss.logging + jboss-logging + 3.6.1.Final + test + + + org.wildfly.common + wildfly-common + 1.7.0.Final + test + + + org.jboss.logmanager + jboss-logmanager + 2.1.19.Final + test + + + jakarta.platform + jakarta.jakartaee-api + ${jakarta.ee.version} + provided + + @@ -201,9 +484,7 @@ org.wildfly wildfly-dist - 10.1.0.Final zip - false target @@ -218,8 +499,7 @@ always org.jboss.logmanager.LogManager - ${project.build.directory}/wildfly-10.1.0.Final - wildfly + ${project.build.directory}/wildfly-35.0.1.Final false @@ -227,19 +507,20 @@ + - glassfish + payara - org.jboss.arquillian.container - arquillian-glassfish-managed-3.1 - 1.0.0.Final + fish.payara.arquillian + arquillian-payara-server-managed + 3.1 test - javax - javaee-api - 7.0 + jakarta.platform + jakarta.jakartaee-api + ${jakarta.ee.version} provided @@ -258,9 +539,9 @@ - org.glassfish.main.distributions - glassfish - 4.1.1 + fish.payara.distributions + payara + 7.2026.5 zip false target @@ -276,7 +557,7 @@ always - ${project.build.directory}/glassfish4 + ${project.build.directory}/payara7 false @@ -286,25 +567,6 @@ - - - - org.jboss.arquillian - arquillian-bom - ${arquillian.version} - import - pom - - - org.jboss.arquillian.selenium - selenium-bom - ${selenium.version} - pom - import - - - - @@ -312,11 +574,11 @@ com.vaadin - vaadin-server + vaadin-server-mpr-jakarta ${vaadin.version} compile - + org.apache.deltaspike.core @@ -333,10 +595,22 @@ - javax.enterprise - cdi-api - 1.2 - provided + jakarta.enterprise + jakarta.enterprise.cdi-api + provided + + + + jakarta.servlet + jakarta.servlet-api + provided + + + + org.jboss.resteasy + resteasy-client + 6.2.11.Final + provided @@ -349,6 +623,13 @@ org.jboss.shrinkwrap.resolver shrinkwrap-resolver-impl-maven + 3.3.6 + test + + + org.jboss.shrinkwrap.descriptors + shrinkwrap-descriptors-impl-javaee + 2.0.0 test @@ -356,12 +637,12 @@ org.jboss.arquillian.graphene graphene-webdriver pom - 2.1.0.Final + 3.0.1.Final test - javax.enterprise - cdi-api + jakarta.enterprise + cdi-api @@ -369,13 +650,13 @@ junit junit - 4.12 + 4.13.2 test org.mockito - mockito-all - 1.9.5 + mockito-core + 5.12.0 test @@ -392,16 +673,36 @@ test + + org.apache.shiro + shiro-jakarta-ee + jakarta + test + org.apache.shiro shiro-core - ${shiro.version} + jakarta test org.apache.shiro shiro-web - ${shiro.version} + jakarta + test + + + + jakarta.ejb + jakarta.ejb-api + test + + + + + io.undertow + undertow-core + 2.3.17.Final test @@ -411,21 +712,21 @@ org.apache.maven.plugins maven-compiler-plugin - 2.5.1 + 3.15.0 - 1.6 - 1.6 + 21 + 21 org.apache.maven.plugins maven-jar-plugin - 2.3.1 + 3.5.0 true - true + false true @@ -450,7 +751,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.19.1 + 3.5.5 always - org.apache.el.ExpressionFactoryImpl + org.apache.el.ExpressionFactoryImpl false + com.vaadin.cdi.ClusterTestCategory maven-deploy-plugin - 2.5 + 3.1.4 org.apache.maven.plugins maven-checkstyle-plugin - 2.10 + 3.6.0 false true @@ -483,6 +785,33 @@ checkstyle/header + + com.mycila + license-maven-plugin + 4.6 + +
src/license/header.txt
+ false + true + false + true + true + UTF-8 + + ${currentYear} + + + **/*.xml + **/*.properties + **/*.txt + **/*.html + **/*.js + **/*.css + **/*.scss + **/*.sh + +
+
diff --git a/vaadin-cdi/src/license/header.txt b/vaadin-cdi/src/license/header.txt new file mode 100644 index 00000000..75b2b3af --- /dev/null +++ b/vaadin-cdi/src/license/header.txt @@ -0,0 +1,8 @@ +Vaadin CDI Integration + +Copyright (C) 2012-${year} Vaadin Ltd + +This program is available under Vaadin Commercial License and Service Terms. + +See for the full +license. \ No newline at end of file diff --git a/vaadin-cdi/src/license/license.txt b/vaadin-cdi/src/license/license.txt new file mode 100644 index 00000000..944a3985 --- /dev/null +++ b/vaadin-cdi/src/license/license.txt @@ -0,0 +1,3 @@ +This program is available under Vaadin Commercial License and Service Terms. +See https://vaadin.com/commercial-license-and-service-terms for the full +license. \ No newline at end of file diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/AfterViewChange.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/AfterViewChange.java new file mode 100644 index 00000000..857fb3dd --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/AfterViewChange.java @@ -0,0 +1,46 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.inject.Qualifier; + +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategy; +import com.vaadin.navigator.ViewChangeListener; + +/** + * {@code ViewChangeEvent} can be observed with this qualifier. + *

+ * Observers are called after all non-cdi + * {@link ViewChangeListener#afterViewChange(ViewChangeListener.ViewChangeEvent)} + * listeners. + *

+ * Keep in mind, context of new view is activated before event is fired. + * Accessing any {@link NormalViewScoped} bean through + * {@link ViewChangeListener.ViewChangeEvent#getOldView()} might lead to + * unexpected result, because it is looked up in the new context. + *

+ * Though, context of new view, and context of old view can be the same + * according to selected {@link ViewContextStrategy}. + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ TYPE, METHOD, PARAMETER, FIELD }) +public @interface AfterViewChange { +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDINavigator.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDINavigator.java new file mode 100644 index 00000000..e76a409a --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDINavigator.java @@ -0,0 +1,101 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.ViewContextualStorageManager; +import com.vaadin.navigator.NavigationStateManager; +import com.vaadin.navigator.Navigator; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.navigator.ViewDisplay; +import com.vaadin.ui.ComponentContainer; +import com.vaadin.ui.SingleComponentContainer; +import com.vaadin.ui.UI; + +import jakarta.enterprise.event.Event; +import jakarta.inject.Inject; + +/** + * Vaadin Navigator as a CDI Bean. + * + * Have to be initialized once with an "init(...)" method. + * During initialization a {@link CDIViewProvider} added automatically. + * + * This class is responsible for controlling {@link com.vaadin.cdi.ViewScoped} context, + * so initialization is mandatory for view scope. + */ +@NormalUIScoped +public class CDINavigator extends Navigator { + + @Inject + private ViewContextualStorageManager viewContextualStorageManager; + + @Inject + private CDIViewProvider cdiViewProvider; + + @Inject + @AfterViewChange + private Event afterViewChangeTrigger; + + /** + * {@inheritDoc} + * + * During initialization a {@link CDIViewProvider} added automatically. + */ + @Override + public void init(UI ui, NavigationStateManager stateManager, ViewDisplay display) { + super.init(ui, stateManager, display); + addProvider(cdiViewProvider); + } + + /** + * Init method like {@link Navigator#Navigator(UI, ViewDisplay)}. + * + * During initialization a {@link CDIViewProvider} added automatically. + */ + public void init(UI ui, ViewDisplay display) { + init(ui, null, display); + } + + /** + * Init method like {@link Navigator#Navigator(UI, SingleComponentContainer)}. + * + * During initialization a {@link CDIViewProvider} added automatically. + */ + public void init(UI ui, SingleComponentContainer container) { + init(ui, new SingleComponentContainerViewDisplay(container)); + } + + /** + * Init method like {@link Navigator#Navigator(UI, ComponentContainer)}. + * + * During initialization a {@link CDIViewProvider} added automatically. + */ + public void init(UI ui, ComponentContainer container) { + init(ui, new ComponentContainerViewDisplay(container)); + } + + @Override + protected boolean fireBeforeViewChange(ViewChangeEvent event) { + final boolean navigationAllowed = super.fireBeforeViewChange(event); + if (navigationAllowed) { + viewContextualStorageManager.applyChange(event); + } else { + viewContextualStorageManager.revertChange(event); + } + return navigationAllowed; + } + + @Override + protected void fireAfterViewChange(ViewChangeEvent event) { + super.fireAfterViewChange(event); + afterViewChangeTrigger.fire(event); + } +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUI.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUI.java index a500c6d6..937fcec5 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUI.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUI.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; @@ -21,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.enterprise.inject.Stereotype; +import jakarta.enterprise.inject.Stereotype; /** * All UIs need to be declared with this annotation. CDIUI annotation binds the diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUIProvider.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUIProvider.java index 43483257..84ef7eca 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUIProvider.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIUIProvider.java @@ -1,37 +1,33 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; -import java.io.Serializable; import java.lang.annotation.Annotation; +import java.util.Comparator; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; -import javax.enterprise.inject.AmbiguousResolutionException; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.util.AnnotationLiteral; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.AmbiguousResolutionException; +import jakarta.enterprise.inject.Any; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.inject.Inject; import com.vaadin.cdi.internal.AnnotationUtil; -import com.vaadin.cdi.internal.CDIUtil; import com.vaadin.cdi.internal.Conventions; -import com.vaadin.cdi.internal.UIBean; -import com.vaadin.cdi.internal.VaadinUICloseEvent; +import com.vaadin.cdi.internal.UIContextualStorageManager; +import com.vaadin.cdi.internal.VaadinSessionScopedContext; import com.vaadin.server.ClientConnector.DetachEvent; import com.vaadin.server.ClientConnector.DetachListener; import com.vaadin.server.DefaultUIProvider; @@ -39,45 +35,56 @@ import com.vaadin.server.UICreateEvent; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.UI; -import com.vaadin.util.CurrentInstance; -public class CDIUIProvider extends DefaultUIProvider implements Serializable { +@ApplicationScoped +public class CDIUIProvider extends DefaultUIProvider { + + /** + * Copied From Vaadin 8.2+. Retained since we cannot be sure that this isn't + * used in other parts of the code (yet). + *

+ * Original description reads:
+ * A request attribute name to store the part of pathInfo that was used to + * select the UI. Will be used by default Navigator to separate view + * identifiers from UI. This can be set by custom UI providers. + *

+ */ + public static final String UI_ROOT_PATH = "com.vaadin.server.UI_ROOT_PATH"; + + private static final String PATH_WILDCARD = "/*"; + + @Inject + private UIContextualStorageManager uiContextualStorageManager; + + @Inject + private BeanManager beanManager; + + private final DetachListener detachListener = new DetachListenerImpl(); private static final Annotation QUALIFIER_ANY = new AnnotationLiteral() { }; - - public static final class DetachListenerImpl implements DetachListener { - private BeanManager beanManager; - public DetachListenerImpl(BeanManager beanManager) { - this.beanManager = beanManager; - } + public final class DetachListenerImpl implements DetachListener { @Override public void detach(DetachEvent event) { Object source = event.getSource(); if (source instanceof UI) { - - UI ui = (UI) source; - beanManager.fireEvent(new VaadinUICloseEvent(CDIUtil - .getSessionId(ui.getSession()), ui.getUIId())); + int uiId = ((UI) source).getUIId(); + if (VaadinSessionScopedContext.guessContextIsUndeployed()) { + // Happens on tomcat when it expires sessions upon undeploy. + // We would get ContextNotActiveException on + // uiContextualStorageManager.destroy + getLogger().log(Level.WARNING, + "VaadinSessionScoped context does not exist. " + + "Maybe application is undeployed." + + " Can''t destroy UI context for UI {0}.", + uiId); + return; + } + uiContextualStorageManager.destroy(uiId); } - - } - } - - // TODO a better way to do this could be custom injection management in the - // Extension if feasible - private BeanManager beanManager = null; - - public BeanManager getBeanManager() { - if (beanManager == null) { - getLogger() - .fine("CDIUIProvider is not injected, using JNDI lookup"); - // as the CDIUIProvider is not injected, need to use JNDI lookup - beanManager = CDIUtil.lookupBeanManager(); } - return beanManager; } @Override @@ -87,40 +94,56 @@ public UI createInstance(UICreateEvent uiCreateEvent) { int uiId = uiCreateEvent.getUiId(); VaadinRequest request = uiCreateEvent.getRequest(); Bean bean = scanForBeans(type, request); - UIBean uiBean = new UIBean(bean, uiId); try { - // Make the UIBean available to UIScopedContext when creating nested + // Make the UI id available to UIScopedContext when creating nested // injected objects - CurrentInstance.set(UIBean.class, uiBean); - UI ui = (UI) getBeanManager().getReference(uiBean, type, - getBeanManager().createCreationalContext(bean)); - ui.addDetachListener(new DetachListenerImpl(getBeanManager())); + uiContextualStorageManager.prepareOpening(uiId); + UI ui = (UI) beanManager.getReference(bean, type, + beanManager.createCreationalContext(bean)); + ui.addDetachListener(detachListener); return ui; } finally { - CurrentInstance.set(UIBean.class, null); + uiContextualStorageManager.cleanupOpening(); } } @Override - public Class getUIClass(UIClassSelectionEvent selectionEvent) { + public Class getUIClass( + UIClassSelectionEvent selectionEvent) { VaadinRequest request = selectionEvent.getRequest(); String uiMapping = parseUIMapping(request); + + Class uiClass = null; + String pathInfo = ""; + if (isRoot(request)) { - return rootUI(); - } - Bean uiBean = getUIBeanWithMapping(uiMapping); + uiClass = rootUI(); + } else { + Bean uiBean = getUIBeanWithMapping(uiMapping); - if (uiBean != null) { - return uiBean.getBeanClass().asSubclass(UI.class); + if (uiBean != null) { + // Provide correct path info for UI for push state navigation + uiClass = uiBean.getBeanClass().asSubclass(UI.class); + pathInfo = removeWildcard( + Conventions.deriveMappingForUI(uiClass)); + } } - if (uiMapping.isEmpty()) { + if (uiClass == null && uiMapping.isEmpty()) { // See if UI is configured to web.xml with VaadinCDIServlet. This is // done only if no specific UI name is given. - return super.getUIClass(selectionEvent); + uiClass = super.getUIClass(selectionEvent); } - return null; + // Sometimes pathInfo does not contain leading slash + if (!pathInfo.isEmpty() && !pathInfo.startsWith("/")) { + pathInfo = "/" + pathInfo; + } + + request.setAttribute(UI_ROOT_PATH, + request.getContextPath() + pathInfo); + + return uiClass; } boolean isRoot(VaadinRequest request) { @@ -130,12 +153,11 @@ boolean isRoot(VaadinRequest request) { return false; } - return pathInfo.equals("/"); + return pathInfo.equals("/") || pathInfo.startsWith("/!"); } Class rootUI() { - Set> rootBeans = AnnotationUtil - .getRootUiBeans(getBeanManager()); + Set> rootBeans = AnnotationUtil.getRootUiBeans(beanManager); if (rootBeans.isEmpty()) { return null; } @@ -154,30 +176,47 @@ Class rootUI() { return rootUI.asSubclass(UI.class); } - private Bean getUIBeanWithMapping(String mapping) { - Set> beans = AnnotationUtil.getUiBeans(getBeanManager()); - - for (Bean bean : beans) { - // We need this check since the returned beans can also be producers - if (UI.class.isAssignableFrom(bean.getBeanClass())) { - Class beanClass = bean.getBeanClass().asSubclass( - UI.class); - - if (beanClass.isAnnotationPresent(CDIUI.class)) { - String computedMapping = Conventions - .deriveMappingForUI(beanClass); - if (mapping.equals(computedMapping)) { - return bean; - } - } - } + Bean getUIBeanWithMapping(String mapping) { + Set> beans = AnnotationUtil.getUiBeans(beanManager); + + return beans.stream() + .filter(bean -> UI.class.isAssignableFrom(bean.getBeanClass())) + .filter(bean -> { + Class beanClass = bean.getBeanClass() + .asSubclass(UI.class); + return beanClass.isAnnotationPresent(CDIUI.class) + && isMatchingPath(mapping, beanClass); + }).sorted(Comparator.comparing(bean -> { + Class beanClass = ((Bean) bean).getBeanClass(); + String path = Conventions.deriveMappingForUI(beanClass); + return removeWildcard(path).length(); + }).reversed()).findFirst().orElse(null); + } + + private boolean isMatchingPath(String mapping, + Class beanClass) { + String path = Conventions.deriveMappingForUI(beanClass); + + boolean isWildcardPath = path.endsWith(PATH_WILDCARD);; + + path = removeWildcard(path); + + boolean exactMatch = mapping.equals(path); + if (!exactMatch && isWildcardPath) { + return path.isEmpty() || mapping.startsWith(path + "/"); } + return exactMatch; + } - return null; + private String removeWildcard(String path) { + if (path.endsWith(PATH_WILDCARD)) { + return path.substring(0, path.length() - PATH_WILDCARD.length()); + } + return path; } - private Bean scanForBeans(Class type, VaadinRequest request) { - BeanManager beanManager = getBeanManager(); + private Bean scanForBeans(Class type, + VaadinRequest request) { Bean bean = null; Set> beans = beanManager.getBeans(type, QUALIFIER_ANY); @@ -199,9 +238,9 @@ private Bean scanForBeans(Class type, VaadinRequest request) { uiMapping = parseUIMapping(request); bean = getUIBeanWithMapping(uiMapping); } else { - throw new IllegalStateException("UI class: " + type.getName() - + " with mapping: " + uiMapping - + " is not annotated with CDIUI!"); + throw new IllegalStateException( + "UI class: " + type.getName() + " with mapping: " + + uiMapping + " is not annotated with CDIUI!"); } } return bean; @@ -218,21 +257,21 @@ String parseUIMapping(String requestPath) { path = requestPath.substring(0, requestPath.length() - 1); } if (!path.contains("!")) { - int lastIndex = path.lastIndexOf('/'); - return path.substring(lastIndex + 1); + return path.substring(path.startsWith("/") ? 1 : 0); } else { int lastIndexOfBang = path.lastIndexOf('!'); - // strip slash with bank => /! - String pathWithoutView = path.substring(0, lastIndexOfBang - 1); - int lastSlashIndex = pathWithoutView.lastIndexOf('/'); - return pathWithoutView.substring(lastSlashIndex + 1); + String pathWithoutView = path.substring(0, lastIndexOfBang); + if (pathWithoutView.endsWith("/")) { + pathWithoutView = pathWithoutView.substring(0, + pathWithoutView.length() - 1); + } + return pathWithoutView + .substring(pathWithoutView.startsWith("/") ? 1 : 0); } } return ""; } - - private static Logger getLogger() { return Logger.getLogger(CDIUIProvider.class.getCanonicalName()); } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIView.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIView.java index cc4f8126..3ea517d0 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIView.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIView.java @@ -1,42 +1,42 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategyQualifier; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNameAndParameters; +import com.vaadin.navigator.View; +import com.vaadin.ui.UI; + +import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.enterprise.inject.Stereotype; - -import com.vaadin.navigator.Navigator; -import com.vaadin.navigator.View; -import com.vaadin.ui.UI; - /** * Classes implementing {@link View} and annotated with @CDIView * are automatically registered with {@link CDIViewProvider} for use by - * {@link Navigator}. + * {@link CDINavigator}. *

* By default, the view name is derived from the class name of the annotated - * class, but this can also be overriden by defining a {@link #value()}. + * class, but this can also be overridden by defining a {@link #value()}. *

* @CDIView views are by default {@link ViewScoped}. - * - * @see javax.inject.Named + *

+ * On a @CDIView view the strategy for the view context + * can be defined by annotating the view with a + * {@link ViewContextStrategyQualifier} annotation. + * By default it is {@link ViewContextByNameAndParameters}. + * + * @see jakarta.inject.Named */ @Stereotype @Retention(RetentionPolicy.RUNTIME) @@ -45,7 +45,7 @@ public @interface CDIView { /** - * + * * The name of the CDIView can be derived from the simple class name So it * is optional. Also multiple views without a value may exist at the same * time. @@ -61,15 +61,6 @@ */ public static final String USE_CONVENTIONS = "USE CONVENTIONS"; - /** - * Specifies whether view parameters can be passed to the view as part of - * the name, i.e in the form of {@code viewName/viewParameters}. Make sure - * there are no other views that start with the same name, since the - * ViewProvider will only check that the given {@code viewAndParameters} - * starts with the view name. - */ - public boolean supportsParameters() default false; - /** * Specifies which UIs can show the view. {@link CDIViewProvider} only lists * the views that have the current UI on this list. @@ -78,8 +69,9 @@ *

* This only needs to be specified if the application has multiple UIs that * use {@link CDIViewProvider}. - * + * * @return list of UIs in which the view can be shown. */ public Class[] uis() default { UI.class }; + } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIViewProvider.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIViewProvider.java index 0954a89f..d2ac2813 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIViewProvider.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/CDIViewProvider.java @@ -1,21 +1,30 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; +import com.vaadin.cdi.access.AccessControl; +import com.vaadin.cdi.internal.AnnotationUtil; +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.internal.ViewContextualStorageManager; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewProvider; +import com.vaadin.ui.UI; + +import jakarta.annotation.security.DenyAll; +import jakarta.annotation.security.RolesAllowed; +import jakarta.enterprise.inject.Any; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.util.AnnotationLiteral; +import jakarta.inject.Inject; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; @@ -24,32 +33,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.annotation.security.DenyAll; -import javax.annotation.security.RolesAllowed; -import javax.enterprise.context.Dependent; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.util.AnnotationLiteral; -import javax.inject.Inject; - -import com.vaadin.cdi.access.AccessControl; -import com.vaadin.cdi.internal.AnnotationUtil; -import com.vaadin.cdi.internal.CDIUtil; -import com.vaadin.cdi.internal.Conventions; -import com.vaadin.cdi.internal.VaadinViewChangeCleanupEvent; -import com.vaadin.cdi.internal.VaadinViewChangeEvent; -import com.vaadin.cdi.internal.VaadinViewCreationEvent; -import com.vaadin.cdi.internal.ViewBean; -import com.vaadin.navigator.Navigator; -import com.vaadin.navigator.View; -import com.vaadin.navigator.ViewChangeListener; -import com.vaadin.navigator.ViewProvider; -import com.vaadin.ui.UI; - public class CDIViewProvider implements ViewProvider { private static final Annotation QUALIFIER_ANY = new AnnotationLiteral() { @@ -58,82 +41,44 @@ public class CDIViewProvider implements ViewProvider { @Inject private BeanManager beanManager; - private static ThreadLocal cleanupEvent = new ThreadLocal(); - @Inject private AccessControl accessControl; - private transient CreationalContext dependentViewCreationalContext; - - public final static class ViewChangeListenerImpl - implements ViewChangeListener { - - private BeanManager beanManager; - public ViewChangeListenerImpl(BeanManager beanManager) { - this.beanManager = beanManager; - } - - @Override - public boolean beforeViewChange(ViewChangeEvent event) { - return true; - } - - @Override - public void afterViewChange(ViewChangeEvent event) { - getLogger().fine("Changing view from " + event.getOldView() + " to " - + event.getNewView()); - // current session id - long sessionId = CDIUtil.getSessionId(); - int uiId = event.getNavigator().getUI().getUIId(); - String viewName = event.getViewName(); - beanManager.fireEvent( - new VaadinViewChangeEvent(sessionId, uiId, viewName)); - } - } - - private ViewChangeListener viewChangeListener; + @Inject + private ViewContextualStorageManager viewContextualStorageManager; - @PostConstruct - private void postConstruct() { - viewChangeListener = new ViewChangeListenerImpl(beanManager); - } + private String lastViewAndParameters; @Override - public String getViewName(String viewAndParameters) { + public String getViewName(final String viewAndParameters) { getLogger().log(Level.FINE, "Attempting to retrieve view name from string \"{0}\"", viewAndParameters); + lastViewAndParameters = viewAndParameters; String name = parseViewName(viewAndParameters); - ViewBean viewBean = getViewBean(name); + Bean viewBean = getViewBean(name); if (viewBean == null) { return null; } if (isUserHavingAccessToView(viewBean)) { - if (viewBean.getBeanClass().isAnnotationPresent(CDIView.class)) { - String specifiedViewName = Conventions - .deriveMappingForView(viewBean.getBeanClass()); - if (!specifiedViewName.isEmpty()) { - return specifiedViewName; - } - } return name; } else { getLogger().log(Level.INFO, "User {0} did not have access to view \"{1}\"", - new Object[] { accessControl.getPrincipalName(), - viewBean }); + new Object[] { accessControl.getPrincipalName(), viewBean }); } return null; } - protected boolean isUserHavingAccessToView(Bean viewBean) { + protected boolean isUserHavingAccessToView(final Bean viewBean) { if (viewBean.getBeanClass().isAnnotationPresent(CDIView.class)) { - if (viewBean.getBeanClass().isAnnotationPresent(DenyAll.class)) { + if (viewBean.getBeanClass() + .isAnnotationPresent(DenyAll.class)) { // DenyAll defined, everyone is denied access return false; } @@ -147,7 +92,8 @@ protected boolean isUserHavingAccessToView(Bean viewBean) { .getAnnotation(RolesAllowed.class); boolean hasAccess = accessControl .isUserInSomeRole(rolesAnnotation.value()); - getLogger().log(Level.FINE, + getLogger().log( + Level.FINE, "Checking if user {0} is having access to {1}: {2}", new Object[] { accessControl.getPrincipalName(), viewBean, Boolean.toString(hasAccess) }); @@ -160,28 +106,21 @@ protected boolean isUserHavingAccessToView(Bean viewBean) { return true; } - /** - * Returns a {@code ViewBean} for given view name. - * - * @param viewName - * the name of the view - * @return the view bean - * - * @since 1.0.4 - */ - protected ViewBean getViewBean(String viewName) { + private Bean getViewBean(String viewName) { getLogger().log(Level.FINE, "Looking for view with name \"{0}\"", viewName); if (viewName == null) { return null; + } else if (viewName.startsWith("!")) { + viewName = viewName.substring(1); } - Set> matching = new HashSet>(); + Set> matching = new HashSet<>(); Set> all = beanManager.getBeans(View.class, QUALIFIER_ANY); if (all.isEmpty()) { - getLogger().severe( - "No Views found! Please add at least one class implementing the View interface."); + getLogger() + .severe("No Views found! Please add at least one class implementing the View interface."); return null; } for (Bean bean : all) { @@ -206,11 +145,10 @@ protected ViewBean getViewBean(String viewName) { } } - Set> viewBeansForThisProvider = getViewBeansForCurrentUI( - matching); + Set> viewBeansForThisProvider = getViewBeansForCurrentUI(matching); if (viewBeansForThisProvider.isEmpty()) { - getLogger().log(Level.WARNING, - "No view beans found for current UI"); + getLogger() + .log(Level.WARNING, "No view beans found for current UI"); return null; } @@ -219,23 +157,22 @@ protected ViewBean getViewBean(String viewName) { "Multiple views mapped with same name for same UI"); } - return new ViewBean(viewBeansForThisProvider.iterator().next(), - viewName); + return viewBeansForThisProvider.iterator().next(); } - private Set> getViewBeansForCurrentUI(Set> beans) { - Set> viewBeans = new HashSet>(); + private Set> getViewBeansForCurrentUI(final Set> beans) { + Set> viewBeans = new HashSet<>(); for (Bean bean : beans) { - CDIView viewAnnotation = bean.getBeanClass() - .getAnnotation(CDIView.class); + CDIView viewAnnotation = bean.getBeanClass().getAnnotation( + CDIView.class); if (viewAnnotation == null) { continue; } - List> uiClasses = Arrays - .asList(viewAnnotation.uis()); + List> uiClasses = Arrays.asList(viewAnnotation + .uis()); if (uiClasses.contains(UI.class)) { viewBeans.add(bean); @@ -254,12 +191,11 @@ private Set> getViewBeansForCurrentUI(Set> beans) { } @Override - public View getView(String viewName) { + public View getView(final String viewName) { getLogger().log(Level.FINE, - "Attempting to retrieve view with name \"{0}\"", viewName); + "Attempting to retrieve view with name \"{0}\"", + viewName); - // current session and UI - long sessionId = CDIUtil.getSessionId(); UI currentUI = UI.getCurrent(); if (currentUI == null) { @@ -269,85 +205,55 @@ public View getView(String viewName) { + " - current UI is not set"); } - ViewBean viewBean = getViewBean(viewName); + Bean viewBean = getViewBean(viewName); if (viewBean != null) { if (!isUserHavingAccessToView(viewBean)) { - getLogger().log(Level.INFO, + getLogger().log( + Level.INFO, "User {0} did not have access to view {1}", new Object[] { accessControl.getPrincipalName(), viewBean }); return null; } - if (dependentViewCreationalContext != null) { - getLogger().log(Level.FINER, - "Releasing creational context for current view {0}", - dependentViewCreationalContext); - dependentViewCreationalContext.release(); - dependentViewCreationalContext = null; - } - - CreationalContext creationalContext = beanManager - .createCreationalContext(viewBean); - getLogger().log(Level.FINER, - "Created new creational context for current view {0}", - creationalContext); - - beanManager.fireEvent(new VaadinViewCreationEvent(sessionId, - currentUI.getUIId(), viewName)); - cleanupEvent.set(new VaadinViewChangeCleanupEvent(sessionId, - currentUI.getUIId())); - - View view = (View) beanManager.getReference(viewBean, - viewBean.getBeanClass(), creationalContext); - getLogger().log(Level.FINE, "Returning view instance {0}", - view.toString()); + final String parameters = getParameters(viewName); + View view = viewContextualStorageManager.prepareChange(viewBean, viewName, parameters); - if (Dependent.class.isAssignableFrom(viewBean.getScope())) { - dependentViewCreationalContext = creationalContext; - } + getLogger().log(Level.FINE, "Returning view instance {0}", view.toString()); - Navigator navigator = currentUI.getNavigator(); - if (navigator != null) { - // This is a fairly dumb way of making sure that there is - // one and only one CDI viewChangeListener for this - // Navigator. - navigator.removeViewChangeListener(viewChangeListener); - navigator.addViewChangeListener(viewChangeListener); - } return view; } throw new RuntimeException("Unable to instantiate view"); } - @PreDestroy - protected void destroy() { - if (dependentViewCreationalContext != null) { - getLogger().log(Level.FINE, - "CDIViewProvider is being destroyed, releasing creational context for dependent view"); - dependentViewCreationalContext.release(); + private String getParameters(String viewName) { + if (!lastViewAndParameters.startsWith(viewName)) { + throw new IllegalStateException("Last known viewstate should start with view name"); + } + int paramsOffset = viewName.length(); + if (lastViewAndParameters.length() > paramsOffset) { + paramsOffset ++; } + return lastViewAndParameters.substring(paramsOffset); } - /** - * Extract the view name part from the full fragment string. - * - * @param viewAndParameters - * the view name and parameters - * @return the view name - * - * @since 1.0.4 - */ - protected String parseViewName(String viewAndParameters) { - + private String parseViewName(String viewAndParameters) { String viewName = viewAndParameters; - if (viewName.startsWith("!")) { + if (viewAndParameters.startsWith("!")) { viewName = viewName.substring(1); } for (String name : AnnotationUtil.getCDIViewMappings(beanManager)) { if (viewName.equals(name) || (viewName.startsWith(name + "/"))) { + if (viewAndParameters.startsWith("!")) { + // when viewAndParameters starts with two or more ! + // we want to find a view which starts with an ! + // but parseViewName(String) removed the leading ! + // so when getViewBean(String) also removes the leading ! + // it would be looking for the wrong view since its missing a ! + return "!".concat(name); + } return name; } } @@ -355,14 +261,6 @@ protected String parseViewName(String viewAndParameters) { return null; } - public static VaadinViewChangeCleanupEvent getCleanupEvent() { - return cleanupEvent.get(); - } - - public static void removeCleanupEvent() { - cleanupEvent.remove(); - } - private static Logger getLogger() { return Logger.getLogger(CDIViewProvider.class.getCanonicalName()); } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalUIScoped.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalUIScoped.java index e71bc489..32be1016 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalUIScoped.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalUIScoped.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; @@ -21,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.enterprise.context.NormalScope; +import jakarta.enterprise.context.NormalScope; /** * The lifecycle of a UIScoped component is bound to a browser tab. diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalViewScoped.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalViewScoped.java index 4cf645b7..79252515 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalViewScoped.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/NormalViewScoped.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; @@ -21,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.enterprise.context.NormalScope; +import jakarta.enterprise.context.NormalScope; /** * The lifecycle of a ViewScoped component starts when the view is navigated to diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/UIScoped.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/UIScoped.java index 6cb19280..256fcef3 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/UIScoped.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/UIScoped.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; @@ -21,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Scope; +import jakarta.inject.Scope; /** * The lifecycle of a UIScoped component is bound to a browser tab. diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/URLMapping.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/URLMapping.java index 2c1c6fac..8ac78d1b 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/URLMapping.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/URLMapping.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/VaadinSessionScoped.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/VaadinSessionScoped.java new file mode 100644 index 00000000..10d57305 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/VaadinSessionScoped.java @@ -0,0 +1,34 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import jakarta.enterprise.context.NormalScope; +import java.lang.annotation.*; + +/** + * The lifecycle of a VaadinSessionScoped bean is bound to a VaadinSession. + *

+ * Injecting with this annotation will create a proxy for the contextual + * instance rather than provide the contextual instance itself. + *

+ *

+ * Contextual instances stored in VaadinSession, so indirectly stored in HTTP session. + * {@link jakarta.annotation.PreDestroy} called after SessionDestroyEvent fired. + *

+ * + * @since 3.0 + */ +@NormalScope +@Inherited +@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR }) +@Retention(RetentionPolicy.RUNTIME) +public @interface VaadinSessionScoped { +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/ViewScoped.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/ViewScoped.java index 76cfa39a..43d43414 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/ViewScoped.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/ViewScoped.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi; @@ -21,7 +16,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import javax.inject.Scope; +import jakarta.inject.Scope; /** * The lifecycle of a ViewScoped component starts when the view is navigated to diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/access/AccessControl.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/access/AccessControl.java index 3841b044..a831dcd9 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/access/AccessControl.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/access/AccessControl.java @@ -1,21 +1,16 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.access; -import javax.enterprise.inject.Alternative; +import jakarta.enterprise.inject.Alternative; /** * Access control base class. diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/access/JaasAccessControl.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/access/JaasAccessControl.java index 9d870776..494e4a4a 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/access/JaasAccessControl.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/access/JaasAccessControl.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.access; @@ -19,10 +14,10 @@ import java.security.Principal; import java.util.logging.Logger; -import javax.enterprise.context.RequestScoped; -import javax.enterprise.inject.Default; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; +import jakarta.enterprise.context.RequestScoped; +import jakarta.enterprise.inject.Default; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; import com.vaadin.server.VaadinServletService; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AbstractVaadinContext.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AbstractVaadinContext.java deleted file mode 100644 index 35ddee7d..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AbstractVaadinContext.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; -import java.util.SortedMap; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Logger; - -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.BeanManager; - -import org.apache.deltaspike.core.util.context.AbstractContext; -import org.apache.deltaspike.core.util.context.ContextualStorage; - -import com.vaadin.cdi.internal.AbstractVaadinContext.SessionData.UIData; -import com.vaadin.cdi.internal.CDIUtil; -import com.vaadin.cdi.internal.UIContextual; -import com.vaadin.cdi.internal.VaadinSessionDestroyEvent; -import com.vaadin.cdi.internal.VaadinUICloseEvent; -import com.vaadin.server.VaadinSession; - -/** - * UIScopedContext is the context for @UIScoped beans. - */ -public abstract class AbstractVaadinContext extends AbstractContext { - - private TreeMap uiCloseQueue = new TreeMap(); - - private final Object cleanupLock = new Object(); - - public static final int CLEANUP_DELAY = 5000; - - private BeanManager beanManager; - private Map storageMap = new ConcurrentHashMap(); - - public static class SessionData { - - public static class UIData { - - private int uiId; - - private String activeView = null; - private String openingView = null; - - public UIData(int uiId) { - this.uiId = uiId; - } - - private int getUiId() { - return uiId; - } - - public String getActiveView() { - return activeView; - } - - public String getOpeningView() { - return openingView; - } - - public String getProbableInjectionPointView() { - if (openingView != null) { - return openingView; - } - if (activeView != null) { - return activeView; - } - throw new IllegalStateException( - "Can't find proper view for @ViewScoped bean, no views are active for this ui."); - } - - public void setOpeningView(String openingView) { - this.openingView = openingView; - } - - public void validateTransition() { - if (openingView != null) { - activeView = openingView; - openingView = null; - } - } - - public void clearPendingViewChange() { - openingView = null; - } - - } - - private Map, ContextualStorage> storageMap = new ConcurrentHashMap, ContextualStorage>(); - - private Map uiDataMap = new ConcurrentHashMap(); - - public SessionData() { - } - - public UIData getUIData(int uiId) { - return getUIData(uiId, false); - } - - public UIData getUIData(int uiId, boolean createIfNotExist) { - if (uiDataMap.containsKey(uiId)) { - return uiDataMap.get(uiId); - } else if (createIfNotExist) { - UIData data = new UIData(uiId); - uiDataMap.put(uiId, data); - return data; - } else { - return null; - } - } - - private Map getUiDataMap() { - return uiDataMap; - } - - public Map, ContextualStorage> getStorageMap() { - return storageMap; - } - - } - - public AbstractVaadinContext(final BeanManager beanManager) { - super(beanManager); - this.beanManager = beanManager; - } - - @Override - public boolean isActive() { - return true; - } - - @Override - public T get(Contextual bean) { - return super.get(wrapBean(bean)); - } - - @Override - public T get(Contextual bean, - CreationalContext creationalContext) { - return super.get(wrapBean(bean), creationalContext); - } - - protected Contextual wrapBean(Contextual bean) { - return bean; - } - - protected synchronized SessionData getSessionData(VaadinSession session, - boolean createIfNotExist) { - if (session == null) { - return null; - } - long sessionId = CDIUtil.getSessionId(session); - return getSessionData(sessionId, createIfNotExist); - } - - protected synchronized SessionData getSessionData( - boolean createIfNotExist) { - return getSessionData(VaadinSession.getCurrent(), createIfNotExist); - } - - protected synchronized SessionData getSessionData(long sessionId, - boolean createIfNotExist) { - if (storageMap.containsKey(sessionId)) { - return storageMap.get(sessionId); - } else { - if (createIfNotExist) { - SessionData data = new SessionData(); - storageMap.put(sessionId, data); - return data; - } else { - return null; - } - } - } - - void dropSessionData(VaadinSessionDestroyEvent event) { - long sessionId = event.getSessionId(); - getLogger().fine("Dropping session data for session: " + sessionId); - - SessionData sessionData = storageMap.remove(sessionId); - if (sessionData != null) { - synchronized (sessionData) { - Collection storages = sessionData.storageMap - .values(); - for (ContextualStorage storage : storages) { - destroyAllActive(storage); - } - } - } - } - - private synchronized void dropUIData(SessionData sessionData, int uiId) { - getLogger().fine("Dropping UI data for UI: " + uiId); - - Map, ContextualStorage> storageMap = sessionData - .getStorageMap(); - for (Contextual contextual : new ArrayList>( - storageMap.keySet())) { - if (contextual instanceof UIContextual - && ((UIContextual) contextual).getUiId() == uiId) { - final ContextualStorage storage = storageMap.remove(contextual); - destroyAllActive(storage); - } - } - sessionData.uiDataMap.remove(uiId); - } - - void queueUICloseEvent(VaadinUICloseEvent event) { - synchronized (cleanupLock) { - // We introduce a cleanup delay because the UI gets referred to - // later in the core cleanup process. If the UI is proxied this will - // cause a new UI to be initialized in some CDI implementations (for - // example Apache OpenWebBeans 1.2.1) - long closeTime = System.currentTimeMillis() + CLEANUP_DELAY; - while (uiCloseQueue.get(closeTime) != null) { - closeTime++; - } - uiCloseQueue.put(closeTime, event); - } - } - - void uiCloseCleanup() { - // Remove the UI's that have been previously queued for closing. We need - // to protect the UI context from deletion long enough that the core - // framework has time to do it's own cleanup. - // We run the cleanup process from VaadinCDIServletService after the - // results of the latest query have been sent. We do it this way to - // avoid using a background thread and to maintain cross-implementation - // compatibility. - Collection> entries = null; - synchronized (cleanupLock) { - long currentTime = System.currentTimeMillis(); - SortedMap subMap = uiCloseQueue - .headMap(currentTime); - entries = new ArrayList>( - subMap.entrySet()); - // Remove the entries from the underlying uiCloseQueue - subMap.clear(); - } - if (entries != null && !entries.isEmpty()) { - for (Entry entry : entries) { - VaadinUICloseEvent event = entry.getValue(); - SessionData sessionData = getSessionData(event.getSessionId(), - false); - if (sessionData != null) { - dropUIData(sessionData, event.getUiId()); - } - } - } - - } - - protected abstract Logger getLogger(); - - public BeanManager getBeanManager() { - return beanManager; - } -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AnnotationUtil.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AnnotationUtil.java index a6f820f2..1fb569fe 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AnnotationUtil.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/AnnotationUtil.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.internal; @@ -22,10 +17,10 @@ import java.util.List; import java.util.Set; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.util.AnnotationLiteral; +import jakarta.enterprise.inject.Any; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.util.AnnotationLiteral; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/CDIUtil.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/CDIUtil.java deleted file mode 100644 index fbea1511..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/CDIUtil.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.vaadin.cdi.internal; - -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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. - */ -import java.util.UUID; -import java.util.logging.Logger; - -import javax.enterprise.inject.spi.BeanManager; -import javax.naming.InitialContext; -import javax.naming.NamingException; - -import com.vaadin.server.VaadinSession; - -public class CDIUtil { - - private static final String[] commonBeanManagerLookups = { - "java:comp/BeanManager", "java:comp/env/BeanManager" }; - - public static BeanManager lookupBeanManager() { - BeanManager beanManager = null; - try { - InitialContext initialContext = new InitialContext(); - for (String beanManagerLookup : commonBeanManagerLookups) { - try { - beanManager = (BeanManager) initialContext - .lookup(beanManagerLookup); - getLogger().fine( - "BeanManager found by '" + beanManagerLookup + "'"); - break; - } catch (NamingException e) { - getLogger().fine( - "BeanManager was not found by '" - + beanManagerLookup + "'"); - } - } - } catch (NamingException e) { - getLogger().warning("Could not instantiate InitialContext"); - } - if (beanManager == null) { - getLogger().severe("Could not get BeanManager through JNDI"); - } - return beanManager; - } - - public static long getSessionId() { - return getSessionId(VaadinSession.getCurrent()); - } - - public static long getSessionId(VaadinSession session) { - - Long id = (Long) session.getAttribute("cdi-session-id"); - if (id == null) { - id = UUID.randomUUID().getLeastSignificantBits(); - session.setAttribute("cdi-session-id", id); - } - return id; - } - - private static Logger getLogger() { - return Logger.getLogger(CDIUtil.class.getCanonicalName()); - } -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextDeployer.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextDeployer.java index 9c647663..e9cb3016 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextDeployer.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextDeployer.java @@ -1,33 +1,27 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.internal; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.inject.Inject; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.ServletRegistration; -import javax.servlet.annotation.WebListener; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.inject.Inject; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletContextEvent; +import jakarta.servlet.ServletContextListener; +import jakarta.servlet.ServletRegistration; +import jakarta.servlet.annotation.WebListener; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.URLMapping; @@ -73,7 +67,7 @@ public void contextInitialized(ServletContextEvent sce) { getLogger().info("Done deploying Vaadin UIs"); } - private Class getVaadinServletDefinedInDeploymentDescriptor( + private Class getVaadinServletDefinedInDeploymentDescriptor( ServletContext context) { for (ServletRegistration servletRegistration : context .getServletRegistrations().values()) { @@ -83,7 +77,6 @@ private Class getVaadinServletDefinedInDeploymentDescriptor( // These should not prevent registration of the VaadinCDIServlet. if (null != servletClassName) { try { - Class servletClass = context.getClassLoader().loadClass( servletClassName); @@ -94,7 +87,7 @@ private Class getVaadinServletDefinedInDeploymentDescriptor( } } catch (ClassNotFoundException e) { - getLogger().warning(String.format("Could not load %s.", servletClassName)); + getLogger().warning(String.format("Coud not load %s.", servletClassName)); } } } @@ -225,13 +218,13 @@ Set> dropBeansWithOutVaadinUIAnnotation(Set> uiBeans) { * @param context */ private void deployVaadinServlet(ServletContext context) { - Class vaadinServletClass = getVaadinServletDefinedInDeploymentDescriptor(context); + Class vaadinServletClass = getVaadinServletDefinedInDeploymentDescriptor(context); if (vaadinServletClass != null) { getLogger() .warning( "Vaadin related servlet is defined in deployment descriptor, " + "automated deployment of VaadinCDIServlet is now disabled"); - Class enclosingClass = vaadinServletClass.getEnclosingClass(); + Class enclosingClass = vaadinServletClass.getEnclosingClass(); if (!VaadinCDIServlet.class.isAssignableFrom(vaadinServletClass) && enclosingClass != null && enclosingClass.isAnnotationPresent(CDIUI.class)) { diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextWrapper.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextWrapper.java index 812c2f49..a7900e21 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextWrapper.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ContextWrapper.java @@ -1,26 +1,22 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.internal; +import org.apache.deltaspike.core.util.context.AbstractContext; + import java.lang.annotation.Annotation; -import javax.enterprise.context.spi.Context; -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.context.spi.CreationalContext; +import jakarta.enterprise.context.spi.AlterableContext; +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.context.spi.CreationalContext; /** * Used to bind multiple scope annotations to a single context. Will delegate @@ -28,12 +24,12 @@ * getting the scope of the context. * */ -public class ContextWrapper implements Context { +public class ContextWrapper implements AlterableContext { - private final Context context; + private final AbstractContext context; private final Class scope; - public ContextWrapper(Context context, Class scope) { + public ContextWrapper(AbstractContext context, Class scope) { this.context = context; this.scope = scope; } @@ -59,4 +55,8 @@ public boolean isActive() { return context.isActive(); } + @Override + public void destroy(Contextual contextual) { + context.destroy(contextual); + } } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/Conventions.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/Conventions.java index c305969e..1afd1e9f 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/Conventions.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/Conventions.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.internal; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/InconsistentDeploymentException.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/InconsistentDeploymentException.java index 5d29f06c..b462425a 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/InconsistentDeploymentException.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/InconsistentDeploymentException.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.internal; @@ -30,7 +25,14 @@ public class InconsistentDeploymentException extends RuntimeException { enum ID { - MULTIPLE_ROOTS, PATH_COLLISION, CLASS_NOT_FOUND, EMBEDDED_SERVLET, CDIVIEW_WITHOUT_VIEW + MULTIPLE_ROOTS, + PATH_COLLISION, + CLASS_NOT_FOUND, + EMBEDDED_SERVLET, + CDIVIEW_WITHOUT_VIEW, + CDIVIEW_DEPENDENT, + CDIUI_SCOPE, + CDIUI_WITHOUT_UI } private ID id; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIBean.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIBean.java deleted file mode 100644 index d95610a0..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIBean.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Set; - -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.InjectionPoint; -import javax.enterprise.inject.spi.PassivationCapable; - -import com.vaadin.ui.UI; - -public class UIBean extends UIContextual implements Bean, PassivationCapable { - - - public UIBean(Bean delegate, long sessionId, int uiId) { - super(delegate, sessionId, uiId); - } - - public UIBean(Bean delegate, int uiId) { - this(delegate, CDIUtil.getSessionId(), uiId); - } - - public UIBean(Bean delegate) { - this(delegate, UI.getCurrent().getUIId()); - } - - private Bean getDelegate() { - return (Bean) delegate; - } - - @Override - public Set getTypes() { - return getDelegate().getTypes(); - } - - @Override - public Set getQualifiers() { - return getDelegate().getQualifiers(); - } - - @Override - public Class getScope() { - return getDelegate().getScope(); - } - - @Override - public String getName() { - return getDelegate().getName(); - } - - @Override - public Set> getStereotypes() { - return getDelegate().getStereotypes(); - } - - @Override - public Class getBeanClass() { - return getDelegate().getBeanClass(); - } - - @Override - public boolean isAlternative() { - return getDelegate().isAlternative(); - } - - @Override - public boolean isNullable() { - return getDelegate().isNullable(); - } - - @Override - public Set getInjectionPoints() { - return getDelegate().getInjectionPoints(); - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (!(o instanceof UIBean)) - return false; - - return super.equals(o); - } - - @Override - public String getId() { - StringBuilder sb = new StringBuilder("com.vaadin.cdi.internal.UIBean#"); - sb.append(sessionId); - sb.append("#"); - sb.append(uiId); - if (delegate instanceof PassivationCapable) { - String delegatePassivationID = ((PassivationCapable) delegate) - .getId(); - if (delegatePassivationID != null - && !delegatePassivationID.isEmpty()) { - sb.append("#"); - sb.append(delegatePassivationID); - } else { - sb.append("#null#"); - sb.append(getBeanClass().getCanonicalName()); - } - } else { - // Even if the bean itself is not passivation capable, we're still - // using UIBean.getid() as a key in ContextualStorage. It may mix up - // beans in some cases, specifically if we're injecting - // non-passivation-capable beans as @UIScoped - sb.append("#"); - sb.append(getBeanClass().getCanonicalName()); - } - return sb.toString(); - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextual.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextual.java deleted file mode 100644 index 4a4f53e9..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextual.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; - -import com.vaadin.ui.UI; - -/** - * Instances of this class are used as an identifier for determining - * the correct ContextualStorage in UIScopedContext - * - * - */ -public class UIContextual implements Contextual { - - protected Contextual delegate; - protected int uiId; - protected long sessionId; - - public UIContextual(Contextual delegate, long sessionId, int uiId) { - this.delegate = delegate; - this.uiId = uiId; - this.sessionId = sessionId; - } - - public UIContextual(Contextual delegate, long sessionId) { - this(delegate, sessionId, UI.getCurrent().getUIId()); - } - - public UIContextual(Contextual delegate) { - this(delegate, CDIUtil.getSessionId()); - } - - public int getUiId() { - return uiId; - } - - public long getSessionId() { - return sessionId; - } - - @Override - public boolean equals(Object o) { - if(!(o instanceof UIContextual)) { - return false; - } - - UIContextual uiContextual = (UIContextual) o; - - if (uiId != uiContextual.uiId) - return false; - if (sessionId != uiContextual.sessionId) - return false; - - return true; - - } - - @Override - public int hashCode() { - int result = (int) sessionId; - result = 31 * result + uiId; - return result; - } - - @Override - public Object create(CreationalContext context) { - return delegate.create(context); - } - - @Override - public void destroy(Object instance, CreationalContext context) { - delegate.destroy(instance, context); - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextualStorageManager.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextualStorageManager.java new file mode 100644 index 00000000..9f17b464 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIContextualStorageManager.java @@ -0,0 +1,91 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.cdi.VaadinSessionScoped; +import com.vaadin.ui.UI; +import org.apache.deltaspike.core.util.context.AbstractContext; +import org.apache.deltaspike.core.util.context.ContextualStorage; + +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.inject.Inject; +import java.io.Serializable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Manage and store ContextualStorage for UI context. + * + * This class is responsible for + * - selecting the active UI context + * - creating, and providing the ContextualStorage for it + * - destroying contextual instances + * + * Concurrency handling ignored intentionally. + * Locking of VaadinSession is the responsibility of Vaadin Framework. + * + * @since 3.0 + */ +@VaadinSessionScoped +public class UIContextualStorageManager implements Serializable { + + @Inject + private BeanManager beanManager; + private final Map storageMap = new HashMap<>(); + private transient Integer openingUiId; + + public ContextualStorage getContextualStorage(boolean createIfNotExist) { + Integer uiId; + if (openingUiId != null) { + uiId = openingUiId; + } else { + uiId = UI.getCurrent().getUIId(); + } + + ContextualStorage storage = storageMap.get(uiId); + if (storage == null && createIfNotExist) { + storage = new VaadinContextualStorage(beanManager); + storageMap.put(uiId, storage); + } + + return storage; + } + + public void prepareOpening(int uiId) { + openingUiId = uiId; + } + + public void cleanupOpening() { + openingUiId = null; + } + + public boolean isActive() { + return UI.getCurrent() != null || openingUiId != null; + } + + @PreDestroy + private void destroyAll() { + Collection storages = storageMap.values(); + for (ContextualStorage storage : storages) { + AbstractContext.destroyAllActive(storage); + } + storageMap.clear(); + } + + public void destroy(int uiId) { + ContextualStorage storage = storageMap.remove(uiId); + if (storage != null) { + AbstractContext.destroyAllActive(storage); + } + } +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIScopedContext.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIScopedContext.java index 4ba2af4f..e9f2a536 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIScopedContext.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/UIScopedContext.java @@ -1,111 +1,56 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.internal; -import java.lang.annotation.Annotation; -import java.util.Map; -import java.util.logging.Logger; - -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; - +import com.vaadin.cdi.UIScoped; +import com.vaadin.server.VaadinSession; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.context.AbstractContext; import org.apache.deltaspike.core.util.context.ContextualStorage; -import com.vaadin.cdi.UIScoped; -import com.vaadin.ui.UI; -import com.vaadin.util.CurrentInstance; +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.inject.spi.BeanManager; +import java.lang.annotation.Annotation; /** * UIScopedContext is the context for @UIScoped beans. */ -public class UIScopedContext extends AbstractVaadinContext { +public class UIScopedContext extends AbstractContext { + + private UIContextualStorageManager contextualStorageManager; public UIScopedContext(final BeanManager beanManager) { super(beanManager); - getLogger().fine("Instantiating UIScoped context"); } @Override - public Class getScope() { - return UIScoped.class; + protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { + return contextualStorageManager.getContextualStorage(createIfNotExist); } - @Override - protected Contextual wrapBean(Contextual bean) { - if(!(bean instanceof UIContextual) && bean instanceof Bean && UI.class.isAssignableFrom(((Bean) bean).getBeanClass())) { - return new UIBean((Bean) bean); - } - return bean; + public void init(BeanManager beanManager) { + contextualStorageManager = BeanProvider + .getContextualReference(beanManager, UIContextualStorageManager.class, false); } @Override - protected synchronized ContextualStorage getContextualStorage( - Contextual contextual, boolean createIfNotExist) { - SessionData sessionData; - if (contextual instanceof UIContextual) { - sessionData = getSessionData( - ((UIContextual) contextual).getSessionId(), - createIfNotExist); - } else { - sessionData = getSessionData(createIfNotExist); - } - if (sessionData == null) { - if (createIfNotExist) { - throw new IllegalStateException( - "Session data not recoverable for " + contextual); - } else { - // noop - return null; - } - } - - // If a non-UI class has the @UIScoped annotation the contextual - // parameter is a CDI managed bean. We need to wrap this in a - // UIContextual so that we can clean up its storage once the UI has been - // closed. - if (!(contextual instanceof UIContextual)) { - if (CurrentInstance.get(UIBean.class) != null) { - contextual = CurrentInstance.get(UIBean.class); - } else { - contextual = new UIContextual(contextual); - } - } - - Map, ContextualStorage> map = sessionData.getStorageMap(); - if (map == null) { - return null; - } - - if (map.containsKey(contextual)) { - ContextualStorage storage = map.get(contextual); - return storage; - } else if (createIfNotExist) { - ContextualStorage storage = new VaadinContextualStorage(getBeanManager(), - true); - map.put(contextual, storage); - return storage; - } else { - return null; - } - + public Class getScope() { + return UIScoped.class; } @Override - protected Logger getLogger() { - return Logger.getLogger(UIScopedContext.class.getCanonicalName()); + public boolean isActive() { + return VaadinSession.getCurrent() != null + && contextualStorageManager != null + && contextualStorageManager.isActive(); } + } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinContextualStorage.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinContextualStorage.java index f8fe050d..a1340a75 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinContextualStorage.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinContextualStorage.java @@ -1,31 +1,62 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.PassivationCapable; - import org.apache.deltaspike.core.util.context.ContextualStorage; +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.inject.spi.PassivationCapable; + /** * Customized version of ContextualStorage to also handle beans that are not * PassivationCapable. Such beans are used as their own keys, which is not ideal * but should work in most single-JVM environments. - * + * + * Note: + * Supporting non-PassivationCapable beans is theoretical. + * Not required by the spec, but in reality beans are PassivationCapable. + * Even for non serializable bean classes. + * + * CDI implementations use PassivationCapable beans, + * because injecting non serializable proxies might block serialization of + * bean instances in a passivation capable context. + * * @see ContextualStorage */ public class VaadinContextualStorage extends ContextualStorage { + private final BeanManager beanManager; - public VaadinContextualStorage(BeanManager beanManager, - boolean concurrent) { - super(beanManager, concurrent, false); + public VaadinContextualStorage(BeanManager beanManager) { + // Concurrency handling ignored intentionally. + // Locking of VaadinSession is responsibility of the Vaadin Framework. + super(beanManager, false, true); + this.beanManager = beanManager; } - + @Override public Object getBeanKey(Contextual bean) { - if (bean instanceof UIContextual) { - return ((UIContextual) bean).delegate; + if(bean instanceof PassivationCapable) { + return super.getBeanKey(bean); + } else { + return bean; + } + } + + @Override + public Contextual getBean(Object beanKey) { + if (beanKey instanceof String) { + return beanManager.getPassivationCapableBean((String) beanKey); } else { - return super.getBeanKey(bean); + return (Contextual) beanKey; } } } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinExtension.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinExtension.java index 22df4bd9..6db51a52 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinExtension.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinExtension.java @@ -1,53 +1,34 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.internal; +import com.vaadin.cdi.*; +import com.vaadin.cdi.internal.InconsistentDeploymentException.ID; +import com.vaadin.navigator.View; +import com.vaadin.ui.Component; +import com.vaadin.ui.UI; + +import jakarta.enterprise.context.Dependent; +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.*; import java.lang.reflect.Modifier; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; -import javax.enterprise.event.Observes; -import javax.enterprise.inject.spi.AfterBeanDiscovery; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.enterprise.inject.spi.Extension; -import javax.enterprise.inject.spi.ProcessManagedBean; - -import com.vaadin.cdi.CDIView; -import com.vaadin.cdi.NormalUIScoped; -import com.vaadin.cdi.NormalViewScoped; -import com.vaadin.cdi.UIScoped; -import com.vaadin.cdi.ViewScoped; -import com.vaadin.cdi.internal.InconsistentDeploymentException.ID; -import com.vaadin.navigator.View; -import com.vaadin.ui.Component; - /** * CDI Extension needed to register the @CDIUI scope to the runtime. */ public class VaadinExtension implements Extension { - public static final class VaadinComponentProxyException extends Exception { - public VaadinComponentProxyException(String message) { - super(message); - } - } - private UIScopedContext uiScopedContext; private ViewScopedContext viewScopedContext; @@ -66,19 +47,46 @@ void processManagedBean(@Observes ProcessManagedBean pmb, + beanClass.getCanonicalName()); } - if (beanClass.isAnnotationPresent(CDIView.class) - && !View.class.isAssignableFrom(beanClass) - && !Modifier.isAbstract(beanClass.getModifiers())) { - String message = "The non-abstract class " - + beanClass.getCanonicalName() - + " with @CDIView should implement " - + View.class.getCanonicalName(); - getLogger().warning(message); - throw new InconsistentDeploymentException(ID.CDIVIEW_WITHOUT_VIEW, - message); + if (beanClass.isAnnotationPresent(CDIView.class)) { + if (!View.class.isAssignableFrom(beanClass) + && !Modifier.isAbstract(beanClass.getModifiers())) { + String message = "The non-abstract class " + + beanClass.getCanonicalName() + + " with @CDIView should implement " + + View.class.getCanonicalName(); + throwInconsistentDeployment(ID.CDIVIEW_WITHOUT_VIEW, message); + } + if (Dependent.class.equals(beanScope)) { + String message = "The CDI View class " + + beanClass.getCanonicalName() + + " should not be Dependent."; + throwInconsistentDeployment(ID.CDIVIEW_DEPENDENT, message); + } + } + + if (beanClass.isAnnotationPresent(CDIUI.class)) { + if (!UI.class.isAssignableFrom(beanClass) + && !Modifier.isAbstract(beanClass.getModifiers())) { + String message = "The non-abstract class " + + beanClass.getCanonicalName() + + " with @CDIUI should extend " + + UI.class.getCanonicalName(); + throwInconsistentDeployment(ID.CDIUI_WITHOUT_UI, message); + } + if (!UIScoped.class.equals(beanScope)) { + String message = "The CDI UI class " + + beanClass.getCanonicalName() + + " should be @UIScoped."; + throwInconsistentDeployment(ID.CDIUI_SCOPE, message); + } } } + private void throwInconsistentDeployment(ID errorId, String message) { + getLogger().warning(message); + throw new InconsistentDeploymentException(errorId, message); + } + void afterBeanDiscovery( @Observes final AfterBeanDiscovery afterBeanDiscovery, final BeanManager beanManager) { @@ -102,59 +110,26 @@ void afterBeanDiscovery( afterBeanDiscovery.addContext(new ContextWrapper(uiScopedContext, NormalUIScoped.class)); getLogger().info("UIScopedContext registered for Vaadin CDI"); + viewScopedContext = new ViewScopedContext(beanManager); afterBeanDiscovery.addContext(new ContextWrapper(viewScopedContext, ViewScoped.class)); afterBeanDiscovery.addContext(new ContextWrapper(viewScopedContext, NormalViewScoped.class)); getLogger().info("ViewScopedContext registered for Vaadin CDI"); - } - - private static Logger getLogger() { - return Logger.getLogger(VaadinExtension.class.getCanonicalName()); - } - private void sessionClose(@Observes VaadinSessionDestroyEvent event) { - if (uiScopedContext != null) { - uiScopedContext.dropSessionData(event); - } - if (viewScopedContext != null) { - viewScopedContext.dropSessionData(event); - } + VaadinSessionScopedContext vaadinSessionScopedContext = new VaadinSessionScopedContext(beanManager); + afterBeanDiscovery.addContext(new ContextWrapper(vaadinSessionScopedContext, VaadinSessionScoped.class)); + getLogger().info("VaadinSessionScopedContext registered for Vaadin CDI"); } - private void uiClose(@Observes VaadinUICloseEvent event) { - if (uiScopedContext != null) { - uiScopedContext.queueUICloseEvent(event); - } - if (viewScopedContext != null) { - viewScopedContext.queueUICloseEvent(event); - } + public void initializeContexts(@Observes AfterDeploymentValidation adv, BeanManager beanManager) { + uiScopedContext.init(beanManager); + viewScopedContext.init(beanManager); } - private void requestEnd(@Observes VaadinViewChangeCleanupEvent event) { - if (uiScopedContext != null) { - uiScopedContext.uiCloseCleanup(); - } - if (viewScopedContext != null) { - viewScopedContext.uiCloseCleanup(); - viewScopedContext.clearPendingViewChange(event.getSessionId(), - event.getUiId()); - } - } - - private void navigationChanged(@Observes VaadinViewChangeEvent event) { - if (viewScopedContext != null) { - long sessionId = event.getSessionId(); - int uiId = event.getUiId(); - viewScopedContext.viewChangeCleanup(sessionId, uiId); - } + private static Logger getLogger() { + return Logger.getLogger(VaadinExtension.class.getCanonicalName()); } - private void navigationStarting(@Observes VaadinViewCreationEvent event) { - if (viewScopedContext != null) { - viewScopedContext.prepareForViewChange(event.getSessionId(), - event.getUIId(), event.getViewMapping()); - } - } } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionDestroyEvent.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionDestroyEvent.java deleted file mode 100644 index 9c68495e..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionDestroyEvent.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - - -public class VaadinSessionDestroyEvent { - - private long sessionId; - - public VaadinSessionDestroyEvent(long sessionId) { - this.sessionId = sessionId; - - } - - public long getSessionId() { - return sessionId; - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionScopedContext.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionScopedContext.java new file mode 100644 index 00000000..3b2dde99 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinSessionScopedContext.java @@ -0,0 +1,88 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.cdi.VaadinSessionScoped; +import com.vaadin.server.VaadinSession; +import org.apache.deltaspike.core.util.ContextUtils; +import org.apache.deltaspike.core.util.context.AbstractContext; +import org.apache.deltaspike.core.util.context.ContextualStorage; + +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.inject.spi.BeanManager; +import java.lang.annotation.Annotation; + +/** + * Context for {@link VaadinSessionScoped}. + * + * Stores contextuals in {@link VaadinSession}. + * Other Vaadin CDI contexts are stored in the corresponding VaadinSessionScoped context. + * + * @since 3.0 + */ +public class VaadinSessionScopedContext extends AbstractContext { + private final BeanManager beanManager; + private static final String ATTRIBUTE_NAME = VaadinSessionScopedContext.class.getName(); + + public VaadinSessionScopedContext(BeanManager beanManager) { + super(beanManager); + this.beanManager = beanManager; + } + + @Override + protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { + VaadinSession session = VaadinSession.getCurrent(); + ContextualStorage storage = findContextualStorage(session); + if (storage == null && createIfNotExist) { + storage = new VaadinContextualStorage(beanManager); + session.setAttribute(ATTRIBUTE_NAME, storage); + } + return storage; + } + + private static ContextualStorage findContextualStorage(VaadinSession session) { + return (ContextualStorage) session.getAttribute(ATTRIBUTE_NAME); + } + + @Override + public Class getScope() { + return VaadinSessionScoped.class; + } + + @Override + public boolean isActive() { + return VaadinSession.getCurrent() != null; + } + + public static void destroy(VaadinSession session) { + ContextualStorage storage = findContextualStorage(session); + if (storage != null) { + AbstractContext.destroyAllActive(storage); + } + } + + /** + * Guess whether this context is undeployed. + * + * Tomcat expires sessions after contexts are undeployed. + * Need this guess to prevent exceptions when try to + * properly destroy contexts on session expiration. + * + * @return true when context is not active, but sure it should + */ + public static boolean guessContextIsUndeployed() { + // Given there is a current VaadinSession, we should have an active context, + // except we get here after the application is undeployed. + return (VaadinSession.getCurrent() != null + && !ContextUtils.isContextActive(VaadinSessionScoped.class)); + } + +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinUICloseEvent.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinUICloseEvent.java deleted file mode 100644 index e07d058c..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinUICloseEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -public class VaadinUICloseEvent { - - private long sessionId; - private int uiId; - - public VaadinUICloseEvent(long sessionId, int uiId) { - this.sessionId = sessionId; - this.uiId = uiId; - - } - - public long getSessionId() { - return sessionId; - } - - public int getUiId() { - return uiId; - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeCleanupEvent.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeCleanupEvent.java deleted file mode 100644 index 0f7d4b10..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeCleanupEvent.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -public class VaadinViewChangeCleanupEvent { - - private final long sessionId; - private final int uiId; - - public VaadinViewChangeCleanupEvent(long sessionId, int uiId) { - this.sessionId = sessionId; - this.uiId = uiId; - } - - public long getSessionId() { - return sessionId; - } - - public int getUiId() { - return uiId; - } -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeEvent.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeEvent.java deleted file mode 100644 index d23bdba1..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewChangeEvent.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -public class VaadinViewChangeEvent { - - private long sessionId; - private int uiId; - private String viewName; - - public VaadinViewChangeEvent(long sessionId, int uiId, - String viewName) { - this.sessionId = sessionId; - this.uiId = uiId; - this.viewName = viewName; - } - - public long getSessionId() { - return sessionId; - } - - public int getUiId() { - return uiId; - } - - public String getViewName() { - return viewName; - } - - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewCreationEvent.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewCreationEvent.java deleted file mode 100644 index 00f6e180..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/VaadinViewCreationEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -public class VaadinViewCreationEvent { - - private long sessionId; - private String viewMapping; - private int uiId; - - public VaadinViewCreationEvent(long sessionId, int uiId, String viewMapping) { - this.sessionId = sessionId; - this.viewMapping = viewMapping; - this.uiId = uiId; - } - - public String getViewMapping() { - return viewMapping; - } - - public int getUIId() { - return uiId; - } - - public long getSessionId() { - return sessionId; - } -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewBean.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewBean.java deleted file mode 100644 index 428f92f1..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewBean.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.Set; -import java.util.logging.Logger; - -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.InjectionPoint; -import javax.enterprise.inject.spi.PassivationCapable; - -import com.vaadin.ui.UI; - -public class ViewBean extends ViewContextual implements Bean, PassivationCapable { - - public ViewBean(Bean delegate, long sessionId, int uiId, - String viewIdentifier) { - super(delegate, sessionId, uiId, viewIdentifier); - } - - public ViewBean(Bean delegate, int uiId, String viewName) { - super(delegate, CDIUtil.getSessionId(), uiId, viewName); - } - - public ViewBean(Bean delegate, String viewName) { - super(delegate, CDIUtil.getSessionId(), UI.getCurrent().getUIId(), viewName); - } - - private Bean getDelegate() { - return (Bean) delegate; - } - - @Override - public Set getTypes() { - return getDelegate().getTypes(); - } - - @Override - public Set getQualifiers() { - return getDelegate().getQualifiers(); - } - - @Override - public Class getScope() { - return getDelegate().getScope(); - } - - @Override - public String getName() { - return getDelegate().getName(); - } - - @Override - public Set> getStereotypes() { - return getDelegate().getStereotypes(); - } - - @Override - public Class getBeanClass() { - return getDelegate().getBeanClass(); - } - - @Override - public boolean isAlternative() { - return getDelegate().isAlternative(); - } - - @Override - public boolean isNullable() { - return getDelegate().isNullable(); - } - - @Override - public Set getInjectionPoints() { - return getDelegate().getInjectionPoints(); - } - - @Override - public boolean equals(Object o) { - if(this == o) { - return true; - } - - if(o == null || !(o instanceof ViewBean)) { - return false; - } - - return super.equals(o); - } - - @Override - public String getId() { - StringBuilder sb = new StringBuilder( - "com.vaadin.cdi.internal.ViewBean#"); - sb.append(uiId); - sb.append("#"); - sb.append(sessionId); - sb.append("#"); - sb.append(viewIdentifier); - - if (delegate instanceof PassivationCapable) { - String delegatePassivationID = ((PassivationCapable) delegate) - .getId(); - if (delegatePassivationID != null - && !delegatePassivationID.isEmpty()) { - sb.append("#"); - sb.append(delegatePassivationID); - } else { - sb.append("#null#"); - sb.append(getBeanClass().getCanonicalName()); - } - } else { - // Even if the bean itself is not passivation capable, we're still - // using ViewBean.getid() as a key in ContextualStorage. It may mix - // up beans in some cases, specifically if we're injecting - // non-passivation-capable beans as @ViewScoped - sb.append("#"); - sb.append(getBeanClass().getCanonicalName()); - } - return sb.toString(); - } - - private Logger getLogger() { - return Logger.getLogger(ViewBean.class.getCanonicalName()); - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategies.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategies.java new file mode 100644 index 00000000..2c8f7883 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategies.java @@ -0,0 +1,83 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.cdi.AfterViewChange; +import com.vaadin.cdi.NormalUIScoped; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNavigation; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategy; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNameAndParameters; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByName; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; + +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; +import java.io.Serializable; +import java.util.Objects; + +/** + * Holder class for ViewContextStrategy implementations. + */ +public class ViewContextStrategies { + + @NormalUIScoped + @ViewContextByName + public static class ViewName implements ViewContextStrategy { + @Inject + private CurrentViewState currentViewState; + + @Override + public boolean inCurrentContext(String viewName, String parameters) { + return Objects.equals(viewName, currentViewState.getViewName()); + } + } + + @NormalUIScoped + @ViewContextByNameAndParameters + public static class ViewNameAndParameters implements ViewContextStrategy { + @Inject + private CurrentViewState currentViewState; + + @Override + public boolean inCurrentContext(String viewName, String parameters) { + return Objects.equals(viewName, currentViewState.getViewName()) + && Objects.equals(parameters, currentViewState.getParameters()); + } + } + + @NormalUIScoped + @ViewContextByNavigation + public static class EveryNavigation implements ViewContextStrategy { + @Override + public boolean inCurrentContext(String viewName, String parameters) { + return false; + } + } + + @NormalUIScoped + public static class CurrentViewState implements Serializable { + private String viewName; + private String parameters; + + private void onViewChange(@Observes @AfterViewChange ViewChangeEvent event) { + viewName = event.getViewName(); + parameters = event.getParameters(); + } + + public String getViewName() { + return viewName; + } + + public String getParameters() { + return parameters; + } + } +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategyProvider.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategyProvider.java new file mode 100644 index 00000000..9c49c277 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextStrategyProvider.java @@ -0,0 +1,72 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategy; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategyQualifier; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNameAndParameters; +import com.vaadin.navigator.View; +import org.apache.deltaspike.core.api.provider.BeanProvider; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.inject.Any; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.inject.Inject; +import java.lang.annotation.Annotation; +import java.util.Set; + +/** + * Looks up ViewContextStrategy for view classes. + */ +@ApplicationScoped +public class ViewContextStrategyProvider { + private static final Any ANY_LITERAL = Any.Literal.INSTANCE; + @Inject + private BeanManager beanManager; + + public ViewContextStrategy lookupStrategy(Class viewClass) { + Class annotationClass = findStrategyAnnotation(viewClass); + if (annotationClass == null) { + annotationClass = ViewContextByNameAndParameters.class; + } + final Bean strategyBean = findStrategyBean(annotationClass); + if (strategyBean == null) { + throw new IllegalStateException( + "No ViewContextStrategy found for " + annotationClass.getCanonicalName()); + } + return BeanProvider.getContextualReference(ViewContextStrategy.class, strategyBean); + } + + private Class findStrategyAnnotation(Class viewClass) { + final Annotation[] annotations = viewClass.getAnnotations(); + for (Annotation annotation : annotations) { + final Class annotationType = annotation.annotationType(); + if (annotationType.getAnnotation(ViewContextStrategyQualifier.class) != null) { + return annotationType; + } + } + return null; + } + + private Bean findStrategyBean(Class annotationClass) { + final Set> strategyBeans = + beanManager.getBeans(ViewContextStrategy.class, ANY_LITERAL); + for (Bean strategyBean : strategyBeans) { + final Class strategyBeanClass = strategyBean.getBeanClass(); + if (ViewContextStrategy.class.isAssignableFrom(strategyBeanClass) + && strategyBeanClass.getAnnotation(annotationClass) != null) { + return strategyBean; + } + } + return null; + } +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextual.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextual.java deleted file mode 100644 index 4af63f6c..00000000 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextual.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.internal; - -import javax.enterprise.context.spi.Contextual; - -import com.vaadin.ui.UI; - -/** - * Instances of this class are used as an identifier for determining - * the correct ContextualStorage in ViewScopedContext - * - * - */ -public class ViewContextual extends UIContextual { - - /** - * The mapped name of the view this ViewContextual is associated with. - * - * Must be a non-null value. - */ - protected String viewIdentifier; - - public ViewContextual(Contextual delegate, long sessionId, int uiId, String viewIdentifier) { - super(delegate, sessionId, uiId); - this.viewIdentifier = viewIdentifier; - } - - public ViewContextual(Contextual delegate, long sessionId, String viewIdentifier) { - this(delegate, sessionId, UI.getCurrent().getUIId(), viewIdentifier); - } - - public ViewContextual(Contextual delegate, String viewIdentifier) { - this(delegate, CDIUtil.getSessionId(), viewIdentifier); - } - - @Override - public boolean equals(Object o) { - ViewContextual vc = null; - if (o instanceof ViewContextual) { - vc = (ViewContextual) o; - return super.equals(o) - && this.viewIdentifier.equals(vc.viewIdentifier); - } else { - return false; - } - } - - @Override - public int hashCode() { - int result = (int) sessionId; - result = (31 * result + uiId) ^ viewIdentifier.hashCode(); - return result; - } - -} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextualStorageManager.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextualStorageManager.java new file mode 100644 index 00000000..dcc31e5a --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewContextualStorageManager.java @@ -0,0 +1,128 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.cdi.NormalUIScoped; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategy; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.context.AbstractContext; +import org.apache.deltaspike.core.util.context.ContextualStorage; + +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.inject.Inject; +import java.io.Serializable; + +/** + * Manage and store ContextualStorage for view context. + * This class is responsible for + * - selecting the active view context + * - creating, and providing the ContextualStorage for it + * - destroying contextual instances + * + * Concurrency handling ignored intentionally. + * Locking of VaadinSession is the responsibility of Vaadin Framework. + */ +@NormalUIScoped +public class ViewContextualStorageManager implements Serializable { + private final static Storage CLOSED = new ClosedStorage(); + private Storage openingContext = CLOSED; + private Storage currentContext = CLOSED; + @Inject + private BeanManager beanManager; + @Inject + private ViewContextStrategyProvider viewContextStrategyManager; + + public void applyChange(ViewChangeListener.ViewChangeEvent event) { + if (!currentContext.contains(event.getViewName(), event.getParameters())) { + currentContext.destroy(); + currentContext = openingContext; + openingContext = CLOSED; + } + } + + public View prepareChange(Bean viewBean, String viewName, String parameters) { + final Class beanClass = viewBean.getBeanClass(); + final Storage temp = currentContext; + if (!currentContext.contains(viewName, parameters)) { + openingContext.destroy(); + ViewContextStrategy strategy = viewContextStrategyManager.lookupStrategy(beanClass); + openingContext = new Storage(strategy); + currentContext = openingContext; + } + final View view = (View) BeanProvider.getContextualReference(beanClass, viewBean); + currentContext = temp; + return view; + } + + public void revertChange(ViewChangeListener.ViewChangeEvent event) { + if (openingContext.contains(event.getViewName(), event.getParameters())) { + openingContext.destroy(); + openingContext = CLOSED; + } + } + + public ContextualStorage getContextualStorage(boolean createIfNotExist) { + return currentContext.getContextualStorage(beanManager, createIfNotExist); + } + + public boolean isActive() { + return currentContext != CLOSED; + } + + @PreDestroy + private void preDestroy() { + openingContext.destroy(); + currentContext.destroy(); + } + + private static class Storage implements Serializable { + ContextualStorage contextualStorage; + final ViewContextStrategy strategy; + + Storage(ViewContextStrategy strategy) { + this.strategy = strategy; + } + + ContextualStorage getContextualStorage(BeanManager beanManager, boolean createIfNotExist) { + if (createIfNotExist && contextualStorage == null) { + contextualStorage = new VaadinContextualStorage(beanManager); + } + return contextualStorage; + } + + void destroy() { + if (contextualStorage != null) { + AbstractContext.destroyAllActive(contextualStorage); + } + } + + boolean contains(String viewName, String parameters) { + return strategy.inCurrentContext(viewName, parameters); + } + + } + + private static class ClosedStorage extends Storage { + ClosedStorage() { + super((viewName, parameters) -> false); + } + + @Override + ContextualStorage getContextualStorage(BeanManager beanManager, boolean createIfNotExist) { + throw new IllegalStateException("Storage is closed"); + } + } + +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewScopedContext.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewScopedContext.java index b38d0d1b..839b1107 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewScopedContext.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/ViewScopedContext.java @@ -1,177 +1,55 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.internal; -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.logging.Logger; - -import javax.enterprise.context.spi.Contextual; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; - -import org.apache.deltaspike.core.util.context.ContextualStorage; - import com.vaadin.cdi.ViewScoped; -import com.vaadin.cdi.internal.AbstractVaadinContext.SessionData.UIData; -import com.vaadin.navigator.View; import com.vaadin.ui.UI; +import org.apache.deltaspike.core.api.provider.BeanProvider; +import org.apache.deltaspike.core.util.context.AbstractContext; +import org.apache.deltaspike.core.util.context.ContextualStorage; + +import jakarta.enterprise.context.spi.Contextual; +import jakarta.enterprise.inject.spi.BeanManager; +import java.lang.annotation.Annotation; /** * ViewScopedContext is the context for @ViewScoped beans. */ -public class ViewScopedContext extends AbstractVaadinContext { +public class ViewScopedContext extends AbstractContext { - private List viewMappings; + private ViewContextualStorageManager contextualStorageManager; - public ViewScopedContext(final BeanManager beanManager) { + public ViewScopedContext(BeanManager beanManager) { super(beanManager); - getLogger().fine("Instantiating ViewScoped context"); } @Override - public Class getScope() { - return ViewScoped.class; + protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { + return contextualStorageManager.getContextualStorage(createIfNotExist); } - @Override - protected Contextual wrapBean(Contextual bean) { - if (!(bean instanceof UIContextual) && bean instanceof Bean - && View.class.isAssignableFrom(((Bean) bean).getBeanClass())) { - String mapping = Conventions - .deriveMappingForView(((Bean) bean).getBeanClass()); - return new ViewBean((Bean) bean, mapping); - } - return bean; + public void init(BeanManager beanManager) { + contextualStorageManager = BeanProvider + .getContextualReference(beanManager, ViewContextualStorageManager.class, false); } @Override - protected synchronized ContextualStorage getContextualStorage( - Contextual contextual, boolean createIfNotExist) { - getLogger().fine("Retrieving contextual storage for " + contextual); - - SessionData sessionData; - if (contextual instanceof UIContextual) { - sessionData = getSessionData( - ((UIContextual) contextual).getSessionId(), - createIfNotExist); - } else { - sessionData = getSessionData(createIfNotExist); - } - if (sessionData == null) { - if (createIfNotExist) { - throw new IllegalStateException( - "Session data not recoverable for " + contextual); - } else { - // noop - return null; - } - } - - // The contextual is not a ViewContextual if we're injecting something - // other - // than a CDIView with the @ViewScoped annotation. In those cases we'll - // look up the currently active view for the current UI. Due to - // technical limitations of the core framework this involves some - // guesswork during view transition. - if (!(contextual instanceof ViewContextual)) { - UI currentUI = UI.getCurrent(); - if (currentUI == null) { - throw new IllegalStateException("Unable to resolve " - + contextual + ", current UI not set."); - } - UIData uiData = sessionData.getUIData(currentUI.getUIId(), true); - String viewName = uiData.getProbableInjectionPointView(); - if (viewName == null) { - getLogger().warning("Could not determine active View"); - } - if (contextual instanceof Bean) { - contextual = new ViewBean((Bean) contextual, viewName); - } else { - contextual = new ViewContextual(contextual, viewName); - } - - } - - Map, ContextualStorage> map = sessionData.getStorageMap(); - - if (map == null) { - return null; - } - - if (map.containsKey(contextual)) { - return map.get(contextual); - } else if (createIfNotExist) { - ContextualStorage storage = new VaadinContextualStorage( - getBeanManager(), true); - map.put(contextual, storage); - return storage; - } else { - return null; - } - - } - - synchronized void prepareForViewChange(long sessionId, int uiId, - String activeViewName) { - getLogger().fine("Setting next view to " + activeViewName); - SessionData sessionData = getSessionData(sessionId, true); - UIData uiData = sessionData.getUIData(uiId, true); - uiData.setOpeningView(activeViewName); - } - - synchronized void viewChangeCleanup(long sessionId, int uiId) { - getLogger().fine("ViewChangeCleanup for " + sessionId + " " + uiId); - SessionData sessionData = getSessionData(sessionId, true); - UIData uiData = sessionData.getUIData(uiId, true); - if (uiData == null) { - return; - } - - uiData.validateTransition(); - String activeViewName = uiData.getActiveView(); - - Map, ContextualStorage> map = sessionData.getStorageMap(); - for (Contextual key : new ArrayList>(map.keySet())) { - if (key instanceof ViewContextual) { - ViewContextual contextual = (ViewContextual) key; - if (contextual.uiId == uiId - && !contextual.viewIdentifier.equals(activeViewName)) { - ContextualStorage storage = map.remove(contextual); - destroyAllActive(storage); - } - } - } - } - - synchronized void clearPendingViewChange(long sessionId, int uiId) { - SessionData sessionData = getSessionData(sessionId, false); - if (sessionData != null) { - UIData uiData = sessionData.getUIData(uiId); - if (uiData != null) { - uiData.clearPendingViewChange(); - } - } + public Class getScope() { + return ViewScoped.class; } @Override - protected Logger getLogger() { - return Logger.getLogger(ViewScopedContext.class.getCanonicalName()); + public boolean isActive() { + return UI.getCurrent() != null + && contextualStorageManager != null + && contextualStorageManager.isActive(); } } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServlet.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServlet.java index 385f9e17..17dfda3f 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServlet.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServlet.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.server; diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServletService.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServletService.java index e74387bf..2f1d029a 100644 --- a/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServletService.java +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/server/VaadinCDIServletService.java @@ -1,39 +1,21 @@ /* - * Copyright 2000-2014 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.server; -import java.util.logging.Logger; - -import javax.enterprise.inject.spi.BeanManager; - import com.vaadin.cdi.CDIUIProvider; -import com.vaadin.cdi.CDIViewProvider; -import com.vaadin.cdi.internal.CDIUtil; -import com.vaadin.cdi.internal.VaadinSessionDestroyEvent; -import com.vaadin.cdi.internal.VaadinViewChangeCleanupEvent; -import com.vaadin.server.DeploymentConfiguration; -import com.vaadin.server.ServiceException; -import com.vaadin.server.SessionDestroyEvent; -import com.vaadin.server.SessionDestroyListener; -import com.vaadin.server.SessionInitEvent; -import com.vaadin.server.SessionInitListener; -import com.vaadin.server.VaadinRequest; -import com.vaadin.server.VaadinResponse; -import com.vaadin.server.VaadinServlet; -import com.vaadin.server.VaadinServletService; +import com.vaadin.cdi.internal.VaadinSessionScopedContext; +import com.vaadin.server.*; +import org.apache.deltaspike.core.api.provider.BeanProvider; + +import java.util.logging.Logger; /** * Servlet service implementation for Vaadin CDI. @@ -44,22 +26,29 @@ */ public class VaadinCDIServletService extends VaadinServletService { - private BeanManager beanManager = null; + private final CDIUIProvider cdiuiProvider; protected final class SessionListenerImpl implements SessionInitListener, SessionDestroyListener { @Override public void sessionInit(SessionInitEvent event) { getLogger().fine("Session init"); - event.getSession().addUIProvider(new CDIUIProvider()); + event.getSession().addUIProvider(cdiuiProvider); } @Override public void sessionDestroy(SessionDestroyEvent event) { - getLogger().fine("Firing session destroy event."); - VaadinSessionDestroyEvent sessionDestroyEvent = new VaadinSessionDestroyEvent( - CDIUtil.getSessionId(event.getSession())); - getBeanManager().fireEvent(sessionDestroyEvent); + if (VaadinSessionScopedContext.guessContextIsUndeployed()) { + // Happens on tomcat when it expires sessions upon undeploy. + // beanManager.getPassivationCapableBean returns null for passivation id, + // so we would get an NPE from AbstractContext.destroyAllActive + getLogger().warning("VaadinSessionScoped context does not exist. " + + "Maybe application is undeployed." + + " Can't destroy VaadinSessionScopedContext."); + return; + } + getLogger().fine("VaadinSessionScopedContext destroy"); + VaadinSessionScopedContext.destroy(event.getSession()); } } @@ -69,33 +58,15 @@ public VaadinCDIServletService(VaadinServlet servlet, throws ServiceException { super(servlet, deploymentConfiguration); + cdiuiProvider = BeanProvider.getContextualReference(CDIUIProvider.class, false); SessionListenerImpl sessionListener = new SessionListenerImpl(); addSessionInitListener(sessionListener); addSessionDestroyListener(sessionListener); } - protected BeanManager getBeanManager() { - if (beanManager == null) { - beanManager = CDIUtil.lookupBeanManager(); - } - return beanManager; - } - private static Logger getLogger() { return Logger.getLogger(VaadinCDIServletService.class .getCanonicalName()); } - @Override - public void handleRequest(VaadinRequest request, VaadinResponse response) - throws ServiceException { - super.handleRequest(request, response); - VaadinViewChangeCleanupEvent event = CDIViewProvider.getCleanupEvent(); - if (event != null) { - getLogger().fine("Cleaning up after View changing request."); - getBeanManager().fireEvent(event); - CDIViewProvider.removeCleanupEvent(); - } - - } } diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByName.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByName.java new file mode 100644 index 00000000..abe40f6a --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByName.java @@ -0,0 +1,37 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.viewcontextstrategy; + +import java.lang.annotation.*; + +import static com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; + +/** + * Strategy to hold the context open while view name does not change. + *

+ * This strategy is not on par with navigator view life cycle. While navigating + * to same view, same context remains active. + * {@link com.vaadin.navigator.View#enter(ViewChangeEvent)} will be called again + * on the same view instance. + *

+ * Note: Navigator view change events do not mean that the view + * context has changed. + * + * @see ViewContextStrategy + * @see ViewContextByNameAndParameters + * @see ViewContextByNavigation + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +@ViewContextStrategyQualifier +public @interface ViewContextByName { +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNameAndParameters.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNameAndParameters.java new file mode 100644 index 00000000..37a9aa0e --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNameAndParameters.java @@ -0,0 +1,40 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.viewcontextstrategy; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; + +import java.lang.annotation.*; + +/** + * Strategy to hold the context open while view name and view parameters do not + * change. + *

+ * This strategy is on par with navigator view life cycle. If navigation is not + * reverted in a {@link ViewChangeEvent#beforeViewChange(ViewChangeEvent)}, a + * new view context is activated. After + * {@link ViewChangeEvent#afterViewChange(ViewChangeEvent)} is called, old view + * context will be closed. + *

+ * {@link View#enter(ViewChangeEvent)} will be called for the new {@link View} + * instance. + * + * @see ViewContextStrategy + * @see ViewContextByName + * @see ViewContextByNavigation + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +@ViewContextStrategyQualifier +public @interface ViewContextByNameAndParameters { +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNavigation.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNavigation.java new file mode 100644 index 00000000..a9187bab --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextByNavigation.java @@ -0,0 +1,36 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.viewcontextstrategy; + +import com.vaadin.cdi.internal.ViewContextStrategies.ViewNameAndParameters; + +import java.lang.annotation.*; + +/** + * Strategy to release, and create a new context on every navigation regardless + * of view name and parameters. + *

+ * It is on par with navigator view life cycle, but navigating to same view with + * same parameters releases the context and creates a new one. + *

+ * In practice it works same as {@link ViewNameAndParameters}, even when + * parameters does not change. + * + * @see ViewContextStrategy + * @see ViewContextByName + * @see ViewContextByNameAndParameters + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +@ViewContextStrategyQualifier +public @interface ViewContextByNavigation { +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategy.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategy.java new file mode 100644 index 00000000..1645604c --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategy.java @@ -0,0 +1,80 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.viewcontextstrategy; + +import com.vaadin.navigator.View; + +import jakarta.enterprise.context.Dependent; +import java.io.Serializable; + +/** + * Decision strategy on whether target navigation state belongs to active view + * context. When the target navigation state does not belong to the active view + * context, the current context will be released and a new one is created. + *

+ * By default the views are using the {@link Dependent} scope, which can be used + * but is not recommended. Any {@link View} with a {@code ViewContextStrategy} + * should use one of the scopes provided in the Vaadin CDI integration. + *

+ * Separate annotations annotated by {@link ViewContextStrategyQualifier} have + * to exist for each of the implementations. + *

+ * Example of a custom implementation: + *

+ * A separate annotation. + * + *

+ * {@literal @}Retention(RetentionPolicy.RUNTIME)
+ * {@literal @}Target({ ElementType.TYPE })
+ * {@literal @}ViewContextStrategyQualifier
+ *  public {@literal @}interface MyStrategyAnnotation {
+ *  }
+ * 
+ * + * An implementation class. + * + *
+ * {@literal @}NormalUIScoped
+ * {@literal @}MyStrategyAnnotation
+ *  public class MyStrategy implements ViewContextStrategy {
+ *    public boolean contains(String viewName, String parameters) {
+ *      ...
+ *    }
+ *  }
+ * 
+ * + * Use annotation on the view. + * + *
+ * {@literal @}CDIView("myView")
+ * {@literal @}MyStrategyAnnotation
+ *  public MyView implements View {
+ *  ...
+ *  }
+ * 
+ */ +public interface ViewContextStrategy extends Serializable { + + /** + * Returns whether the active context contains target navigation state. This + * method should compare the current navigation state and the one given + * through the parameters and decide if the current context should be held + * open or released. + * + * @param viewName + * target navigation view name + * @param parameters + * target navigation parameters + * @return {@code true} to hold context open; {@code false} to release it + */ + boolean inCurrentContext(String viewName, String parameters); + +} diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategyQualifier.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategyQualifier.java new file mode 100644 index 00000000..892ab03c --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/viewcontextstrategy/ViewContextStrategyQualifier.java @@ -0,0 +1,32 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.viewcontextstrategy; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotations which define a strategy to + * drive the behavior of the view context have to be annotated with this. + *

+ * Annotations for built-in strategies: + * {@link ViewContextByNameAndParameters}, + * {@link ViewContextByName}, + * {@link ViewContextByNavigation} + * + * @see ViewContextStrategy + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE}) +public @interface ViewContextStrategyQualifier { +} diff --git a/vaadin-cdi/src/main/resources/META-INF/beans.xml b/vaadin-cdi/src/main/resources/META-INF/beans.xml index 1b5ed17e..42c62105 100644 --- a/vaadin-cdi/src/main/resources/META-INF/beans.xml +++ b/vaadin-cdi/src/main/resources/META-INF/beans.xml @@ -1,4 +1,7 @@ - + \ No newline at end of file diff --git a/vaadin-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension similarity index 100% rename from vaadin-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension rename to vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractCDIIntegrationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractCDIIntegrationTest.java index 6dfddd75..fa0c6057 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractCDIIntegrationTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractCDIIntegrationTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import org.jboss.arquillian.container.test.api.Deployer; @@ -7,19 +17,21 @@ import org.jboss.arquillian.test.api.ArquillianResource; import org.junit.runner.RunWith; import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; -import javax.enterprise.inject.New; import java.net.MalformedURLException; import java.net.URL; +import java.time.Duration; @RunWith(Arquillian.class) @RunAsClient abstract public class AbstractCDIIntegrationTest { @Drone - @New WebDriver firstWindow; @ArquillianResource @@ -31,8 +43,6 @@ abstract public class AbstractCDIIntegrationTest { protected static final By NAVIGATE_BUTTON = By.id("navigate"); protected static final String INSTRUMENTED_UI_URI = "instrumentedUI"; private static final String SECOND_UI_URI = "secondUI"; - protected static final String INSTRUMENTED_VIEW_URI = INSTRUMENTED_UI_URI - + "/#!instrumentedView"; protected static final String DANGLING_VIEW_URI = SECOND_UI_URI + "/#!danglingView"; @@ -53,5 +63,30 @@ public WebElement findElement(By by) { public WebElement findElement(String id) { return findElement(By.id(id)); } + public void clickAndWait(String id) { + findElement(id).click(); + waitForClient(); + } + + public void clickAndWait(By by) { + findElement(by).click(); + waitForClient(); + } + + public void waitForClient() { + new WebDriverWait(firstWindow, Duration.ofSeconds(10)).until(input -> + (Boolean) ((JavascriptExecutor) firstWindow) + .executeScript("return !vaadin.clients[Object.keys(vaadin.clients)[0]].isActive()")); + } + + public void refreshWindow() { + refreshWindow(firstWindow); + } + + public void refreshWindow(WebDriver window) { + window.navigate().refresh(); + (new WebDriverWait(window, Duration.ofSeconds(15))).until(ExpectedConditions + .presenceOfElementLocated(LABEL)); + } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractManagedCDIIntegrationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractManagedCDIIntegrationTest.java index 4113e70a..515d7afa 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractManagedCDIIntegrationTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractManagedCDIIntegrationTest.java @@ -1,12 +1,19 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; -import com.google.common.base.Predicate; import com.vaadin.cdi.internal.Conventions; import com.vaadin.cdi.uis.RootUI; -import org.jboss.arquillian.graphene.Graphene; import org.jboss.arquillian.test.api.ArquillianResource; import org.openqa.selenium.By; -import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; @@ -17,7 +24,7 @@ import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; -import java.util.concurrent.TimeUnit; +import java.time.Duration; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -43,7 +50,7 @@ public void openWindow(String uri) throws MalformedURLException { public void openWindow(WebDriver window, String uri) throws MalformedURLException { openWindowNoWait(window, uri, contextPath); - (new WebDriverWait(window, 15)).until(ExpectedConditions + (new WebDriverWait(window, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(LABEL)); } @@ -51,34 +58,20 @@ public void openWindowNoWait(String uri) throws MalformedURLException { openWindowNoWait(firstWindow, uri, contextPath); } - public void refreshWindow() { - refreshWindow(firstWindow); - } - - public void refreshWindow(WebDriver window) { - window.navigate().refresh(); - (new WebDriverWait(window, 15)).until(ExpectedConditions - .presenceOfElementLocated(LABEL)); - } - public void waitForValue(final By by, final int value) { - Graphene.waitModel(firstWindow).withTimeout(10, TimeUnit.SECONDS) - .until(new Predicate() { - @Override - public boolean apply(WebDriver driver) { + new WebDriverWait(firstWindow, Duration.ofSeconds(10)) + .until(driver -> { + try { return number(driver.findElement(by).getText()) == value; + } catch (NumberFormatException e) { + return false; } }); } public void waitForValue(final By by, final String value) { - Graphene.waitModel(firstWindow).withTimeout(10, TimeUnit.SECONDS) - .until(new Predicate() { - @Override - public boolean apply(WebDriver driver) { - return value.equals(driver.findElement(by).getText()); - } - }); + new WebDriverWait(firstWindow, Duration.ofSeconds(10)) + .until(driver -> value.equals(driver.findElement(by).getText())); } public void resetCounts() throws IOException { @@ -99,30 +92,8 @@ private String slurp(String uri) throws IOException { return line; } - public void clickAndWait(String id) { - findElement(id).click(); - waitForClient(); - } - - public void clickAndWait(By by) { - findElement(by).click(); - waitForClient(); - } - - public void waitForClient() { - new WebDriverWait(firstWindow, 10).until(new ClientIsReadyPredicate()); - } - public void assertDefaultRootNotInstantiated() throws IOException { assertThat(getCount(RootUI.CONSTRUCT_COUNT), is(0)); } - private class ClientIsReadyPredicate implements Predicate { - @Override - public boolean apply(WebDriver input) { - return (Boolean) ((JavascriptExecutor) firstWindow) - .executeScript("return !vaadin.clients[Object.keys(vaadin.clients)[0]].isActive()"); - } - } - } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractViewStrategyTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractViewStrategyTest.java new file mode 100644 index 00000000..af557064 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/AbstractViewStrategyTest.java @@ -0,0 +1,122 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.ViewStrategyUI; +import org.junit.Before; + +import java.io.IOException; + +import static com.vaadin.cdi.uis.ViewStrategyUI.NAVBTN_ID; +import static com.vaadin.cdi.uis.ViewStrategyUI.TARGETSTATE_ID; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +abstract class AbstractViewStrategyTest extends AbstractManagedCDIIntegrationTest { + + @Before + public void setUp() throws Exception { + String viewUri = Conventions.deriveMappingForUI(ViewStrategyUI.class); + openWindow(viewUri); + resetCounts(); + } + + + protected void assertDestroyCounts(int count) throws IOException { + assertViewDestroyCount(count); + assertBeanDestroyCount(count); + } + + protected void assertConstructCounts(int count) throws IOException { + assertViewConstructCount(count); + assertBeanConstructCount(count); + } + + + protected void assertViewDestroyCount(int count) throws IOException { + assertThat(getCount(getTestedViewDestroyCounter()), is(count)); + } + + protected void assertBeanDestroyCount(int count) throws IOException { + assertThat(getCount(ViewStrategyUI.ViewScopedBean.DESTROY_COUNT), is(count)); + } + + protected abstract String getTestedViewDestroyCounter(); + + protected abstract String getTestedViewConstructCounter(); + + protected void assertBeanConstructCount(int count) throws IOException { + assertThat(getCount(ViewStrategyUI.ViewScopedBean.CONSTRUCT_COUNT), is(count)); + } + + protected void assertViewConstructCount(int count) throws IOException { + assertThat(getCount(getTestedViewConstructCounter()), is(count)); + } + + protected void assertBeanValue(String expectedValue) { + String value = findElement(ViewStrategyUI.VALUE_LABEL_ID).getText(); + assertEquals(expectedValue, value); + } + + protected void navigateTo(String viewState) { + findElement(TARGETSTATE_ID).clear(); + findElement(TARGETSTATE_ID).sendKeys(viewState); + clickAndWait(NAVBTN_ID); + } + + protected void assertNop(String sourceState, String targetState, String beanValue) + throws Exception { + navigateTo(sourceState); + assertConstructCounts(1); + assertDestroyCounts(0); + assertBeanValue(beanValue); + + navigateTo(targetState); + // context hold + assertConstructCounts(1); + assertDestroyCounts(0); + // no navigation happened - init not called again + assertBeanValue(beanValue); + } + + protected void assertAfterNavigateToOtherViewContextCreated(String sourceState, String srcBeanValue) + throws Exception { + navigateTo(sourceState); + assertConstructCounts(1); + assertDestroyCounts(0); + assertThat(getCount(ViewStrategyUI.OtherView.CONSTRUCT_COUNT), is(0)); + assertBeanValue(srcBeanValue); + + navigateTo(ViewStrategyUI.OTHER); + assertViewConstructCount(1); + assertBeanConstructCount(2); // bean created again in new context + assertDestroyCounts(1); + assertThat(getCount(ViewStrategyUI.OtherView.CONSTRUCT_COUNT), is(1)); + assertBeanValue(",other:"); + } + + protected void assertAfterNavigateToTestedViewContextCreated( + String sourceState, String targetState, String srcBeanValue, String targetBeanValue) + throws Exception { + navigateTo(sourceState); + assertConstructCounts(1); + assertDestroyCounts(0); + assertBeanValue(srcBeanValue); + + navigateTo(targetState); + assertViewConstructCount(2); + assertBeanConstructCount(2); + assertDestroyCounts(1); + assertBeanValue(targetBeanValue); + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ArchiveProvider.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ArchiveProvider.java index e4c8290b..5bb7e079 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ArchiveProvider.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ArchiveProvider.java @@ -1,56 +1,52 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; -import javax.enterprise.inject.spi.Extension; - +import com.vaadin.cdi.access.AccessControl; +import com.vaadin.cdi.access.JaasAccessControl; import com.vaadin.cdi.internal.*; +import com.vaadin.cdi.server.VaadinCDIServlet; +import com.vaadin.cdi.server.VaadinCDIServletService; +import com.vaadin.cdi.viewcontextstrategy.*; import org.jboss.shrinkwrap.api.ArchivePaths; import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage; -import com.vaadin.cdi.access.AccessControl; -import com.vaadin.cdi.access.JaasAccessControl; -import com.vaadin.cdi.server.VaadinCDIServlet; -import com.vaadin.cdi.server.VaadinCDIServletService; +import jakarta.enterprise.inject.spi.Extension; /** */ public class ArchiveProvider { public final static Class FRAMEWORK_CLASSES[] = new Class[] { - AccessControl.class, CDIUIProvider.class, CDIViewProvider.class, - ContextDeployer.class, JaasAccessControl.class, UIContextual.class, - UIBean.class, UIScopedContext.class, CDIUI.class, - ViewContextual.class, ViewBean.class, ViewScopedContext.class, - CDIView.class, VaadinSessionDestroyEvent.class, - VaadinUICloseEvent.class, VaadinViewChangeEvent.class, - VaadinViewCreationEvent.class, AbstractVaadinContext.class, - VaadinViewChangeCleanupEvent.class, VaadinCDIServlet.class, + AccessControl.class, CDIUIProvider.class, CDIViewProvider.class, CDINavigator.class, + ContextDeployer.class, JaasAccessControl.class, + UIScopedContext.class, UIContextualStorageManager.class, + ViewScopedContext.class, ViewContextualStorageManager.class, + ViewContextStrategy.class, AfterViewChange.class, ViewContextStrategyProvider.class, + ViewContextStrategyQualifier.class, ViewContextByNavigation.class, ViewContextByName.class, + ViewContextByNameAndParameters.class, ViewContextStrategies.class, + CDIView.class, CDIUI.class, + VaadinCDIServlet.class, VaadinCDIServletService.class, CDIUIProvider.DetachListenerImpl.class, - CDIViewProvider.ViewChangeListenerImpl.class, Conventions.class, + Conventions.class, InconsistentDeploymentException.class, AnnotationUtil.class, VaadinExtension.class, VaadinContextualStorage.class, ContextWrapper.class, - CDIUtil.class, URLMapping.class, + URLMapping.class, UIScoped.class, ViewScoped.class, NormalUIScoped.class, NormalViewScoped.class, + VaadinSessionScoped.class, VaadinSessionScopedContext.class, CounterFilter.class, Counter.class}; public static WebArchive createWebArchive(String warName, Class... classes) { return createWebArchive(warName, true, classes); @@ -72,7 +68,7 @@ static WebArchive base(String warName, boolean emptyBeansXml) { .create(WebArchive.class, warName + ".war") .addClasses(FRAMEWORK_CLASSES) .addAsLibraries( - pom.resolve("com.vaadin:vaadin-server") + pom.resolve("com.vaadin:vaadin-server-mpr-jakarta") .withTransitivity().asFile()) .addAsLibraries( pom.resolve("com.vaadin:vaadin-client-compiled") @@ -86,7 +82,8 @@ static WebArchive base(String warName, boolean emptyBeansXml) { .withTransitivity().asFile()) .addAsServiceProvider(Extension.class, VaadinExtension.class); if (emptyBeansXml) { - archive = archive.addAsWebInfResource(EmptyAsset.INSTANCE, + archive = archive.addAsWebInfResource( + new StringAsset(""), ArchivePaths.create("beans.xml")); } return archive; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingDeploymentTest.java index 5a64a955..81a93b19 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingDeploymentTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingDeploymentTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; import com.vaadin.cdi.uis.PlainColidingAlternativeUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingUIPathTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingUIPathTest.java deleted file mode 100644 index d91804ad..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithConflictingUIPathTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.vaadin.cdi; - -import com.vaadin.cdi.uis.AnotherPathCollisionUI; -import com.vaadin.cdi.uis.PathCollisionUI; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.InSequence; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; - -import static org.junit.Assert.fail; - -public class CDIIntegrationWithConflictingUIPathTest extends - AbstractCDIIntegrationTest { - - - @Deployment(name = "uiPathCollision", managed = false, testable = false) - public static WebArchive multipleUIsWithSamePath() { - return ArchiveProvider.createWebArchive("uiPathCollision", - PathCollisionUI.class, AnotherPathCollisionUI.class); - } - - /** - * Tests invalid deployment of multiple roots within a WAR Should be started - * first -- Arquillian deployments are not perfectly isolated. - */ - @Test(expected = Exception.class) - @InSequence(-2) - public void uiPathCollisionBreaksDeployment() throws Exception { - deployer.deploy("uiPathCollision"); - fail("Duplicate deployment paths should not be deployable"); - } - -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithCustomDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithCustomDeploymentTest.java index cbac6039..08ee30f8 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithCustomDeploymentTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithCustomDeploymentTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; import com.vaadin.cdi.uis.CustomMappingUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithDefaultDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithDefaultDeploymentTest.java index 048ef98f..383b7e02 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithDefaultDeploymentTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIIntegrationWithDefaultDeploymentTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; import com.vaadin.cdi.uis.*; @@ -53,7 +47,7 @@ public static WebArchive archiveWithDefaultRootUI() { RestrictedView.class, PlainUI.class, ParameterizedNavigationUI.class, EnterpriseUI.class, Boundary.class, EnterpriseLabel.class, SubUI.class, - PlainAlternativeUI.class, NoViewProviderNavigationUI.class, + PlainAlternativeUI.class, ConventionalView.class, MainView.class, SubView.class, AbstractScopedInstancesView.class, AbstractNavigatableView.class, NavigatableUI.class); @@ -106,36 +100,6 @@ public void oneToOneRelationBetweenBrowserAndUI() assertDefaultRootNotInstantiated(); } - @Test - public void dependentScopedViewIsInstantiatedTwiceWithViewProvider() - throws IOException { - openWindow(firstWindow, INSTRUMENTED_VIEW_URI); - firstWindow.findElement(NAVIGATE_BUTTON).click(); - waitForValue(VIEW_LABEL, "ViewLabel"); - assertThat(getCount(InstrumentedView.CONSTRUCT_COUNT), is(2)); - } - - @Test - public void dependentScopedViewIsInstantiatedOnce() - throws IOException { - String uri = deriveMappingForUI(NoViewProviderNavigationUI.class); - openWindow(uri); - assertThat(getCount(InstrumentedView.CONSTRUCT_COUNT), is(1)); - firstWindow.findElement(NAVIGATE_BUTTON).click(); - - waitForValue(VIEW_LABEL, "ViewLabel"); - assertThat(getCount(InstrumentedView.CONSTRUCT_COUNT), is(1)); - assertThat(getCount(NoViewProviderNavigationUI.CONSTRUCT_COUNT), is(1)); - assertThat(getCount(NoViewProviderNavigationUI.NAVIGATION_COUNT), is(1)); - - firstWindow.findElement(NAVIGATE_BUTTON).click(); - waitForValue(VIEW_LABEL, "ViewLabel"); - assertThat(getCount(InstrumentedView.CONSTRUCT_COUNT), is(1)); - assertThat(getCount(NoViewProviderNavigationUI.CONSTRUCT_COUNT), is(1)); - assertThat(getCount(NoViewProviderNavigationUI.NAVIGATION_COUNT), is(2)); - - } - @Test public void rootUIDiscovery() throws IOException { assertThat(getCount(RootUI.CONSTRUCT_COUNT), is(0)); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderTest.java index 4f280a4d..3315d273 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; import static org.hamcrest.CoreMatchers.is; @@ -33,7 +27,7 @@ public void initialize() { @Test public void uriWithJustUINoEndingSlash() { - String origin = "http://localhost:8080/hello-cdi/uIWithViewUI"; + String origin = "/uIWithViewUI"; String expected = "uIWithViewUI"; String actual = cut.parseUIMapping(origin); assertThat(actual, is(expected)); @@ -41,7 +35,7 @@ public void uriWithJustUINoEndingSlash() { @Test public void uriWithJustUIWithEndingSlash() { - String origin = "http://localhost:8080/hello-cdi/uIWithViewUI/"; + String origin = "/uIWithViewUI/"; String expected = "uIWithViewUI"; String actual = cut.parseUIMapping(origin); assertThat(actual, is(expected)); @@ -49,7 +43,7 @@ public void uriWithJustUIWithEndingSlash() { @Test public void uriWithUIAndViewWithoutEndingSlash() { - String origin = "http://localhost:8080/hello-cdi/uIWithViewUI/!helloView"; + String origin = "/uIWithViewUI/!helloView"; String expected = "uIWithViewUI"; String actual = cut.parseUIMapping(origin); assertThat(actual, is(expected)); @@ -57,10 +51,47 @@ public void uriWithUIAndViewWithoutEndingSlash() { @Test public void uriWithUIAndViewWithEndingSlash() { - String origin = "http://localhost:8080/hello-cdi/uIWithViewUI/!helloView/"; + String origin = "/uIWithViewUI/!helloView/"; String expected = "uIWithViewUI"; String actual = cut.parseUIMapping(origin); assertThat(actual, is(expected)); } + @Test + public void uriWithUIAndViewWithParameters() { + String origin = "/uIWithViewUI!helloView/param1=foo¶m2=bar"; + String expected = "uIWithViewUI"; + String actual = cut.parseUIMapping(origin); + assertThat(actual, is(expected)); + } + + /* + * PushState based navigation requires that the full path info is used as-is + * without ending slash. CDIUIProvider should match UI with + * String::startsWith. + */ + + @Test + public void uriWithUIAndViewWithEndingSlashForPushStateNavigation() { + String origin = "/uIWithViewUI/helloView/"; + String expected = "uIWithViewUI/helloView"; + String actual = cut.parseUIMapping(origin); + assertThat(actual, is(expected)); + } + + @Test + public void uriWithUIAndViewForPushStateNavigation() { + String origin = "/uIWithViewUI/helloView"; + String expected = "uIWithViewUI/helloView"; + String actual = cut.parseUIMapping(origin); + assertThat(actual, is(expected)); + } + + @Test + public void uriWithUIAndViewAndParametersForPushStateNavigation() { + String origin = "/uIWithViewUI/helloView/param1=foo/param2=bar"; + String expected = "uIWithViewUI/helloView/param1=foo/param2=bar"; + String actual = cut.parseUIMapping(origin); + assertThat(actual, is(expected)); + } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderViewDetectionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderViewDetectionTest.java new file mode 100644 index 00000000..fa0a10f6 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CDIUIProviderViewDetectionTest.java @@ -0,0 +1,79 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; + +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import com.vaadin.cdi.uis.RootUI; +import com.vaadin.cdi.uis.SubUI; +import com.vaadin.ui.UI; + +@RunWith(MockitoJUnitRunner.class) +public class CDIUIProviderViewDetectionTest { + + @Mock + BeanManager beanManager; + + @InjectMocks + CDIUIProvider cut; + + @Before + public void setUp() throws Exception { + final Set> beans = new LinkedHashSet<>(Arrays.asList( + mockBean(RootUI.class), mockBean(SubUI.class))); + + when(beanManager.getBeans(eq(UI.class), isA(Annotation.class))) + .thenReturn(beans); + } + + private Bean mockBean(Class beanClass) { + final Bean bean = mock(Bean.class); + when(bean.getBeanClass()).thenReturn(beanClass); + return bean; + } + + private void assertMapping(Class uiClass, String mapping) { + Assert.assertEquals(uiClass.getCanonicalName(), + cut.getUIBeanWithMapping(mapping).getBeanClass().getCanonicalName()); + } + + @Test + public void testRootUI() { + assertMapping(RootUI.class, ""); + assertMapping(RootUI.class, cut.parseUIMapping("/!")); + assertMapping(RootUI.class, cut.parseUIMapping("/!subUI")); + } + + @Test + public void testSubUI() { + assertMapping(SubUI.class, "subUI"); + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ClusterTestCategory.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ClusterTestCategory.java new file mode 100644 index 00000000..98acb357 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ClusterTestCategory.java @@ -0,0 +1,14 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +public interface ClusterTestCategory { +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ConsistentInjectionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ConsistentInjectionTest.java index dc03830d..f9727aa8 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ConsistentInjectionTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ConsistentInjectionTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.Conventions; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/CrossInjectionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/CrossInjectionTest.java index b7f1fb61..cd55bd2d 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/CrossInjectionTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/CrossInjectionTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import static com.vaadin.cdi.internal.Conventions.deriveMappingForUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/DeploymentTestSuiteIT.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/DeploymentTestSuiteIT.java index 35239585..6a9625d1 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/DeploymentTestSuiteIT.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/DeploymentTestSuiteIT.java @@ -1,24 +1,31 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; -import org.junit.runner.RunWith; -import org.junit.runners.Suite; - import com.vaadin.cdi.internal.ConventionsTest; import com.vaadin.cdi.shiro.ShiroTest; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ CDIIntegrationWithCustomDeploymentTest.class, CDIUIProviderTest.class, ConventionsTest.class, MultipleRootUIsTest.class, CDIIntegrationWithConflictingDeploymentTest.class, - CDIIntegrationWithConflictingUIPathTest.class, CDIIntegrationWithDefaultDeploymentTest.class, RootViewAtContextRootTest.class, MultipleAccessIsolationTest.class, ScopedInstancesTest.class, InjectionTest.class, ConsistentInjectionTest.class, QualifiedInjectionTest.class, MultipleSessionTest.class, ScopedProducerTest.class, CrossInjectionTest.class, ShiroTest.class, - InappropriateNestedServletInDeploymentTest.class, - InappropriateCDIViewInDeploymentTest.class, NonPassivatingBeanTest.class, - UIDestroyTest.class, ViewDestroyTest.class}) + InappropriateDeploymentTest.class, NonPassivatingBeanTest.class, + UIDestroyTest.class}) public class DeploymentTestSuiteIT { } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateCDIViewInDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateCDIViewInDeploymentTest.java deleted file mode 100644 index 7b48cc69..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateCDIViewInDeploymentTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.vaadin.cdi; - -import com.vaadin.cdi.views.CDIViewNotImplementingView; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.InSequence; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; - -import static org.junit.Assert.fail; - -public class InappropriateCDIViewInDeploymentTest extends - AbstractCDIIntegrationTest { - - @Deployment(name = "cdiViewWithoutView", managed = false, testable = false) - public static WebArchive multipleUIsWithSamePath() { - return ArchiveProvider.createWebArchive("cdiViewWithoutView", - CDIViewNotImplementingView.class); - } - - /** - * Tests invalid deployment of multiple roots within a WAR Should be started - * first -- Arquillian deployments are not perfectly isolated. - */ - @Test(expected = Exception.class) - @InSequence(-2) - public void cdiViewWithoutViewBreaksDeployment() throws Exception { - deployer.deploy("cdiViewWithoutView"); - fail("CDIView that does not implement View should not be deployable"); - } - -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateDeploymentTest.java new file mode 100644 index 00000000..b4fd581e --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateDeploymentTest.java @@ -0,0 +1,96 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.uis.*; +import com.vaadin.cdi.views.CDIViewDependent; +import com.vaadin.cdi.views.CDIViewNotImplementingView; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; + +import static org.junit.Assert.fail; + +public class InappropriateDeploymentTest extends + AbstractCDIIntegrationTest { + + @Deployment(name = "cdiViewWithoutView", managed = false, testable = false) + public static WebArchive cdiViewWithoutView() { + return ArchiveProvider.createWebArchive("cdiViewWithoutView", + CDIViewNotImplementingView.class); + } + + @Test(expected = Exception.class) + public void cdiViewWithoutViewBreaksDeployment() throws Exception { + deployer.deploy("cdiViewWithoutView"); + fail("CDIView that does not implement View should not be deployable"); + } + + @Deployment(name = "cdiViewDependent", managed = false, testable = false) + public static WebArchive cdiViewDependent() { + return ArchiveProvider.createWebArchive("cdiViewDependent", + CDIViewDependent.class); + } + + @Test(expected = Exception.class) + public void cdiViewDependentBreaksDeployment() throws Exception { + deployer.deploy("cdiViewDependent"); + fail("Dependent scoped CDIView should not be deployable"); + } + + @Deployment(name = "cdiUIWithoutUI", managed = false, testable = false) + public static WebArchive cdiUIWithoutUI() { + return ArchiveProvider.createWebArchive("cdiUIWithoutUI", + CDIUINotExtendingUI.class); + } + + @Test(expected = Exception.class) + public void cdiUIWithoutUIBreaksDeployment() throws Exception { + deployer.deploy("cdiUIWithoutUI"); + fail("CDIUI that does not extend UI should not be deployable"); + } + + @Deployment(name = "cdiUIWrongScope", managed = false, testable = false) + public static WebArchive cdiUIWrongScope() { + return ArchiveProvider.createWebArchive("cdiUIWrongScope", + CDIUIWrongScope.class); + } + + @Test(expected = Exception.class) + public void cdiUIWrongScopeBreaksDeployment() throws Exception { + deployer.deploy("cdiUIWrongScope"); + fail("CDIUI that is not @UIScoped should not be deployable"); + } + + @Deployment(name = "uiPathCollision", managed = false, testable = false) + public static WebArchive uiPathCollision() { + return ArchiveProvider.createWebArchive("uiPathCollision", + PathCollisionUI.class, AnotherPathCollisionUI.class); + } + + @Test(expected = Exception.class) + public void uiPathCollisionBreaksDeployment() throws Exception { + deployer.deploy("uiPathCollision"); + fail("Duplicate deployment paths should not be deployable"); + } + + @Deployment(name = "nestedServlet", managed = false, testable = false) + public static WebArchive nestedServlet() { + return ArchiveProvider.createWebArchive("nestedServlet", + UIWithNestedServlet.class); + } + + @Test(expected = Exception.class) + public void nestedServletBreaksDeployment() throws Exception { + deployer.deploy("nestedServlet"); + fail("Servlet class nested in the UI should not be deployable"); + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateNestedServletInDeploymentTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateNestedServletInDeploymentTest.java deleted file mode 100644 index e79077d5..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/InappropriateNestedServletInDeploymentTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi; - -import com.vaadin.cdi.uis.UIWithNestedServlet; -import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.InSequence; -import org.jboss.shrinkwrap.api.spec.WebArchive; -import org.junit.Test; - -import static org.junit.Assert.fail; - -public class InappropriateNestedServletInDeploymentTest extends - AbstractCDIIntegrationTest { - - @Deployment(name = "nestedServlet", managed = false, testable = false) - public static WebArchive alternativeAndActiveWithSamePath() { - return ArchiveProvider.createWebArchive("nestedServlet", - UIWithNestedServlet.class); - } - - /** - * Tests invalid deployment nested servlet within a UI class. Should be - * started first -- Arquillian deployments are not perfectly isolated. - */ - @Test(expected = Exception.class) - @InSequence(-2) - public void nestedServletBreaksDeployment() throws Exception { - deployer.deploy("nestedServlet"); - fail("Servlet class nested in the UI should not be deployable"); - } - -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/InjectionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/InjectionTest.java index e92ad800..0c2f9322 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/InjectionTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/InjectionTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.Conventions; @@ -13,6 +23,7 @@ import org.openqa.selenium.support.ui.WebDriverWait; import java.net.MalformedURLException; +import java.time.Duration; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; @@ -31,7 +42,7 @@ public static WebArchive alternativeAndActiveWithSamePath() { public void testUIInjection() throws MalformedURLException { openWindow(Conventions.deriveMappingForUI(InjectionUI.class)); - (new WebDriverWait(firstWindow, 15)).until(ExpectedConditions + (new WebDriverWait(firstWindow, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(By.id(InjectionUI.beanId1))); String bean11 = firstWindow.findElement(By.id(InjectionUI.beanId1)) @@ -43,7 +54,7 @@ public void testUIInjection() throws MalformedURLException { refreshWindow(); - (new WebDriverWait(firstWindow, 15)).until(ExpectedConditions + (new WebDriverWait(firstWindow, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(By.id(InjectionUI.beanId1))); String bean12 = firstWindow.findElement(By.id(InjectionUI.beanId1)) diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleAccessIsolationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleAccessIsolationTest.java index c29d1486..7d9ac46f 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleAccessIsolationTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleAccessIsolationTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.uis.ConcurrentUI; @@ -11,6 +21,7 @@ import org.openqa.selenium.support.ui.WebDriverWait; import java.io.IOException; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -45,7 +56,7 @@ public void testConcurrentAccess() throws IOException, firstWindow.getWindowHandles()); // wait for second window fully loads firstWindow.switchTo().window(handles.get(1)); - (new WebDriverWait(firstWindow, 15)).until(ExpectedConditions + (new WebDriverWait(firstWindow, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(LABEL)); firstWindow.switchTo().window(handles.get(0)); @@ -74,7 +85,7 @@ public void testConsecutiveAccess() throws IOException, assertThat(firstWindow.findElement(By.id(ConcurrentUI.COUNTER_LABEL)) .getText(), is("1")); firstWindow.navigate().refresh(); - (new WebDriverWait(firstWindow, 15)).until(ExpectedConditions + (new WebDriverWait(firstWindow, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(LABEL)); assertThat(firstWindow.findElement(By.id(ConcurrentUI.COUNTER_LABEL)) .getText(), is("0")); @@ -82,7 +93,7 @@ public void testConsecutiveAccess() throws IOException, @SuppressWarnings("unchecked") private void waitForNumberOfWindowsToEqual(final int numberOfWindows) { - (new WebDriverWait(firstWindow, 30)).until(new ExpectedCondition() { + (new WebDriverWait(firstWindow, Duration.ofSeconds(30))).until(new ExpectedCondition() { @Override public Object apply(Object input) { return firstWindow.getWindowHandles().size() == numberOfWindows; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleRootUIsTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleRootUIsTest.java index 6bc8239d..71854650 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleRootUIsTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleRootUIsTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi; import com.vaadin.cdi.uis.CustomMappingUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleSessionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleSessionTest.java index 3e3eab58..428b280c 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleSessionTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/MultipleSessionTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.Conventions; @@ -12,6 +22,7 @@ import org.openqa.selenium.support.ui.WebDriverWait; import java.net.MalformedURLException; +import java.time.Duration; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; @@ -30,7 +41,7 @@ public static WebArchive injectedBeanDependsOnSession() { public void injectedBeanDependsOnSessionTest() throws MalformedURLException { openWindow(Conventions.deriveMappingForUI(MultipleSessionUI.class)); - (new WebDriverWait(firstWindow, 15)).until(ExpectedConditions + (new WebDriverWait(firstWindow, Duration.ofSeconds(15))).until(ExpectedConditions .presenceOfElementLocated(By .id(MultipleSessionUI.MAINSESSION2_ID))); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/NonPassivatingBeanTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/NonPassivatingBeanTest.java index b4d0b9e1..cbc6c28b 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/NonPassivatingBeanTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/NonPassivatingBeanTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import static org.hamcrest.CoreMatchers.equalTo; @@ -13,7 +23,6 @@ import com.vaadin.cdi.internal.Conventions; import com.vaadin.cdi.internal.NonPassivatingBean; -import com.vaadin.cdi.internal.ViewScopedContext; import com.vaadin.cdi.uis.NonPassivatingUI; import com.vaadin.cdi.views.NonPassivatingContentView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/NoneTestCategory.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/NoneTestCategory.java new file mode 100644 index 00000000..c870a76d --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/NoneTestCategory.java @@ -0,0 +1,14 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +public interface NoneTestCategory { +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ProxiedClusteringTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ProxiedClusteringTest.java new file mode 100644 index 00000000..2f5a5afa --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ProxiedClusteringTest.java @@ -0,0 +1,171 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.ClusterIncTestLayout; +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.UIScopedIncUI; +import com.vaadin.cdi.uis.ViewScopedIncUI; +import io.undertow.Undertow; +import io.undertow.client.UndertowClient; +import io.undertow.server.handlers.ResponseCodeHandler; +import io.undertow.server.handlers.proxy.LoadBalancingProxyClient; +import io.undertow.server.handlers.proxy.ProxyHandler; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.OperateOnDeployment; +import org.jboss.arquillian.container.test.api.TargetsContainer; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.descriptor.api.Descriptors; +import org.jboss.shrinkwrap.descriptor.api.webapp31.WebAppDescriptor; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; + +import static org.junit.Assert.assertEquals; + +@Category(ClusterTestCategory.class) +public class ProxiedClusteringTest extends AbstractCDIIntegrationTest { + + @Deployment(name = "node1", testable = false) + @TargetsContainer("node-1") + public static WebArchive deployment1() { + return getArchive(); + } + + @Deployment(name = "node2", testable = false) + @TargetsContainer("node-2") + public static WebArchive deployment2() { + return getArchive(); + } + + @OperateOnDeployment("node1") + @ArquillianResource + private URL url1; + + @OperateOnDeployment("node2") + @ArquillianResource + private URL url2; + + private ReverseProxy proxy; + + public static WebArchive getArchive() { + WebArchive archive = ArchiveProvider.createWebArchive("clusterinctest", + UIScopedIncUI.class, ViewScopedIncUI.class, ClusterIncTestLayout.class); + WebAppDescriptor webAppDescriptor = Descriptors.create(WebAppDescriptor.class).distributable(); + archive.addAsWebInfResource(new StringAsset(webAppDescriptor.exportAsString()), + webAppDescriptor.getDescriptorName()); + return archive; + } + + @Before + public void setUp() throws Exception { + if (ReverseProxy.INSTANCE == null) { + ReverseProxy.INSTANCE = new ReverseProxy(url1, url2); + } + proxy = ReverseProxy.INSTANCE; + proxy.setSelectedHost(0); + } + + @AfterClass + public static void tearDownClass() { + ReverseProxy.INSTANCE.stop(); + } + + @Test + public void testUICounter() throws Exception { + String path = Conventions.deriveMappingForUI(UIScopedIncUI.class); + firstWindow.navigate().to(proxy.getUrl() + path); + waitForClient(); + + doCount(); + } + + @Test + public void testViewCounter() throws Exception { + String path = Conventions.deriveMappingForUI(ViewScopedIncUI.class); + firstWindow.navigate().to(proxy.getUrl() + path); + waitForClient(); + clickAndWait(ViewScopedIncUI.NAVBTN_ID); + + doCount(); + } + + private void doCount() { + String[] portsArr = new String[]{String.valueOf(url1.getPort()), String.valueOf(url2.getPort())}; + for (int i = 1; i < 5; i++) { + proxy.setSelectedHost( i % 2); + clickAndWait(ClusterIncTestLayout.INC_BUTTON_ID); + assertEquals(String.valueOf(i), findElement(ClusterIncTestLayout.NORMALVALUE_LABEL_ID).getText()); + assertEquals(String.valueOf(i), findElement(ClusterIncTestLayout.VALUE_LABEL_ID).getText()); + assertEquals(portsArr[proxy.getSelectedHost()], findElement(ClusterIncTestLayout.PORT_LABEL_ID).getText()); + } + } + + private static class ReverseProxy { + + static ReverseProxy INSTANCE; + + private int selectedHost = 0; + private final Undertow reverseProxy; + + private String contextRoot; + + public ReverseProxy(URL url1, URL url2) throws URISyntaxException, MalformedURLException { + LoadBalancingProxyClient loadBalancer = new LoadBalancingProxyClient( + UndertowClient.getInstance(), null, new HostSelectorImpl()); + loadBalancer + .addHost(new URL(url1.getProtocol(), url1.getHost(), url1.getPort(), "").toURI()) + .addHost(new URL(url2.getProtocol(), url2.getHost(), url2.getPort(), "").toURI()); + reverseProxy = Undertow.builder() + .addHttpListener(0, "localhost") + .setHandler(new ProxyHandler(loadBalancer, ResponseCodeHandler.HANDLE_404)) + .build(); + reverseProxy.start(); + assert url1.getPath() == url2.getPath(); + contextRoot = url1.getPath(); + } + + public void stop() { + reverseProxy.stop(); + } + + public int getSelectedHost() { + return selectedHost; + } + + public void setSelectedHost(int selectedHost) { + this.selectedHost = selectedHost; + } + + public String getUrl() { + int localPort = ((InetSocketAddress) reverseProxy.getListenerInfo().get(0).getAddress()).getPort(); + return "http://localhost:" + localPort + contextRoot; + } + + private class HostSelectorImpl implements LoadBalancingProxyClient.HostSelector { + @Override + public int selectHost(LoadBalancingProxyClient.Host[] availableHosts) { + return selectedHost; + } + + } + + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/QualifiedInjectionTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/QualifiedInjectionTest.java index 7714ac5e..e00bc33a 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/QualifiedInjectionTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/QualifiedInjectionTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.*; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/RootViewAtContextRootTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/RootViewAtContextRootTest.java index 33ba379e..617e0498 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/RootViewAtContextRootTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/RootViewAtContextRootTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.uis.ParameterizedNavigationUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedInstancesTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedInstancesTest.java index db92edb4..3372504e 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedInstancesTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedInstancesTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.UIScopedBean; @@ -26,8 +36,8 @@ public class ScopedInstancesTest extends AbstractManagedCDIIntegrationTest { public static WebArchive alternativeAndActiveWithSamePath() { return ArchiveProvider.createWebArchive("scopedNavigation", UIScopedView.class, AbstractScopedInstancesView.class, - AbstractNavigatableView.class, ViewScopedView.class, - NavigatableUI.class, UIScopedBean.class, ViewScopedBean.class); + AbstractNavigatableView.class, ViewScopedView.class, NavigatableUI.class, + UIScopedBean.class, ViewScopedBean.class); } @Test @@ -83,6 +93,7 @@ public void injectedInstancesInContexts() throws MalformedURLException { String secondViewScopedInViewScoped = getTextById(ViewScopedBean.ID); String secondUIScopedInViewScoped = getTextById(UIScopedBean.ID); + // Navigate back to the UIScoped view navigateToUIScoped(); @@ -95,10 +106,8 @@ public void injectedInstancesInContexts() throws MalformedURLException { assertThat(firstViewScopedInViewScoped, not(firstViewScopedInUIScoped)); assertThat(firstViewScopedInViewScoped, not(secondViewScopedInViewScoped)); - assertThat(firstViewScopedInViewScoped, - not(secondViewScopedInUIScoped)); - assertThat(secondViewScopedInViewScoped, - not(firstViewScopedInUIScoped)); + assertThat(firstViewScopedInViewScoped, not(secondViewScopedInUIScoped)); + assertThat(secondViewScopedInViewScoped, not(firstViewScopedInUIScoped)); assertThat(secondViewScopedInViewScoped, not(secondViewScopedInUIScoped)); assertThat(firstViewScopedInUIScoped, not(secondViewScopedInUIScoped)); @@ -115,15 +124,20 @@ public void injectedInstancesInContexts() throws MalformedURLException { @Test public void testCreationalContext() throws Exception { resetCounts(); - openWindow(deriveMappingForUI(NavigatableUI.class)); // ViewScoped view instance opens initially + openWindow(deriveMappingForUI(NavigatableUI.class)); + assertThat(getCount(ViewScopedView.DependentBean.DESTROY_COUNT), is(0)); + assertThat(getCount(UIScopedView.DependentBean.DESTROY_COUNT), is(0)); // Open UIScoped view instance navigateToUIScoped(); + // bean dependent to viewsoped view should be destroyed + assertThat(getCount(ViewScopedView.DependentBean.DESTROY_COUNT), is(1)); + assertThat(getCount(UIScopedView.DependentBean.DESTROY_COUNT), is(0)); // Navigate back to the ViewScoped view navigateToViewScoped(); - + // bean dependent to uiscoped view should not be destroyed assertThat(getCount(ViewScopedView.DependentBean.DESTROY_COUNT), is(1)); assertThat(getCount(UIScopedView.DependentBean.DESTROY_COUNT), is(0)); } @@ -133,18 +147,14 @@ private String getTextById(String id) { } private void navigateToUIScoped() { - firstWindow - .findElement( - By.id(AbstractScopedInstancesView.NAVIGATE_TO_UISCOPED)) - .click(); + firstWindow.findElement( + By.id(AbstractScopedInstancesView.NAVIGATE_TO_UISCOPED)).click(); waitForValue(By.id(UIScopedView.DESCRIPTION_LABEL), "UIScopedView"); } private void navigateToViewScoped() { - firstWindow - .findElement(By - .id(AbstractScopedInstancesView.NAVIGATE_TO_VIEWSCOPED)) - .click(); + firstWindow.findElement( + By.id(AbstractScopedInstancesView.NAVIGATE_TO_VIEWSCOPED)).click(); waitForValue(By.id(ViewScopedView.DESCRIPTION_LABEL), "ViewScopedView"); } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedProducerTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedProducerTest.java index 670d2a4e..42980d38 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedProducerTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ScopedProducerTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; import com.vaadin.cdi.internal.ProducedBean; @@ -9,6 +19,7 @@ import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -52,7 +63,7 @@ public void separateUIs() { @SuppressWarnings("unchecked") private void waitForNumberOfWindowsToEqual(final int numberOfWindows) { - (new WebDriverWait(firstWindow, 30)).until(new ExpectedCondition() { + (new WebDriverWait(firstWindow, Duration.ofSeconds(30))).until(new ExpectedCondition() { @Override public Object apply(Object input) { return firstWindow.getWindowHandles().size() == numberOfWindows; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionContextTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionContextTest.java new file mode 100644 index 00000000..9775a7a3 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionContextTest.java @@ -0,0 +1,75 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.SessionUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class SessionContextTest extends AbstractManagedCDIIntegrationTest { + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("sessionScope", + SessionUI.class); + } + + @Before + public void setUp() throws Exception { + resetCounts(); + String uri = Conventions.deriveMappingForUI(SessionUI.class); + openWindow(uri); + } + + @Test + public void testUIsAccessSameSession() throws Exception { + Assert.assertEquals("", findElement(SessionUI.VALUELABEL_ID).getText()); + clickAndWait(SessionUI.SETVALUEBTN_ID); + refreshWindow();//creates new UI + Assert.assertEquals(SessionUI.VALUE, findElement(SessionUI.VALUELABEL_ID).getText()); + } + + @Test + public void testVaadinSessionCloseDestroysSessionContext() throws Exception { + Assert.assertEquals(0, getCount(SessionUI.SessionScopedBean.DESTROY_COUNT)); + clickAndWait(SessionUI.INVALIDATEBTN_ID); + Assert.assertEquals(1, getCount(SessionUI.SessionScopedBean.DESTROY_COUNT)); + } + + @Test + public void testHttpSessionCloseDestroysSessionContext() throws Exception { + Assert.assertEquals(0, getCount(SessionUI.SessionScopedBean.DESTROY_COUNT)); + clickAndWait(SessionUI.HTTP_INVALIDATEBTN_ID); + Assert.assertEquals(1, getCount(SessionUI.SessionScopedBean.DESTROY_COUNT)); + } + + @Test + @Ignore + //ignored because it's slow, and expiration should be same as session close + public void testHttpSessionExpirationDestroysSessionContext() throws Exception { + Assert.assertEquals(0, getCount(SessionUI.SessionScopedBean.DESTROY_COUNT)); + clickAndWait(SessionUI.EXPIREBTN_ID); + boolean destroyed = false; + for (int i=0; i<60; i++) { + Thread.sleep(1000); + if (getCount(SessionUI.SessionScopedBean.DESTROY_COUNT) > 0) { + System.out.printf("session expired after %d seconds\n", i); + destroyed = true; + break; + } + } + Assert.assertTrue(destroyed); + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionReplicationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionReplicationTest.java new file mode 100644 index 00000000..c194d7a2 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/SessionReplicationTest.java @@ -0,0 +1,79 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.SessionReplicationUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.OperateOnDeployment; +import org.jboss.arquillian.container.test.api.TargetsContainer; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.jboss.shrinkwrap.descriptor.api.Descriptors; +import org.jboss.shrinkwrap.descriptor.api.webapp31.WebAppDescriptor; +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.net.URL; + +@Category(ClusterTestCategory.class) +public class SessionReplicationTest extends AbstractCDIIntegrationTest { + + @Deployment(name = "node1", testable = false) + @TargetsContainer("node-1") + public static WebArchive deployment1() { + return getArchive(); + } + + @Deployment(name = "node2", testable = false) + @TargetsContainer("node-2") + public static WebArchive deployment2() { + return getArchive(); + } + + @OperateOnDeployment("node1") + @ArquillianResource + private URL url1; + + @OperateOnDeployment("node2") + @ArquillianResource + private URL url2; + + public static WebArchive getArchive() { + WebArchive archive = ArchiveProvider.createWebArchive("replication", + SessionReplicationUI.class); + WebAppDescriptor webAppDescriptor = Descriptors.create(WebAppDescriptor.class).distributable(); + return archive.addAsWebInfResource(new StringAsset(webAppDescriptor.exportAsString()), + webAppDescriptor.getDescriptorName()); + } + + @Test + public void testSessionReplication() throws Exception { + String path = Conventions.deriveMappingForUI(SessionReplicationUI.class); + firstWindow.navigate().to(url1.toString() + path); + waitForClient(); + assertSessionLabelsEquals(""); + clickAndWait(SessionReplicationUI.SETVALUEBTN_ID); + + firstWindow.navigate().to(url2.toString() + path); + waitForClient(); + assertSessionLabelsEquals(SessionReplicationUI.VALUE); + } + + private void assertSessionLabelsEquals(String expected) { + Assert.assertEquals(expected, findElement(SessionReplicationUI.HTTPVALUELABEL_ID).getText()); + Assert.assertEquals(expected, findElement(SessionReplicationUI.VAADINVALUELABEL_ID).getText()); + Assert.assertEquals(expected, findElement(SessionReplicationUI.CDIVALUELABEL_ID).getText()); + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/UIDestroyTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/UIDestroyTest.java index faea91fe..78efcb83 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/UIDestroyTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/UIDestroyTest.java @@ -1,12 +1,21 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; -import com.vaadin.cdi.internal.AbstractVaadinContext; import com.vaadin.cdi.internal.Conventions; -import com.vaadin.cdi.uis.DestroyNormalUI; import com.vaadin.cdi.uis.DestroyUI; import com.vaadin.cdi.views.TestView; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; import org.junit.Test; import java.io.IOException; @@ -16,46 +25,39 @@ public class UIDestroyTest extends AbstractManagedCDIIntegrationTest { - private String uri; private String uiId; @Deployment(testable = false) public static WebArchive deployment() { - return ArchiveProvider.createWebArchive("uiDestroy", DestroyUI.class, - DestroyNormalUI.class, TestView.class); + return ArchiveProvider.createWebArchive("uiDestroy", + DestroyUI.class, + TestView.class); } - protected Class getUIClass() { - return DestroyUI.class; - } - - @Test - public void testViewChangeTriggersClosedUIDestroy() throws Exception { + @Before + public void setUp() throws IOException { resetCounts(); - uri = Conventions.deriveMappingForUI(getUIClass()); + String uri = Conventions.deriveMappingForUI(DestroyUI.class); openWindow(uri); uiId = findElement(DestroyUI.UIID_ID).getText(); assertDestroyCount(0); - // close first UI - clickAndWait(DestroyUI.CLOSE_BTN_ID); - - // open new UI - openWindow(uri); - assertDestroyCount(0); - - Thread.sleep(AbstractVaadinContext.CLEANUP_DELAY + 1); + } - // ViewChange event triggers a cleanup - clickAndWait(DestroyUI.NAVIGATE_BTN_ID); + @Test + public void testUiCloseTriggersDestroy() throws Exception { + clickAndWait(DestroyUI.CLOSE_BTN_ID); + assertDestroyCount(1); + } - // first UI cleaned up + @Test + public void testSessionCloseDestroysUIContext() throws Exception { + clickAndWait(DestroyUI.CLOSE_SESSION_BTN_ID); assertDestroyCount(1); } private void assertDestroyCount(int count) throws IOException { assertThat(getCount(DestroyUI.DESTROY_COUNT + uiId), is(count)); - assertThat(getCount(DestroyUI.UIScopedBean.DESTROY_COUNT + uiId), - is(count)); + assertThat(getCount(DestroyUI.UIScopedBean.DESTROY_COUNT + uiId), is(count)); } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/UINormalDestroyTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/UINormalDestroyTest.java deleted file mode 100644 index 9d59dc1e..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/UINormalDestroyTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.vaadin.cdi; - -import com.vaadin.cdi.uis.DestroyNormalUI; -import com.vaadin.cdi.uis.DestroyUI; - -public class UINormalDestroyTest extends UIDestroyTest { - @Override - protected Class getUIClass() { - return DestroyNormalUI.class; - } -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyNormalUITest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyNormalUITest.java deleted file mode 100644 index 61fd36ce..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyNormalUITest.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.vaadin.cdi; - -import com.vaadin.cdi.uis.DestroyViewNormalUI; -import com.vaadin.cdi.uis.DestroyViewUI; - -public class ViewDestroyNormalUITest extends ViewDestroyTest { - @Override - protected Class getUIClass() { - return DestroyViewNormalUI.class; - } -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyTest.java index 721d7a5c..1c9ec411 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewDestroyTest.java @@ -1,70 +1,79 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi; -import com.vaadin.cdi.internal.AbstractVaadinContext; import com.vaadin.cdi.internal.Conventions; -import com.vaadin.cdi.uis.DestroyViewNormalUI; import com.vaadin.cdi.uis.DestroyViewUI; import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Before; import org.junit.Test; import java.io.IOException; +import java.net.MalformedURLException; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; public class ViewDestroyTest extends AbstractManagedCDIIntegrationTest { - private String viewUri; + private String uiId; - @Deployment(name = "viewDestroy", testable = false) + @Deployment(testable = false) public static WebArchive deployment() { - return ArchiveProvider.createWebArchive("viewDestroy", - DestroyViewUI.class, DestroyViewNormalUI.class); + return ArchiveProvider.createWebArchive("viewDestroy", DestroyViewUI.class); } @Before public void setUp() throws Exception { resetCounts(); - viewUri = Conventions.deriveMappingForUI(getUIClass()) + "#!home"; - openWindow(viewUri); - assertViewDestroyCounts(0); - } - - protected Class getUIClass() { - return DestroyViewUI.class; } @Test - @OperateOnDeployment("viewDestroy") public void testViewDestroyOnUIDestroy() throws Exception { - clickAndWait(DestroyViewUI.CLOSE_BTN_ID); - openWindow(viewUri); + loadView(DestroyViewUI.VIEWSCOPED_VIEW); assertViewDestroyCounts(0); - clickAndWait(DestroyViewUI.CLOSE_BTN_ID); - Thread.sleep(AbstractVaadinContext.CLEANUP_DELAY + 1); - // open new UI. Navigating to home view on load triggers cleanup. - openWindow(viewUri); - - assertViewDestroyCounts(2); + clickAndWait(DestroyViewUI.CLOSE_BTN_ID); + assertViewDestroyCounts(1); } @Test - @OperateOnDeployment("viewDestroy") public void testViewChangeDestroysViewScope() throws Exception { - // ViewChange event triggers a cleanup - clickAndWait(DestroyViewUI.NAVIGATE_BTN_ID); + loadView(DestroyViewUI.VIEWSCOPED_VIEW); + assertViewDestroyCounts(0); + clickAndWait(DestroyViewUI.NAVIGATE_OTHER_BTN_ID); + assertViewDestroyCounts(1); + } + @Test + public void testChangeToNonCdiViewDestroysViewScope() throws Exception { + loadView(DestroyViewUI.VIEWSCOPED_VIEW); + assertViewDestroyCounts(0); + clickAndWait(DestroyViewUI.NAVIGATE_ERROR_BTN_ID); assertViewDestroyCounts(1); } private void assertViewDestroyCounts(int count) throws IOException { - assertThat(getCount(DestroyViewUI.VIEW_DESTROY_COUNT_KEY), is(count)); - assertThat(getCount(DestroyViewUI.VIEWBEAN_DESTROY_COUNT_KEY), - is(count)); + assertThat(getCount(DestroyViewUI.ViewScopedView.DESTROY_COUNT + uiId), is(count)); + assertThat(getCount(DestroyViewUI.ViewScopedBean.DESTROY_COUNT + uiId), is(count)); + } + + private void loadView(final String view) throws MalformedURLException { + // Navigate to about:blank first to ensure a full page reload + // (avoids issues when the same URL is loaded but the previous UI was closed) + firstWindow.navigate().to("about:blank"); + String viewUri = Conventions.deriveMappingForUI(DestroyViewUI.class) + "#!" + view; + openWindow(viewUri); + uiId = findElement(DestroyViewUI.UIID_ID).getText(); } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java new file mode 100644 index 00000000..340d7582 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java @@ -0,0 +1,118 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.ViewNavigationUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; +import org.junit.Test; + +import jakarta.enterprise.context.ContextNotActiveException; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class ViewNavigationTest extends AbstractManagedCDIIntegrationTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewNavigation", ViewNavigationUI.class); + } + + @Before + public void setUp() throws Exception { + String uri = Conventions.deriveMappingForUI(ViewNavigationUI.class); + openWindow(uri); + } + + @Test + public void testRevertedNavigationRevertsViewScope() throws Exception { + clickAndWait(ViewNavigationUI.REVERTED_NAV_BTN_ID); + assertBeanValue(ViewNavigationUI.DEFAULTVIEW_VALUE); + } + + @Test + public void testNavigationToOtherViewCreatesNewContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + assertBeanValue(ViewNavigationUI.SUCCESSVIEW_VALUE); + } + + @Test + public void testBeforeViewChangeFiredInOldContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + String value = findElement(ViewNavigationUI.BEFORE_VALUE_LABEL_ID).getText(); + assertEquals(ViewNavigationUI.DEFAULTVIEW_VALUE, value); + } + + @Test + public void testBeforeViewChangeWithoutOldViewThrowsContextNotActive() throws Exception { + // happens on opening root view, so need no navigation + String value = findElement(ViewNavigationUI.BEFORE_VALUE_LABEL_ID).getText(); + assertEquals(ContextNotActiveException.class.getSimpleName(), value); + } + + @Test + public void testAfterViewChangeFiredInNewContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + String value = findElement(ViewNavigationUI.AFTER_VALUE_LABEL_ID).getText(); + assertEquals(ViewNavigationUI.SUCCESSVIEW_VALUE, value); + } + + @Test + public void testAfterViewChangeCDIEventFiredInNewContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + String value = findElement(ViewNavigationUI.CDIAFTER_VALUE_LABEL_ID).getText(); + assertEquals(ViewNavigationUI.SUCCESSVIEW_VALUE, value); + } + + private void assertBeanValue(String expectedValue) { + String value = findElement(ViewNavigationUI.VALUE_LABEL_ID).getText(); + assertEquals(expectedValue, value); + } + + @Test + public void testBeforeLeaveFiredInOldContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + String value = findElement(ViewNavigationUI.BEFORE_LEAVE_VALUE_LABEL_ID).getText(); + assertEquals(ViewNavigationUI.DEFAULTVIEW_VALUE, value); + } + + @Test + public void testShowViewCalledInNewContext() throws Exception { + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + String value = findElement(ViewNavigationUI.SHOW_VIEW_VALUE_LABEL_ID).getText(); + assertEquals(ViewNavigationUI.SUCCESSVIEW_VALUE, value); + } + + @Test + public void testDelayedNavigationFindsInactiveOpeningContext() throws Exception { + resetCounts(); + clickAndWait(ViewNavigationUI.DELAY_NAV_BTN_ID); + assertBeanValue(ViewNavigationUI.DELAYVIEW_VALUE); + assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(0)); + + // navigation is delayed in DelayNavigationView.beforeLeave() + clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); + // target view is constructed + assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(1)); + // actual context remains active + assertBeanValue(ViewNavigationUI.DELAYVIEW_VALUE); + + // perform delayed navigation. The target view now belongs to the inactive opening context. + clickAndWait(ViewNavigationUI.DelayNavigationView.PREFORM_DELAYED_NAV_BTN_ID); + assertBeanValue(ViewNavigationUI.SUCCESSVIEW_VALUE); + assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(1)); + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategiesUiInitTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategiesUiInitTest.java new file mode 100644 index 00000000..8b8d28a6 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategiesUiInitTest.java @@ -0,0 +1,48 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.ViewStrategyInitUI; +import com.vaadin.cdi.uis.ViewStrategyUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ViewStrategiesUiInitTest extends AbstractManagedCDIIntegrationTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewStrategiesUiInit", ViewStrategyInitUI.class); + } + + @Before + public void setUp() throws Exception { + String viewUri = Conventions.deriveMappingForUI(ViewStrategyUI.class)+"#!home/p1"; + openWindow(viewUri); + } + + @Test + public void testViewNameStrategyHasRightStateAfterUiInit() throws Exception { + clickAndWait(ViewStrategyInitUI.VIEWNAME_BTN_ID); + final String result = findElement(ViewStrategyInitUI.OUTPUT_ID).getText(); + Assert.assertEquals("true", result); + } + + @Test + public void testViewNameAndParametersStrategyHasRightStateAfterUiInit() throws Exception { + clickAndWait(ViewStrategyInitUI.VIEWNAMEPARAMS_BTN_ID); + final String result = findElement(ViewStrategyInitUI.OUTPUT_ID).getText(); + Assert.assertEquals("true", result); + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyAlwaysTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyAlwaysTest.java new file mode 100644 index 00000000..10af48fe --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyAlwaysTest.java @@ -0,0 +1,72 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.uis.ViewStrategyUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; + +public class ViewStrategyAlwaysTest extends AbstractViewStrategyTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewStrategyAlways", ViewStrategyUI.class); + } + + @Test + public void testNavigationToSameViewAndParametersCreatesNewContext() throws Exception { + assertAfterNavigateToTestedViewContextCreated( + ViewStrategyUI.BYALWAYS + "/p1", + ViewStrategyUI.BYALWAYS + "/p1", + ",byalways:p1", + ",byalways:p1" + ); + } + + @Test + public void testNavigationToSameViewNoParametersCreatesNewContext() throws Exception { + assertAfterNavigateToTestedViewContextCreated( + ViewStrategyUI.BYALWAYS, + ViewStrategyUI.BYALWAYS, + ",byalways:", + ",byalways:" + ); + } + + @Test + public void testNavigationToSameViewDifferentParametersCreatesNewContext() throws Exception { + assertAfterNavigateToTestedViewContextCreated( + ViewStrategyUI.BYALWAYS + "/p1", + ViewStrategyUI.BYALWAYS + "/p2", + ",byalways:p1", + ",byalways:p2" + ); + } + + @Test + public void testNavigationToOtherViewCreatesNewContext() throws Exception { + assertAfterNavigateToOtherViewContextCreated( + ViewStrategyUI.BYALWAYS, + ",byalways:" + ); + } + + @Override + protected String getTestedViewDestroyCounter() { + return ViewStrategyUI.ByAlwaysView.DESTROY_COUNT; + } + + @Override + protected String getTestedViewConstructCounter() { + return ViewStrategyUI.ByAlwaysView.CONSTRUCT_COUNT; + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyCallTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyCallTest.java new file mode 100644 index 00000000..09ed704c --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyCallTest.java @@ -0,0 +1,104 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.internal.Conventions; +import com.vaadin.cdi.uis.ViewStrategyCallUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Before; +import org.junit.Test; + +import java.net.MalformedURLException; + +import static com.vaadin.cdi.uis.ViewStrategyCallUI.*; +import static org.junit.Assert.assertEquals; + +public class ViewStrategyCallTest extends AbstractManagedCDIIntegrationTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewStrategyCall", ViewStrategyCallUI.class); + } + + @Before + public void setUp() throws MalformedURLException { + String uri = Conventions.deriveMappingForUI(ViewStrategyCallUI.class); + openWindow(uri); + } + + @Test + public void testStrategyNotCalledWithoutViewContext() throws Exception { + // No need call navigateTo. First navigation already done + // to root view during initialization of UI. + assertStrategyNotCalled(); + } + + @Test + public void testRootViewWithParams() throws Exception { + navigateTo("/p1/p2"); + assertStrategyCalled("", "p1/p2"); + } + + @Test + public void testRootViewNoParams() throws Exception { + navigateTo(""); + assertStrategyCalled("", ""); + } + + @Test + public void testSameViewNoParams() throws Exception { + navigateTo(SAMEVIEW); + assertStrategyCalled(SAMEVIEW, ""); + } + + @Test + public void testSameViewWithParams() throws Exception { + navigateTo(SAMEVIEW + "/p1/p2"); + assertStrategyCalled(SAMEVIEW, "p1/p2"); + } + + @Test + public void testReturnTrueHoldContext() throws Exception { + navigateTo(SAMEVIEW); + // contextStrategy for root view returns true + String value = findElement(BEANVALUE_OUTPUT_ID).getText(); + assertEquals(BEANVALUE, value); + } + + @Test + public void testReturnFalseReleaseContext() throws Exception { + navigateTo(SAMEVIEW); + // Strategy of active context called. + // It is still the context opened on root view. + navigateTo(OTHERVIEW); + // strategy returns false for 'other' + String value = findElement(BEANVALUE_OUTPUT_ID).getText(); + assertEquals(UNDEFINED, value); + } + + private void navigateTo(String viewState) { + findElement(TARGETSTATE_ID).clear(); + findElement(TARGETSTATE_ID).sendKeys(viewState); + clickAndWait(NAVBTN_ID); + } + + private void assertStrategyNotCalled() { + assertStrategyCalled(UNDEFINED, UNDEFINED); + } + + private void assertStrategyCalled(String expectedViewName, String expectedParameters) { + String viewName = findElement(VIEWNAME_OUTPUT_ID).getText(); + String parameters = findElement(PARAMETERS_OUTPUT_ID).getText(); + assertEquals(expectedViewName, viewName); + assertEquals(expectedParameters, parameters); + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameAndParamsTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameAndParamsTest.java new file mode 100644 index 00000000..4f5d653b --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameAndParamsTest.java @@ -0,0 +1,70 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.uis.ViewStrategyUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; + +public class ViewStrategyViewNameAndParamsTest extends AbstractViewStrategyTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewStrategyViewNameAndParams", ViewStrategyUI.class); + } + + @Test + public void testNavigationToSameViewAndParametersNop() throws Exception { + assertNop( + ViewStrategyUI.BYVIEWNAMEPARAMS + "/p1", + ViewStrategyUI.BYVIEWNAMEPARAMS + "/p1", + ",byviewnameparams:p1" + ); + } + + @Test + public void testNavigationToSameViewNoParametersNop() throws Exception { + assertNop( + ViewStrategyUI.BYVIEWNAMEPARAMS, + ViewStrategyUI.BYVIEWNAMEPARAMS, + ",byviewnameparams:" + ); + } + + @Test + public void testNavigationToSameViewDifferentParametersCreatesNewContext() throws Exception { + assertAfterNavigateToTestedViewContextCreated( + ViewStrategyUI.BYVIEWNAMEPARAMS + "/p1", + ViewStrategyUI.BYVIEWNAMEPARAMS + "/p2", + ",byviewnameparams:p1", + ",byviewnameparams:p2" + ); + } + + @Test + public void testNavigationToOtherViewCreatesNewContext() throws Exception { + assertAfterNavigateToOtherViewContextCreated( + ViewStrategyUI.BYVIEWNAMEPARAMS, + ",byviewnameparams:" + ); + } + + @Override + protected String getTestedViewDestroyCounter() { + return ViewStrategyUI.ByViewNameAndParametersView.DESTROY_COUNT; + } + + @Override + protected String getTestedViewConstructCounter() { + return ViewStrategyUI.ByViewNameAndParametersView.CONSTRUCT_COUNT; + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameTest.java new file mode 100644 index 00000000..73563452 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewStrategyViewNameTest.java @@ -0,0 +1,74 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi; + +import com.vaadin.cdi.uis.ViewStrategyUI; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; + +public class ViewStrategyViewNameTest extends AbstractViewStrategyTest { + + @Deployment(testable = false) + public static WebArchive deployment() { + return ArchiveProvider.createWebArchive("viewStrategyViewName", ViewStrategyUI.class); + } + + @Test + public void testNavigationToSameViewAndParametersNop() throws Exception { + assertNop( + ViewStrategyUI.BYVIEWNAME + "/p1", + ViewStrategyUI.BYVIEWNAME + "/p1", + ",byviewname:p1" + ); + } + + @Test + public void testNavigationToSameViewNoParametersNop() throws Exception { + assertNop( + ViewStrategyUI.BYVIEWNAME, + ViewStrategyUI.BYVIEWNAME, + ",byviewname:" + ); + } + + @Test + public void testNavigationToSameViewDifferentParametersHoldsContext() throws Exception { + navigateTo(ViewStrategyUI.BYVIEWNAME + "/p1"); + assertConstructCounts(1); + assertDestroyCounts(0); + assertBeanValue(",byviewname:p1"); + + navigateTo(ViewStrategyUI.BYVIEWNAME + "/p2"); + // context hold + assertConstructCounts(1); + assertDestroyCounts(0); + // navigation happened - init called again + assertBeanValue(",byviewname:p1,byviewname:p2"); + } + + @Test + public void testNavigationToOtherViewCreatesNewContext() throws Exception { + assertAfterNavigateToOtherViewContextCreated( + ViewStrategyUI.BYVIEWNAME, + ",byviewname:" + ); + } + + protected String getTestedViewDestroyCounter() { + return ViewStrategyUI.ByViewNameView.DESTROY_COUNT; + } + + protected String getTestedViewConstructCounter() { + return ViewStrategyUI.ByViewNameView.CONSTRUCT_COUNT; + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Alpha.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Alpha.java index 408d23cb..ca51a956 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Alpha.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Alpha.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import static java.lang.annotation.ElementType.FIELD; @@ -9,7 +19,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Qualifier @Retention(RUNTIME) diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/AlphaBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/AlphaBean.java index 6fc577f0..f95ba180 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/AlphaBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/AlphaBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; @Alpha diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Beta.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Beta.java index 7e2bde12..20c3cff3 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Beta.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Beta.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import static java.lang.annotation.ElementType.FIELD; @@ -9,7 +19,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Qualifier @Retention(RUNTIME) diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/BetaBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/BetaBean.java index f17e655c..91ff6887 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/BetaBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/BetaBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; @Beta diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ClusterIncTestLayout.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ClusterIncTestLayout.java new file mode 100644 index 00000000..4d833e1e --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ClusterIncTestLayout.java @@ -0,0 +1,75 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import com.vaadin.server.VaadinService; +import com.vaadin.server.VaadinServletRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; + +import jakarta.servlet.http.HttpServletRequest; +import java.io.Serializable; + +public class ClusterIncTestLayout extends VerticalLayout { + + public static final String VALUE_LABEL_ID = "value"; + public static final String NORMALVALUE_LABEL_ID = "normalvalue"; + public static final String INC_BUTTON_ID = "incButton"; + public static final String PORT_LABEL_ID = "port"; + + private IncTestBean incTestBean; + private IncTestBean incNormalTestBean; + + public ClusterIncTestLayout() { + setSizeFull(); + + final Label valueLabel = new Label(); + valueLabel.setId(VALUE_LABEL_ID); + addComponent(valueLabel); + + final Label normalValueLabel = new Label(); + normalValueLabel.setId(NORMALVALUE_LABEL_ID); + addComponent(normalValueLabel); + + final Label portLabel = new Label(); + portLabel.setId(PORT_LABEL_ID); + addComponent(portLabel); + + Button incBtn = new Button("increment"); + incBtn.setId(INC_BUTTON_ID); + incBtn.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + valueLabel.setValue(String.valueOf(incTestBean.incrementAndGet())); + normalValueLabel.setValue(String.valueOf(incNormalTestBean.incrementAndGet())); + HttpServletRequest servletRequest = ((VaadinServletRequest) VaadinService.getCurrentRequest()) + .getHttpServletRequest(); + portLabel.setValue(String.valueOf(servletRequest.getLocalPort())); + } + }); + addComponent(incBtn); + } + + public void init(IncTestBean incTestBean, IncTestBean incNormalTestBean) { + this.incTestBean = incTestBean; + this.incNormalTestBean = incNormalTestBean; + } + + public static class IncTestBean implements Serializable { + int counter = 0; + + public int incrementAndGet() { + return ++counter; + } + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ConventionsTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ConventionsTest.java index c576dcde..76667b66 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ConventionsTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ConventionsTest.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.internal; import static com.vaadin.cdi.internal.Conventions.deriveMappingForUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Counter.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Counter.java index df9c63c4..3af1ab26 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Counter.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Counter.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; -import javax.enterprise.context.ApplicationScoped; +import jakarta.enterprise.context.ApplicationScoped; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CounterFilter.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CounterFilter.java index 698cd723..6b0610fe 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CounterFilter.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CounterFilter.java @@ -1,12 +1,22 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; -import javax.inject.Inject; -import javax.servlet.*; -import javax.servlet.annotation.WebFilter; +import jakarta.inject.Inject; +import jakarta.servlet.*; +import jakarta.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(urlPatterns = "/*", asyncSupported = true) -public class CounterFilter implements javax.servlet.Filter { +public class CounterFilter implements jakarta.servlet.Filter { @Inject Counter counter; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CrossInjectingBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CrossInjectingBean.java index 833990d9..efce24d5 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CrossInjectingBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/CrossInjectingBean.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.vaadin.cdi.NormalViewScoped; import com.vaadin.cdi.views.CrossInjectingView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/MyBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/MyBean.java index f58448b6..70f02c16 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/MyBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/MyBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import com.vaadin.cdi.NormalUIScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/NonPassivatingBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/NonPassivatingBean.java index e0408e79..5037d1dd 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/NonPassivatingBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/NonPassivatingBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import com.vaadin.cdi.ViewScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Preferred.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Preferred.java index 0cc3f828..b93108ae 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Preferred.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/Preferred.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import static java.lang.annotation.ElementType.FIELD; @@ -9,7 +19,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; -import javax.inject.Qualifier; +import jakarta.inject.Qualifier; @Qualifier @Retention(RUNTIME) diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ProducedBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ProducedBean.java index 2aa3a1be..8d4dd338 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ProducedBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ProducedBean.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; -import javax.enterprise.inject.Typed; +import jakarta.enterprise.inject.Typed; import java.util.concurrent.atomic.AtomicLong; @Typed() diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/UIScopedBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/UIScopedBean.java index 05b40a30..bc60f5ff 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/UIScopedBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/UIScopedBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import com.vaadin.cdi.NormalUIScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ViewScopedBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ViewScopedBean.java index 90a06154..91dab5a2 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ViewScopedBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/internal/ViewScopedBean.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.internal; import com.vaadin.cdi.NormalViewScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AbstractShiroTestView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AbstractShiroTestView.java index b3a8cc59..c8e4f03a 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AbstractShiroTestView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AbstractShiroTestView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; import com.vaadin.cdi.views.AbstractNavigatableView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AdminView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AdminView.java index eefc4364..2f3b45a1 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AdminView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/AdminView.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; -import javax.annotation.security.RolesAllowed; +import jakarta.annotation.security.RolesAllowed; import com.vaadin.cdi.CDIView; import com.vaadin.ui.Component; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/GuestView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/GuestView.java index d87913f4..0765109d 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/GuestView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/GuestView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/LoginPane.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/LoginPane.java index 84c3be8d..1e058a95 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/LoginPane.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/LoginPane.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; import org.apache.shiro.SecurityUtils; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroAccessControl.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroAccessControl.java index e3abd1e5..bf223a44 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroAccessControl.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroAccessControl.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; -import javax.enterprise.inject.Alternative; +import jakarta.enterprise.inject.Alternative; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; @@ -13,7 +23,7 @@ * This implementation does not provide any custom Shiro session manager or * security context. To use server push and link Shiro sessions to Vaadin * session rather than the HTTP session, see e.g. - * http://mikepilone.blogspot.fi/2013/07/vaadin-shiro-and-push.html . + * https://mikepilone.blogspot.fi/2013/07/vaadin-shiro-and-push.html . * * In this test, Shiro is initialized by ShiroWebListener using shiro.ini and * sessions are managed using ShiroWebFilter. diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroTest.java index c3660fac..c0a4f912 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroTest.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; import com.vaadin.cdi.AbstractManagedCDIIntegrationTest; @@ -12,6 +22,7 @@ import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage; import org.junit.Test; +import org.junit.Ignore; import org.openqa.selenium.By; import static org.hamcrest.CoreMatchers.not; @@ -20,24 +31,23 @@ /** * Simple test of Shiro access control. */ +@Ignore("Arquillian integration test - requires an application server container profile and browser") public class ShiroTest extends AbstractManagedCDIIntegrationTest { @Deployment(name = "shiro", testable = false) public static WebArchive initAndPostConstructAreConsistent() { - PomEquippedResolveStage pom = Maven.resolver().loadPomFromFile( - "pom.xml"); + PomEquippedResolveStage pom = Maven.resolver() + .loadPomFromFile("pom.xml"); return ArchiveProvider .createWebArchive("shiro", false, NavigatableUI.class, ShiroAccessControl.class, ShiroWebListener.class, ShiroWebFilter.class, AbstractNavigatableView.class, AbstractShiroTestView.class, LoginPane.class, GuestView.class, ViewerView.class, AdminView.class) - .addAsLibraries( - pom.resolve("org.apache.shiro:shiro-core:1.3.2") - .withTransitivity().asFile()) - .addAsLibraries( - pom.resolve("org.apache.shiro:shiro-web:1.3.2") - .withTransitivity().asFile()) + .addAsLibraries(pom.resolve("org.apache.shiro:shiro-core:1.3.2") + .withTransitivity().asFile()) + .addAsLibraries(pom.resolve("org.apache.shiro:shiro-web:1.3.2") + .withTransitivity().asFile()) .addAsWebInfResource(new ClassLoaderAsset("shiro.ini"), ArchivePaths.create("shiro.ini")) .addAsWebInfResource(new ClassLoaderAsset("shiro.beans.xml"), diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebFilter.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebFilter.java index d4e76a92..60780996 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebFilter.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebFilter.java @@ -1,7 +1,17 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; -import javax.servlet.DispatcherType; -import javax.servlet.annotation.WebFilter; +import jakarta.servlet.DispatcherType; +import jakarta.servlet.annotation.WebFilter; import org.apache.shiro.web.servlet.ShiroFilter; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebListener.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebListener.java index fa600dd4..939958d5 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebListener.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ShiroWebListener.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; -import javax.servlet.annotation.WebListener; +import jakarta.servlet.annotation.WebListener; import org.apache.shiro.web.env.EnvironmentLoaderListener; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ViewerView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ViewerView.java index 5b5ec359..3d11c77b 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ViewerView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/shiro/ViewerView.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.shiro; -import javax.annotation.security.RolesAllowed; +import jakarta.annotation.security.RolesAllowed; import com.vaadin.cdi.CDIView; import com.vaadin.ui.Component; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/AnotherPathCollisionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/AnotherPathCollisionUI.java index c6591137..9918e36a 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/AnotherPathCollisionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/AnotherPathCollisionUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/Boundary.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/Boundary.java index 81e9e8d3..d21f255e 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/Boundary.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/Boundary.java @@ -1,21 +1,16 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.uis; -import javax.ejb.Stateless; +import jakarta.ejb.Stateless; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUINotExtendingUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUINotExtendingUI.java new file mode 100644 index 00000000..1a51b75b --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUINotExtendingUI.java @@ -0,0 +1,18 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + + +import com.vaadin.cdi.CDIUI; + +@CDIUI +public class CDIUINotExtendingUI { +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUIWrongScope.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUIWrongScope.java new file mode 100644 index 00000000..328b5565 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CDIUIWrongScope.java @@ -0,0 +1,25 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.NormalUIScoped; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.UI; + +@CDIUI +@NormalUIScoped +public class CDIUIWrongScope extends UI { + @Override + protected void init(VaadinRequest request) { + + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConcurrentUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConcurrentUI.java index 0eba92bf..61cdb92f 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConcurrentUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConcurrentUI.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -10,8 +20,8 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI public class ConcurrentUI extends UI { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConflictingRootUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConflictingRootUI.java index e20c5d4b..00ec5d82 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConflictingRootUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConflictingRootUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConsistentInjectionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConsistentInjectionUI.java index 2aeac261..d229bc65 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConsistentInjectionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConsistentInjectionUI.java @@ -1,7 +1,17 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.internal.MyBean; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConventionalUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConventionalUI.java index 23ee0f5a..bf287252 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConventionalUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ConventionalUI.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CustomMappingUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CustomMappingUI.java index 444c3ea4..1dfafc65 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CustomMappingUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/CustomMappingUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -24,8 +18,8 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DanglingView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DanglingView.java index 9077ed30..26b93283 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DanglingView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DanglingView.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIView; @@ -24,8 +18,8 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DependentCDIEventListener.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DependentCDIEventListener.java index 5adbeb41..3c2c7104 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DependentCDIEventListener.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DependentCDIEventListener.java @@ -1,26 +1,20 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.internal.Counter; -import javax.annotation.PostConstruct; -import javax.enterprise.event.Observes; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; import java.io.Serializable; public class DependentCDIEventListener implements Serializable { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyNormalUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyNormalUI.java deleted file mode 100644 index 2ced495d..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyNormalUI.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.vaadin.cdi.uis; - -import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.NormalUIScoped; - -@CDIUI("normal") -@NormalUIScoped -public class DestroyNormalUI extends DestroyUI { -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyUI.java index d7c0aceb..1ca88d1b 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyUI.java @@ -1,41 +1,47 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.CDIViewProvider; import com.vaadin.cdi.UIScoped; import com.vaadin.cdi.internal.Counter; -import com.vaadin.cdi.internal.UIScopedBean; -import com.vaadin.navigator.Navigator; -import com.vaadin.navigator.View; -import com.vaadin.navigator.ViewDisplay; import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.inject.Inject; +import jakarta.annotation.PreDestroy; +import jakarta.inject.Inject; import java.io.Serializable; -import java.util.concurrent.atomic.AtomicInteger; @CDIUI("") public class DestroyUI extends UI { public static final String CLOSE_BTN_ID = "close"; + public static final String CLOSE_SESSION_BTN_ID = "close session"; public static final String NAVIGATE_BTN_ID = "navigate"; public static final String LABEL_ID = "label"; public static final String UIID_ID = "UIID"; public static final String DESTROY_COUNT = "uidestroycount"; @Inject - CDIViewProvider viewProvider; + CDINavigator navigator; @Inject - Counter counter; + UIScopedBean bean; @Inject - UIScopedBean bean; + Counter counter; @PreDestroy public void destroy() { @@ -60,28 +66,20 @@ protected void init(VaadinRequest request) { Button closeBtn = new Button("close UI"); closeBtn.setId(CLOSE_BTN_ID); - closeBtn.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(Button.ClickEvent event) { - close(); - } - }); + closeBtn.addClickListener(event -> close()); layout.addComponent(closeBtn); + Button closeSessionBtn = new Button("close Session"); + closeSessionBtn.setId(CLOSE_SESSION_BTN_ID); + closeSessionBtn.addClickListener(event -> VaadinSession.getCurrent().close()); + + layout.addComponent(closeSessionBtn); Button viewNavigateBtn = new Button("navigate"); viewNavigateBtn.setId(NAVIGATE_BTN_ID); - viewNavigateBtn.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(Button.ClickEvent event) { - final Navigator navigator = new Navigator(DestroyUI.this, - new ViewDisplay() { - @Override - public void showView(View view) { - } - }); - navigator.addProvider(viewProvider); - navigator.navigateTo("test"); - } + viewNavigateBtn.addClickListener(event -> { + navigator.init(DestroyUI.this, view -> { + }); + navigator.navigateTo("test"); }); layout.addComponent(viewNavigateBtn); @@ -106,4 +104,5 @@ public void setUiId(int uiId) { this.uiId = uiId; } } + } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewNormalUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewNormalUI.java deleted file mode 100644 index ff6c41e7..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewNormalUI.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.vaadin.cdi.uis; - -import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.NormalUIScoped; - -@CDIUI("normal") -@NormalUIScoped -public class DestroyViewNormalUI extends DestroyViewUI { -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewUI.java index 040bd315..b2dcf64e 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/DestroyViewUI.java @@ -1,31 +1,46 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import com.vaadin.cdi.*; +import com.vaadin.cdi.CDINavigator; +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.CDIView; +import com.vaadin.cdi.ViewScoped; import com.vaadin.cdi.internal.Counter; -import com.vaadin.navigator.Navigator; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener; -import com.vaadin.navigator.ViewDisplay; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PreDestroy; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.inject.Inject; import java.io.Serializable; @CDIUI("viewDestroy") public class DestroyViewUI extends UI { public static final String CLOSE_BTN_ID = "close"; public static final String LABEL_ID = "label"; - public static final String VIEW_DESTROY_COUNT_KEY = "viewcount"; - public static final String VIEWBEAN_DESTROY_COUNT_KEY = "viewbeancount"; - public static final String NAVIGATE_BTN_ID = "navigate"; + public static final String NAVIGATE_VIEW_BTN_ID = "navigateview"; + public static final String UIID_ID = "UIID"; + public static final String VIEWSCOPED_VIEW = "viewscoped"; + public static final String OTHER_VIEW = "other"; + public static final String NAVIGATE_ERROR_BTN_ID = "error"; + public static final String NAVIGATE_OTHER_BTN_ID = "other"; @Inject - CDIViewProvider viewProvider; + CDINavigator navigator; @Inject Counter counter; @@ -40,74 +55,93 @@ protected void init(VaadinRequest vaadinRequest) { label.setId(LABEL_ID); layout.addComponent(label); + final Label uiId = new Label(String.valueOf(getUIId())); + uiId.setId(UIID_ID); + layout.addComponent(uiId); + Button closeBtn = new Button("close UI"); closeBtn.setId(CLOSE_BTN_ID); - closeBtn.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(Button.ClickEvent event) { - close(); - } - }); + closeBtn.addClickListener(event -> close()); layout.addComponent(closeBtn); - final Navigator navigator = new Navigator(this, new ViewDisplay() { - @Override - public void showView(View view) { - } - }); - navigator.addProvider(viewProvider); - - Button viewNavigateBtn = new Button("navigate"); - viewNavigateBtn.setId(NAVIGATE_BTN_ID); - viewNavigateBtn.addClickListener(new Button.ClickListener() { - @Override - public void buttonClick(Button.ClickEvent event) { - navigator.navigateTo("other"); - } + navigator.init(this, view -> { }); + navigator.setErrorView(ErrorView.class); + + Button otherNavigateBtn = new Button("navigate other"); + otherNavigateBtn.setId(NAVIGATE_OTHER_BTN_ID); + otherNavigateBtn.addClickListener(event -> navigator.navigateTo(OTHER_VIEW)); + layout.addComponent(otherNavigateBtn); + + Button viewNavigateBtn = new Button("navigate view"); + viewNavigateBtn.setId(NAVIGATE_VIEW_BTN_ID); + viewNavigateBtn.addClickListener(event -> navigator.navigateTo(VIEWSCOPED_VIEW)); layout.addComponent(viewNavigateBtn); + Button errorNavigateBtn = new Button("navigate error"); + errorNavigateBtn.setId(NAVIGATE_ERROR_BTN_ID); + errorNavigateBtn.addClickListener(event -> navigator.navigateTo("nonexsistentview")); + layout.addComponent(errorNavigateBtn); + setContent(layout); } - @CDIView(value = "home") - public static class HomeView implements View { + @CDIView(value = VIEWSCOPED_VIEW) + public static class ViewScopedView implements View { + public static final String DESTROY_COUNT = "viewdestroy"; + @Inject ViewScopedBean viewScopedBean; @Inject Counter counter; + int uiId; + @PreDestroy public void destroy() { - counter.increment(VIEW_DESTROY_COUNT_KEY); + counter.increment(DESTROY_COUNT + uiId); } @Override public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) { + uiId = UI.getCurrent().getUIId(); + } + } + @CDIView(value = OTHER_VIEW) + public static class OtherView implements View { + @Override + public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) { } } @ViewScoped public static class ViewScopedBean implements Serializable { + public static final String DESTROY_COUNT = "viewbeandestroy"; + @Inject Counter counter; + int uiId; + @PreDestroy public void destroy() { - counter.increment(VIEWBEAN_DESTROY_COUNT_KEY); + counter.increment(DESTROY_COUNT + uiId); + } + + @PostConstruct + public void contruct() { + uiId = UI.getCurrent().getUIId(); } } - @CDIView("other") - public static class OtherView implements View { + public static class ErrorView implements View { @Override public void enter(ViewChangeListener.ViewChangeEvent event) { } } - } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseLabel.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseLabel.java index 1c505696..0a7bdb52 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseLabel.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseLabel.java @@ -1,23 +1,17 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; import com.vaadin.cdi.UIScoped; import com.vaadin.ui.Label; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseUI.java index f2584448..a820baf0 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/EnterpriseUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -24,8 +18,8 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI(value = "enterpriseUI") public class EnterpriseUI extends UI { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InjectionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InjectionUI.java index 871881d5..373ad423 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InjectionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InjectionUI.java @@ -1,7 +1,17 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.views.BeanView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedInterceptor.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedInterceptor.java index d5397552..b1852349 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedInterceptor.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedInterceptor.java @@ -1,26 +1,20 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.internal.Counter; -import javax.inject.Inject; -import javax.interceptor.AroundInvoke; -import javax.interceptor.InvocationContext; +import jakarta.inject.Inject; +import jakarta.interceptor.AroundInvoke; +import jakarta.interceptor.InvocationContext; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedUI.java index 7e5692a3..df22d620 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedUI.java @@ -1,49 +1,38 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.CDIViewProvider; import com.vaadin.cdi.internal.Counter; -import com.vaadin.navigator.Navigator; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI(value = "instrumentedUI") public class InstrumentedUI extends UI { public static final String CONSTRUCT_COUNT = "InstrumentedUIConstruct"; - @Inject - InstrumentedView view; @Inject - CDIViewProvider viewProvider; + CDINavigator navigator; @Inject Counter counter; - private Navigator navigator; - private int clickCount; @PostConstruct @@ -70,8 +59,7 @@ public void buttonClick(Button.ClickEvent clickEvent) { Button navigate = new Button("Navigate", new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { - navigator = new Navigator(InstrumentedUI.this, layout); - navigator.addProvider(viewProvider); + navigator.init(InstrumentedUI.this, layout); navigator.navigateTo("instrumentedView"); } }); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedView.java index 568eb989..55aebf22 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InstrumentedView.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIView; @@ -24,14 +18,12 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.context.Dependent; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; /** */ @CDIView(value = "instrumentedView") -@Dependent public class InstrumentedView extends CustomComponent implements View { public static final String CONSTRUCT_COUNT = "InstrumentedViewConstruct"; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedBean.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedBean.java index b820bc88..a023bfc5 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedBean.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedBean.java @@ -1,22 +1,16 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; -import javax.interceptor.Interceptors; +import jakarta.interceptor.Interceptors; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedUI.java index 9c2a3588..4be44df5 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/InterceptedUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -24,9 +18,9 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.event.Observes; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; @CDIUI(value = "interceptedUI") public class InterceptedUI extends UI { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/MultipleSessionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/MultipleSessionUI.java index 1d10fd62..36c2ea25 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/MultipleSessionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/MultipleSessionUI.java @@ -1,12 +1,15 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import java.util.Map; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; - import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.internal.MyBean; import com.vaadin.server.VaadinRequest; @@ -18,6 +21,12 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.util.CurrentInstance; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; +import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + @CDIUI("") public class MultipleSessionUI extends UI { @@ -49,7 +58,8 @@ public Lock getLockInstance() { Map, CurrentInstance> oldCurrentInstance = CurrentInstance .setCurrent(otherSession); otherSession.getLockInstance().lock(); - // proxy looks up actual bean based on session and UI ID + UI.setCurrent(this); + // proxy looks up actual bean based on current session and UI Label otherSessionLabel = new Label("" + bean.getBeanId()); otherSessionLabel.setId(OTHERSESSION_ID); layout.addComponent(otherSessionLabel); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NavigatableUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NavigatableUI.java index ae8fc901..da4eeb22 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NavigatableUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NavigatableUI.java @@ -1,26 +1,34 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.inject.Inject; - +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.CDIViewProvider; -import com.vaadin.navigator.Navigator; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.UI; +import jakarta.inject.Inject; + @CDIUI public class NavigatableUI extends UI { @Inject - CDIViewProvider viewProvider; - + CDINavigator navigator; + @Override protected void init(VaadinRequest request) { setSizeFull(); - Navigator navigator = new Navigator(NavigatableUI.this, this); - navigator.addProvider(viewProvider); + navigator.init(NavigatableUI.this, this); } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NoViewProviderNavigationUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NoViewProviderNavigationUI.java deleted file mode 100644 index fbe8a59a..00000000 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NoViewProviderNavigationUI.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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 com.vaadin.cdi.uis; - -import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.internal.Counter; -import com.vaadin.navigator.Navigator; -import com.vaadin.server.VaadinRequest; -import com.vaadin.ui.*; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; - -@CDIUI(value = "noViewProviderNavigationUI") -public class NoViewProviderNavigationUI extends UI { - - public static final String CONSTRUCT_COUNT = "NoViewProviderNavigationUIConstruct"; - public static final String NAVIGATION_COUNT = "NoViewProviderNavigationUINavigation"; - @Inject - InstrumentedView view; - @Inject - Counter counter; - - @PostConstruct - public void initialize() { - counter.increment(CONSTRUCT_COUNT); - } - - @Override - protected void init(VaadinRequest request) { - setSizeFull(); - - final VerticalLayout verticalLayout = new VerticalLayout(); - verticalLayout.setSizeFull(); - - final HorizontalLayout horizontalLayout = new HorizontalLayout(); - - final Label label = new Label("+NoViewProviderNavigationUI"); - label.setId("label"); - - Button navigate = new Button("Navigate", new Button.ClickListener() { - @Override - public void buttonClick(Button.ClickEvent clickEvent) { - counter.increment(NAVIGATION_COUNT); - Navigator navigator = new Navigator( - NoViewProviderNavigationUI.this, horizontalLayout); - navigator.addView("instrumentedView", view); - navigator.navigateTo("instrumentedView"); - } - }); - navigate.setId("navigate"); - verticalLayout.addComponent(label); - verticalLayout.addComponent(navigate); - verticalLayout.addComponent(horizontalLayout); - setContent(verticalLayout); - } - -} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NonPassivatingUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NonPassivatingUI.java index e1c78805..a28a7d1e 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NonPassivatingUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NonPassivatingUI.java @@ -1,22 +1,31 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.inject.Inject; - +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.CDIViewProvider; -import com.vaadin.navigator.Navigator; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.UI; +import jakarta.inject.Inject; + @CDIUI("") public class NonPassivatingUI extends UI { - @Inject CDIViewProvider provider; - + @Inject + CDINavigator navigator; + @Override protected void init(VaadinRequest request) { - Navigator navi = new Navigator(this,this); - navi.addProvider(provider); + navigator.init(this,this); } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NotExistingUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NotExistingUI.java index a3b9e33e..46b3b662 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NotExistingUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/NotExistingUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.server.VaadinRequest; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ParameterizedNavigationUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ParameterizedNavigationUI.java index f8e2b5a1..8a9fb99f 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ParameterizedNavigationUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ParameterizedNavigationUI.java @@ -1,40 +1,33 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; -import com.vaadin.cdi.CDIViewProvider; import com.vaadin.cdi.internal.Counter; -import com.vaadin.navigator.Navigator; import com.vaadin.server.VaadinRequest; import com.vaadin.ui.Button; import com.vaadin.ui.Label; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI(value = "parameterizedNavigationUI") public class ParameterizedNavigationUI extends UI { public static final String CONSTRUCT_COUNT = "ParameterizedNavigationUIConstruct"; @Inject - CDIViewProvider viewProvider; + CDINavigator navigator; @Inject Counter counter; @@ -57,9 +50,7 @@ protected void init(VaadinRequest request) { Button navigate = new Button("button", new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { - Navigator navigator = new Navigator( - ParameterizedNavigationUI.this, layout); - navigator.addProvider(viewProvider); + navigator.init(ParameterizedNavigationUI.this, layout); navigator.navigateTo(navigateTo); } }); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PathCollisionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PathCollisionUI.java index 0c4fae42..663d3b89 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PathCollisionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PathCollisionUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainAlternativeUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainAlternativeUI.java index 3cd787fd..f7876a75 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainAlternativeUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainAlternativeUI.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.uis; @@ -22,9 +17,9 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.inject.Alternative; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.inject.Alternative; +import jakarta.inject.Inject; @CDIUI(value = "plainAlternativeUI") @Alternative diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainColidingAlternativeUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainColidingAlternativeUI.java index 9961947e..4d77b860 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainColidingAlternativeUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainColidingAlternativeUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -23,9 +17,9 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.inject.Alternative; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.inject.Alternative; +import jakarta.inject.Inject; @Alternative @CDIUI("PlainUI") diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainUI.java index 291027de..7efd328b 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/PlainUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -23,8 +17,8 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI("PlainUI") public class PlainUI extends UI { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ProducerUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ProducerUI.java index e78b11b1..dc2a5f91 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ProducerUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ProducerUI.java @@ -1,8 +1,18 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.enterprise.context.SessionScoped; -import javax.enterprise.inject.Produces; -import javax.inject.Inject; +import jakarta.enterprise.context.SessionScoped; +import jakarta.enterprise.inject.Produces; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.NormalUIScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/QualifierInjectionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/QualifierInjectionUI.java index 31d6ad26..5b839dd1 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/QualifierInjectionUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/QualifierInjectionUI.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.internal.Alpha; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RestrictedView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RestrictedView.java index 6c9dd9c5..d3d37d54 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RestrictedView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RestrictedView.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIView; @@ -24,8 +18,8 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RootUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RootUI.java index 01574a58..ebbc1d2f 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RootUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/RootUI.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -23,8 +17,8 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; /** */ diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ScopedInstrumentedView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ScopedInstrumentedView.java index 33140818..840d1132 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ScopedInstrumentedView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ScopedInstrumentedView.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SecondUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SecondUI.java index 3c0ccda2..40b99638 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SecondUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SecondUI.java @@ -1,21 +1,16 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; +import com.vaadin.cdi.CDINavigator; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.CDIViewProvider; import com.vaadin.cdi.internal.Counter; @@ -26,20 +21,18 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI(value = "secondUI") public class SecondUI extends UI { public static final String CONSTRUCT_COUNT = "SecondUIConstruct"; - @Inject - CDIViewProvider viewProvider; - - private Navigator navigator; @Inject Counter counter; + @Inject + CDINavigator navigator; @PostConstruct public void initialize() { @@ -59,8 +52,7 @@ protected void init(VaadinRequest request) { Button navigate = new Button("button", new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent clickEvent) { - navigator = new Navigator(SecondUI.this, layout); - navigator.addProvider(viewProvider); + navigator.init(SecondUI.this, layout); navigator.navigateTo("danglingView"); } }); diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionReplicationUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionReplicationUI.java new file mode 100644 index 00000000..863bfdae --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionReplicationUI.java @@ -0,0 +1,89 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + + +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.VaadinSessionScoped; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +import jakarta.inject.Inject; +import java.io.Serializable; + +@CDIUI +public class SessionReplicationUI extends UI { + + public static final String SETVALUEBTN_ID = "setvalbtn"; + public static final String HTTPVALUELABEL_ID = "httplabel"; + public static final String VAADINVALUELABEL_ID = "vaadinlabel"; + public static final String CDIVALUELABEL_ID = "cdiLabel"; + public static final String VALUE = "session"; + + @Inject + VaadinSessionBean vaadinSessionBean; + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setSizeFull(); + + Button setBtn = new Button("set"); + setBtn.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + VaadinSession vaadinSession = VaadinSession.getCurrent(); + vaadinSession.setAttribute("test",VALUE); + vaadinSession.getSession().setAttribute("test",VALUE); + vaadinSessionBean.setValue(VALUE); + } + }); + + setBtn.setId(SETVALUEBTN_ID); + layout.addComponent(setBtn); + + Label vaadinLabel = new Label(); + vaadinLabel.setValue((String) VaadinSession.getCurrent().getAttribute("test")); + vaadinLabel.setId(VAADINVALUELABEL_ID); + layout.addComponent(vaadinLabel); + + Label httpLabel = new Label(); + httpLabel.setValue((String) VaadinSession.getCurrent().getSession().getAttribute("test")); + httpLabel.setId(HTTPVALUELABEL_ID); + layout.addComponent(httpLabel); + + Label cdiLabel = new Label(); + cdiLabel.setValue(vaadinSessionBean.getValue()); + cdiLabel.setId(CDIVALUELABEL_ID); + layout.addComponent(cdiLabel); + } + + @VaadinSessionScoped + public static class VaadinSessionBean implements Serializable { + private String value = ""; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionUI.java new file mode 100644 index 00000000..7a6899fe --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SessionUI.java @@ -0,0 +1,97 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + + +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.VaadinSessionScoped; +import com.vaadin.cdi.internal.Counter; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +import jakarta.annotation.PreDestroy; +import jakarta.inject.Inject; + +@CDIUI +public class SessionUI extends UI { + + public static final String SETVALUEBTN_ID = "setvalbtn"; + public static final String VALUELABEL_ID = "label"; + public static final String VALUE = "session"; + public static final String INVALIDATEBTN_ID = "invalidatebtn"; + public static final String HTTP_INVALIDATEBTN_ID = "httpinvalidatebtn"; + public static final String EXPIREBTN_ID = "expirebtn"; + + @Inject + SessionScopedBean sessionScopedBean; + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setSizeFull(); + + Button setBtn = new Button("set"); + setBtn.addClickListener(event -> sessionScopedBean.setValue(VALUE)); + setBtn.setId(SETVALUEBTN_ID); + layout.addComponent(setBtn); + + Button invalidateBtn = new Button("invalidate"); + invalidateBtn.addClickListener(event -> VaadinSession.getCurrent().close()); + invalidateBtn.setId(INVALIDATEBTN_ID); + layout.addComponent(invalidateBtn); + + Button httpInvalidateBtn = new Button("httpinvalidate"); + httpInvalidateBtn.addClickListener(event -> VaadinSession.getCurrent().getSession().invalidate()); + httpInvalidateBtn.setId(HTTP_INVALIDATEBTN_ID); + layout.addComponent(httpInvalidateBtn); + + Button expireBtn = new Button("httpexpire"); + expireBtn.addClickListener(event -> VaadinSession.getCurrent().getSession().setMaxInactiveInterval(1)); + expireBtn.setId(EXPIREBTN_ID); + layout.addComponent(expireBtn); + + Label label = new Label(); + label.setValue(sessionScopedBean.getValue()); // bean instantiated here + label.setId(VALUELABEL_ID); + layout.addComponent(label); + } + + @VaadinSessionScoped + //Like other vaadin scopes, + // Serializable is mandatory only if you want a working session serialization + public static class SessionScopedBean { + public static final String DESTROY_COUNT = "SessionScopedBeanDestroy"; + + @Inject + Counter counter; + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @PreDestroy + private void preDestroy() { + counter.increment(DESTROY_COUNT); + } + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SubUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SubUI.java index 0b732811..a3bab375 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SubUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/SubUI.java @@ -1,17 +1,12 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ package com.vaadin.cdi.uis; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/TestUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/TestUI.java index 66fdc5c4..5ac5b6bd 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/TestUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/TestUI.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIScopedIncUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIScopedIncUI.java new file mode 100644 index 00000000..a71dded7 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIScopedIncUI.java @@ -0,0 +1,49 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.NormalUIScoped; +import com.vaadin.cdi.UIScoped; +import com.vaadin.cdi.internal.ClusterIncTestLayout; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.UI; + +import jakarta.inject.Inject; + +@CDIUI("uiscoped") +public class UIScopedIncUI extends UI { + + @Inject + UIScopedBean uiScopedBean; + + @Inject + NormalUIScopedBean normalUIScopedBean; + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + ClusterIncTestLayout layout = new ClusterIncTestLayout(); + setContent(layout); + layout.setSizeFull(); + + layout.init(uiScopedBean, normalUIScopedBean); + } + + @UIScoped + public static class UIScopedBean extends ClusterIncTestLayout.IncTestBean { + } + + @NormalUIScoped + public static class NormalUIScopedBean extends ClusterIncTestLayout.IncTestBean { + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDIDependentListener.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDIDependentListener.java index 5069bc57..f0dda7b8 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDIDependentListener.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDIDependentListener.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -24,15 +18,15 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIUI(value = "uIWithCDIDependentListener") public class UIWithCDIDependentListener extends UI { public static final String CONSTRUCT_COUNT = "UIWithCDIDependentListenerConstruct"; @Inject - private javax.enterprise.event.Event events; + private jakarta.enterprise.event.Event events; @Inject Counter counter; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDISelfListener.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDISelfListener.java index 73e4a3a1..b36cc64a 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDISelfListener.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithCDISelfListener.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIUI; @@ -24,9 +18,9 @@ import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.event.Observes; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.event.Observes; +import jakarta.inject.Inject; @CDIUI(value = "uIWithCDISelfListener") public class UIWithCDISelfListener extends UI { @@ -37,7 +31,7 @@ public class UIWithCDISelfListener extends UI { public static final String MESSAGE_ID = "message"; @Inject - private javax.enterprise.event.Event events; + private jakarta.enterprise.event.Event events; @Inject Counter counter; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithNestedServlet.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithNestedServlet.java index 060cd502..b96319ad 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithNestedServlet.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UIWithNestedServlet.java @@ -1,6 +1,16 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.uis; -import javax.servlet.annotation.WebServlet; +import jakarta.servlet.annotation.WebServlet; import com.vaadin.annotations.VaadinServletConfiguration; import com.vaadin.cdi.CDIUI; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UnsecuredUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UnsecuredUI.java index 1fa339ff..a53f558b 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UnsecuredUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/UnsecuredUI.java @@ -1,22 +1,16 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIUI; import com.vaadin.cdi.access.AccessControl; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java new file mode 100644 index 00000000..bc8450c9 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java @@ -0,0 +1,217 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.*; +import com.vaadin.cdi.internal.Counter; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.*; + +import jakarta.annotation.PostConstruct; +import jakarta.enterprise.context.ContextNotActiveException; +import jakarta.inject.Inject; + +@CDIUI("") +public class ViewNavigationUI extends UI { + public static final String REVERTED_NAV_BTN_ID = "revertednavbtn"; + public static final String SUCCESS_NAV_BTN_ID = "successnavbtn"; + public static final String DELAY_NAV_BTN_ID = "delayednavbtn"; + public static final String VALUE_LABEL_ID = "valuelabel"; + public static final String DEFAULTVIEW_VALUE = "defaultview"; + private static final String LABEL_ID = "label"; + private static final String REVERTME = "revertme"; + private static final String SUCCESS = "success"; + private static final String DELAY = "delay"; + public static final String SUCCESSVIEW_VALUE = "successview"; + public static final String DELAYVIEW_VALUE = "delayview"; + public static final String BEFORE_VALUE_LABEL_ID = "beforevaluelabel"; + public static final String AFTER_VALUE_LABEL_ID = "aftervaluelabel"; + public static final String CDIAFTER_VALUE_LABEL_ID = "cdiaftervaluelabel"; + public static final String BEFORE_LEAVE_VALUE_LABEL_ID = "beforeleavevaluelabel"; + public static final String SHOW_VIEW_VALUE_LABEL_ID = "viewcomponentvaluelabel"; + + @Inject + CDINavigator navigator; + @Inject + ViewScopedBean bean; + private Label beforeLeaveValue; + private Label showViewValue; + private Label value; + private Label cdiAfterValue; + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + + final Label label = new Label("label"); + label.setId(LABEL_ID); + layout.addComponent(label); + + value = new Label(); + value.setId(VALUE_LABEL_ID); + layout.addComponent(value); + + final Label beforeValue = new Label(); + beforeValue.setId(BEFORE_VALUE_LABEL_ID); + layout.addComponent(beforeValue); + + beforeLeaveValue = new Label(); + beforeLeaveValue.setId(BEFORE_LEAVE_VALUE_LABEL_ID); + layout.addComponent(beforeLeaveValue); + + showViewValue = new Label(); + showViewValue.setId(SHOW_VIEW_VALUE_LABEL_ID); + layout.addComponent(showViewValue); + + final Label afterValue = new Label(); + afterValue.setId(AFTER_VALUE_LABEL_ID); + layout.addComponent(afterValue); + + cdiAfterValue = new Label(); + cdiAfterValue.setId(CDIAFTER_VALUE_LABEL_ID); + layout.addComponent(cdiAfterValue); + + final Panel viewDisplayPanel = new Panel(); + viewDisplayPanel.setContent(new Label()); + layout.addComponent(viewDisplayPanel); + + navigator.init(this, view -> { + showViewValue.setValue(bean.getValue()); + if (view instanceof Component) { + viewDisplayPanel.setContent((Component) view); + } + }); + + navigator.addViewChangeListener(new ViewChangeListener() { + @Override + public boolean beforeViewChange(ViewChangeEvent event) { + if (event.getViewName().equals(REVERTME)) { + return false; + } else { + if (event.getOldView() != null) { + beforeValue.setValue(bean.getValue()); + } else { + // given no oldView, we have no view context during beforeViewChange + try { + bean.getValue(); + } catch (ContextNotActiveException e) { + beforeValue.setValue(e.getClass().getSimpleName()); + } + } + return true; + } + } + + @Override + public void afterViewChange(ViewChangeEvent event) { + afterValue.setValue(bean.getValue()); + } + }); + + createNavBtn(layout, REVERTED_NAV_BTN_ID, REVERTME); + createNavBtn(layout, SUCCESS_NAV_BTN_ID, SUCCESS); + createNavBtn(layout, DELAY_NAV_BTN_ID, DELAY); + + setContent(layout); + } + + private void createNavBtn(VerticalLayout layout, String navBtnId, String targetView) { + Button navigateBtn = new Button(navBtnId); + navigateBtn.setId(navBtnId); + navigateBtn.addClickListener(event -> { + navigator.navigateTo(targetView); + value.setValue(bean.getValue()); + }); + layout.addComponent(navigateBtn); + } + + @CDIView("") + public static class DefaultView implements View { + @Inject + ViewScopedBean bean; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.setValue(DEFAULTVIEW_VALUE); + } + } + + @CDIView(REVERTME) + public static class RevertMeView implements View { + @Inject + ViewScopedBean bean; + + + @PostConstruct + private void init() { + bean.setValue("revertedview"); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + throw new IllegalStateException("Should never happen"); + } + } + + @CDIView(SUCCESS) + public static class SuccessView implements View { + @Inject + ViewScopedBean bean; + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "successconstructcount"; + + @PostConstruct + private void init() { + bean.setValue(SUCCESSVIEW_VALUE); + counter.increment(CONSTRUCT_COUNT); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + } + } + + @CDIView(DELAY) + public static class DelayNavigationView extends VerticalLayout implements View { + @Inject + ViewScopedBean bean; + Button performDelayedNavBtn; + public static final String PREFORM_DELAYED_NAV_BTN_ID = "performDelayedNavBtn"; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.setValue(DELAYVIEW_VALUE); + performDelayedNavBtn = new Button(PREFORM_DELAYED_NAV_BTN_ID); + performDelayedNavBtn.setId(PREFORM_DELAYED_NAV_BTN_ID); + addComponent(performDelayedNavBtn); + } + } + + @NormalViewScoped + public static class ViewScopedBean { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewScopedIncUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewScopedIncUI.java new file mode 100644 index 00000000..21a91ceb --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewScopedIncUI.java @@ -0,0 +1,82 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.*; +import com.vaadin.cdi.internal.ClusterIncTestLayout; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +import jakarta.inject.Inject; + +@CDIUI("viewscoped") +public class ViewScopedIncUI extends UI { + + public static final String NAVBTN_ID = "navigateBtn"; + + @Inject + CDINavigator navigator; + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setSizeFull(); + + navigator.init(this, layout); + } + + @CDIView("") + public static class RootView extends VerticalLayout implements View { + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + Button navBtn = new Button("navigate"); + navBtn.setId(NAVBTN_ID); + navBtn.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + getUI().getNavigator().navigateTo("increment"); + } + }); + addComponent(navBtn); + } + } + + @CDIView + public static class IncrementView extends ClusterIncTestLayout implements View { + + @Inject + IncrementBean incrementBean; + @Inject + NormalIncrementBean normalIncrementBean; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + init(incrementBean, normalIncrementBean); + } + + } + + @ViewScoped + public static class IncrementBean extends ClusterIncTestLayout.IncTestBean { + } + + @NormalViewScoped + public static class NormalIncrementBean extends ClusterIncTestLayout.IncTestBean { + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyCallUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyCallUI.java new file mode 100644 index 00000000..d26784ac --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyCallUI.java @@ -0,0 +1,148 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.*; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategy; +import com.vaadin.cdi.viewcontextstrategy.ViewContextStrategyQualifier; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.*; + +import jakarta.inject.Inject; +import java.lang.annotation.*; +import java.util.Objects; + +@CDIUI("") +public class ViewStrategyCallUI extends UI { + public static final String VIEWNAME_OUTPUT_ID = "viewnameid"; + public static final String PARAMETERS_OUTPUT_ID = "parametersid"; + public static final String BEANVALUE_OUTPUT_ID = "beanvalueid"; + public static final String TARGETSTATE_ID = "targetstate"; + public static final String NAVBTN_ID = "navbtn"; + public static final String BEANVALUE = "beanvalue"; + public static final String UNDEFINED = "undefined"; + public static final String SAMEVIEW = "same"; + public static final String OTHERVIEW = "other"; + + @Inject + CDINavigator navigator; + private Label viewName; + private Label parameters; + private Label beanValue; + + @Override + protected void init(VaadinRequest request) { + navigator.init(this, view -> { + }); + + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + setContent(layout); + + final Label label = new Label("label"); + label.setId("label"); + layout.addComponent(label); + + viewName = new Label(); + viewName.setId(VIEWNAME_OUTPUT_ID); + viewName.setValue(UNDEFINED); + layout.addComponent(viewName); + + parameters = new Label(); + parameters.setId(PARAMETERS_OUTPUT_ID); + parameters.setValue(UNDEFINED); + layout.addComponent(parameters); + + beanValue = new Label(); + beanValue.setId(BEANVALUE_OUTPUT_ID); + beanValue.setValue(UNDEFINED); + layout.addComponent(beanValue); + + final TextField targetState = new TextField(); + targetState.setId(TARGETSTATE_ID); + layout.addComponent(targetState); + + final Button navBtn = new Button("navigate", + event -> navigator.navigateTo(targetState.getValue())); + navBtn.setId(NAVBTN_ID); + layout.addComponent(navBtn); + } + + @CDIView(value = SAMEVIEW) + public static class SameView implements View { + @Inject + ViewScopedBean bean; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + final ViewStrategyCallUI ui = (ViewStrategyCallUI) UI.getCurrent(); + ui.beanValue.setValue(bean.getValue()); + } + } + + @CDIView(value = OTHERVIEW) + public static class OtherView implements View { + @Inject + ViewScopedBean bean; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + final ViewStrategyCallUI ui = (ViewStrategyCallUI) UI.getCurrent(); + ui.beanValue.setValue(bean.getValue()); + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target({ ElementType.TYPE }) + @Inherited + @ViewContextStrategyQualifier + public @interface TestContextStrategy { + } + + @CDIView(value = "") + @TestContextStrategy + public static class RootView implements View { + @Inject + ViewScopedBean bean; + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.setValue(BEANVALUE); + } + } + + @TestContextStrategy + public static class TestStrategy implements ViewContextStrategy { + @Override + public boolean inCurrentContext(String viewName, String parameters) { + final ViewStrategyCallUI ui = (ViewStrategyCallUI) UI.getCurrent(); + ui.viewName.setValue(viewName); + ui.parameters.setValue(parameters); + return !Objects.equals(viewName, OTHERVIEW); + } + } + + @NormalViewScoped + public static class ViewScopedBean { + private String value = UNDEFINED; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyInitUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyInitUI.java new file mode 100644 index 00000000..6fe2318a --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyInitUI.java @@ -0,0 +1,83 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.CDINavigator; +import com.vaadin.cdi.CDIUI; +import com.vaadin.cdi.CDIView; +import com.vaadin.cdi.internal.ViewContextStrategies; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +import jakarta.inject.Inject; + +@CDIUI("") +public class ViewStrategyInitUI extends UI { + private static final String LABEL_ID = "label"; + public static final String OUTPUT_ID = "output"; + public static final String VIEWNAME_BTN_ID = "viewname"; + public static final String VIEWNAMEPARAMS_BTN_ID = "viewnameparams"; + + @Inject + ViewContextStrategies.ViewName viewName; + + @Inject + ViewContextStrategies.ViewNameAndParameters viewNameAndParameters; + + @Inject + CDINavigator navigator; + + @Override + protected void init(VaadinRequest request) { + navigator.init(this, view -> { }); + + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + + final Label label = new Label("label"); + label.setId(LABEL_ID); + layout.addComponent(label); + + final Label output = new Label(); + output.setId(OUTPUT_ID); + layout.addComponent(output); + + final Button viewNameBtn = new Button("viewname", event -> { + final boolean contains = viewName.inCurrentContext("home", "p2"); + output.setValue(String.valueOf(contains)); + }); + viewNameBtn.setId(VIEWNAME_BTN_ID); + layout.addComponent(viewNameBtn); + + final Button viewNameParamsBtn = new Button("viewnameparams", event -> { + final boolean contains = viewNameAndParameters.inCurrentContext("home", "p1"); + output.setValue(String.valueOf(contains)); + }); + + viewNameParamsBtn.setId(VIEWNAMEPARAMS_BTN_ID); + layout.addComponent(viewNameParamsBtn); + + setContent(layout); + } + + @CDIView(value = "home") + public static class HomeView implements View { + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + } + } + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyUI.java new file mode 100644 index 00000000..9163c468 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewStrategyUI.java @@ -0,0 +1,224 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.uis; + +import com.vaadin.cdi.*; +import com.vaadin.cdi.internal.Counter; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNavigation; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByNameAndParameters; +import com.vaadin.cdi.viewcontextstrategy.ViewContextByName; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.*; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; +import jakarta.inject.Inject; + +@CDIUI("") +public class ViewStrategyUI extends UI { + public static final String BYVIEWNAME = "byviewname"; + public static final String BYVIEWNAMEPARAMS = "byviewnameparams"; + public static final String BYALWAYS = "byalways"; + public static final String OTHER = "other"; + + public static final String TARGETSTATE_ID = "targetstate"; + public static final String NAVBTN_ID = "navbtn"; + + public static final String VALUE_LABEL_ID = "valuelabel"; + private static final String LABEL_ID = "label"; + + @Inject + CDINavigator navigator; + @Inject + ViewScopedBean bean; + private Label value; + + + @Override + protected void init(VaadinRequest request) { + setSizeFull(); + + VerticalLayout layout = new VerticalLayout(); + layout.setSizeFull(); + + final Label label = new Label("label"); + label.setId(LABEL_ID); + layout.addComponent(label); + + value = new Label(); + value.setId(VALUE_LABEL_ID); + layout.addComponent(value); + + final Panel viewDisplayPanel = new Panel(); + viewDisplayPanel.setContent(new Label()); + layout.addComponent(viewDisplayPanel); + + navigator.init(this, view -> { + }); + + final TextField targetState = new TextField(); + targetState.setId(TARGETSTATE_ID); + layout.addComponent(targetState); + + final Button navBtn = new Button("navigate", + event -> { + navigator.navigateTo(targetState.getValue()); + value.setValue(bean.getValue()); + }); + navBtn.setId(NAVBTN_ID); + layout.addComponent(navBtn); + + setContent(layout); + } + + @CDIView("") + public static class DefaultView implements View { + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + } + } + + @CDIView(value = BYVIEWNAME) + @ViewContextByName + public static class ByViewNameView implements View { + @Inject + ViewScopedBean bean; + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "viewnameconstructcount"; + public static String DESTROY_COUNT = "viewnamedestroycount"; + + @PostConstruct + private void init() { + counter.increment(CONSTRUCT_COUNT); + } + + @PreDestroy + private void destroy() { + counter.increment(DESTROY_COUNT); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.enter(event); + } + } + + @CDIView(value = BYVIEWNAMEPARAMS) + @ViewContextByNameAndParameters + public static class ByViewNameAndParametersView implements View { + @Inject + ViewScopedBean bean; + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "viewnameparamsconstructcount"; + public static String DESTROY_COUNT = "viewnameparamsdestroycount"; + + @PostConstruct + private void init() { + counter.increment(CONSTRUCT_COUNT); + } + + @PreDestroy + private void destroy() { + counter.increment(DESTROY_COUNT); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.enter(event); + } + } + + @CDIView(value = BYALWAYS) + @ViewContextByNavigation + public static class ByAlwaysView implements View { + @Inject + ViewScopedBean bean; + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "alwaysconstructcount"; + public static String DESTROY_COUNT = "alwaysdestroycount"; + + @PostConstruct + private void init() { + counter.increment(CONSTRUCT_COUNT); + } + + @PreDestroy + private void destroy() { + counter.increment(DESTROY_COUNT); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.enter(event); + } + } + + @CDIView(value = OTHER) + public static class OtherView implements View { + @Inject + ViewScopedBean bean; + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "otherconstructcount"; + public static String DESTROY_COUNT = "otherdestroycount"; + + @PostConstruct + private void init() { + counter.increment(CONSTRUCT_COUNT); + } + + @PreDestroy + private void destroy() { + counter.increment(DESTROY_COUNT); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + bean.enter(event); + } + } + + + @NormalViewScoped + public static class ViewScopedBean { + @Inject + Counter counter; + public static String CONSTRUCT_COUNT = "beanconstructcount"; + public static String DESTROY_COUNT = "beandestroycount"; + + @PostConstruct + private void init() { + counter.increment(CONSTRUCT_COUNT); + } + + @PreDestroy + private void destroy() { + counter.increment(DESTROY_COUNT); + } + + private String value = ""; + + public String getValue() { + return value; + } + + public void enter(ViewChangeListener.ViewChangeEvent event) { + value = value + "," + event.getViewName() + ":" + event.getParameters(); + } + } + + +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewWithoutAnnotation.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewWithoutAnnotation.java index 8919ba97..23fe204e 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewWithoutAnnotation.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewWithoutAnnotation.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.navigator.View; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/WithAnnotationRegisteredView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/WithAnnotationRegisteredView.java index 0c3fb2dc..58c5acd6 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/WithAnnotationRegisteredView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/WithAnnotationRegisteredView.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.uis; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractNavigatableView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractNavigatableView.java index 2b51c486..de854b47 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractNavigatableView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractNavigatableView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.navigator.View; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractScopedInstancesView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractScopedInstancesView.java index c01639e0..b96f52c0 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractScopedInstancesView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/AbstractScopedInstancesView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.navigator.View; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/BeanView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/BeanView.java index 36644f6c..b3ad0d11 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/BeanView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/BeanView.java @@ -1,7 +1,17 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; import com.vaadin.cdi.internal.MyBean; import com.vaadin.ui.Label; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewDependent.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewDependent.java new file mode 100644 index 00000000..0621f1a5 --- /dev/null +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewDependent.java @@ -0,0 +1,27 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.views; + +import com.vaadin.cdi.CDIView; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; + +import jakarta.enterprise.context.Dependent; + +@CDIView("viewDependent") +@Dependent +public class CDIViewDependent implements View { + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + + } +} diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewNotImplementingView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewNotImplementingView.java index 9f4d77a3..23969c24 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewNotImplementingView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CDIViewNotImplementingView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ConventionalView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ConventionalView.java index e66b095e..811766f1 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ConventionalView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ConventionalView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; @@ -9,12 +19,10 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.enterprise.context.Dependent; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIView(uis = { ParameterizedNavigationUI.class }) -@Dependent public class ConventionalView extends CustomComponent implements View { public static final String CONSTRUCT_COUNT = "ConventionalViewConstruct"; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CrossInjectingView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CrossInjectingView.java index d05acb47..91b4f171 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CrossInjectingView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/CrossInjectingView.java @@ -1,8 +1,18 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import java.util.concurrent.atomic.AtomicLong; -import javax.inject.Inject; +import jakarta.inject.Inject; import com.vaadin.cdi.CDIView; import com.vaadin.cdi.NormalViewScoped; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/MainView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/MainView.java index f4ccc107..db886d30 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/MainView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/MainView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; import com.vaadin.ui.Component; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/NonPassivatingContentView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/NonPassivatingContentView.java index 83913d5d..7a632414 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/NonPassivatingContentView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/NonPassivatingContentView.java @@ -1,25 +1,32 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; -import java.util.HashSet; -import java.util.Set; - -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; -import javax.inject.Inject; - import com.vaadin.cdi.CDIView; import com.vaadin.cdi.ViewScoped; -import com.vaadin.cdi.internal.CDIUtil; import com.vaadin.cdi.internal.NonPassivatingBean; import com.vaadin.cdi.internal.ViewScopedContext; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Label; -import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; +import jakarta.enterprise.context.spi.CreationalContext; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.inject.Inject; +import java.util.HashSet; +import java.util.Set; + @CDIView("") public class NonPassivatingContentView extends CustomComponent implements View { @@ -44,8 +51,9 @@ public void enter(ViewChangeEvent event) { Label label = new Label(bean.getSomeString()); label.setId(label_id); - - ViewScopedContext context = new InitializedViewScopedContext(bm); + + ViewScopedContext context = new ViewScopedContext(bm); + context.init(bm); // A dummy CreationalContext to avoid using CDI implementation specific // classes @@ -79,16 +87,6 @@ public void release() { } - private static class InitializedViewScopedContext extends ViewScopedContext { - public InitializedViewScopedContext(BeanManager bm) { - super(bm); - // a hack to simulate a view change event - SessionData sessionData = getSessionData(CDIUtil.getSessionId(), true); - SessionData.UIData uiData = sessionData.getUIData(UI.getCurrent().getUIId(), true); - uiData.setOpeningView(""); - } - } - /** * A custom CDI Bean implementation that does not implement * PassivationCapable. @@ -105,17 +103,17 @@ public void destroy(Object instance, CreationalContext context) { } @Override - public Set getTypes() { + public Set getTypes() { return null; } @Override - public Set getQualifiers() { - return new HashSet(); + public Set getQualifiers() { + return new HashSet<>(); } @Override - public Class getScope() { + public Class getScope() { return ViewScoped.class; } @@ -125,23 +123,18 @@ public String getName() { } @Override - public boolean isNullable() { - return false; - } - - @Override - public Set getInjectionPoints() { - return new HashSet(); + public Set getInjectionPoints() { + return new HashSet<>(); } @Override - public Class getBeanClass() { + public Class getBeanClass() { return Object.class; } @Override - public Set getStereotypes() { - return new HashSet(); + public Set getStereotypes() { + return new HashSet<>(); } @Override diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithPath.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithPath.java index fa10c9ca..f1a120de 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithPath.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithPath.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPath.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPath.java index 10a20426..fd5bd87d 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPath.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPath.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPathAndAnnotation.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPathAndAnnotation.java index fef5401b..42c65735 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPathAndAnnotation.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/OneAndOnlyViewWithoutPathAndAnnotation.java @@ -1,19 +1,13 @@ /* - * Copyright 2000-2013 Vaadin Ltd. - * - * Licensed 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. + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. */ - package com.vaadin.cdi.views; import com.vaadin.navigator.View; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/RootView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/RootView.java index 3ba15f73..f6d2d173 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/RootView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/RootView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; @@ -8,8 +18,8 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; -import javax.annotation.PostConstruct; -import javax.inject.Inject; +import jakarta.annotation.PostConstruct; +import jakarta.inject.Inject; @CDIView("") public class RootView extends CustomComponent implements View { diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/SubView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/SubView.java index 19dc83d5..8046c3d9 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/SubView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/SubView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; import com.vaadin.ui.Component; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/TestView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/TestView.java index fd1f01ca..529305a2 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/TestView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/TestView.java @@ -1,3 +1,13 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; import com.vaadin.cdi.CDIView; diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/UIScopedView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/UIScopedView.java index 8a0f8478..ecd63984 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/UIScopedView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/UIScopedView.java @@ -1,9 +1,15 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; -import javax.annotation.PreDestroy; -import javax.enterprise.context.Dependent; -import javax.inject.Inject; - import com.vaadin.cdi.CDIView; import com.vaadin.cdi.UIScoped; import com.vaadin.cdi.internal.Counter; @@ -17,6 +23,10 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; + @UIScoped @CDIView(value = AbstractScopedInstancesView.UISCOPED_VIEW) public class UIScopedView extends AbstractScopedInstancesView implements View { @@ -46,13 +56,13 @@ protected Component buildContent() { instanceLabel.setId(INSTANCE_LABEL); layout.addComponent(instanceLabel); - final Label viewScopedLabel = new Label( - String.valueOf(viewScopedBean.getUnderlyingInstance())); + final Label viewScopedLabel = new Label(String.valueOf(viewScopedBean + .getUnderlyingInstance())); viewScopedLabel.setId(ViewScopedBean.ID); layout.addComponent(viewScopedLabel); - final Label uiScopedLabel = new Label( - String.valueOf(uiScopedBean.getUnderlyingInstance())); + final Label uiScopedLabel = new Label(String.valueOf(uiScopedBean + .getUnderlyingInstance())); uiScopedLabel.setId(UIScopedBean.ID); layout.addComponent(uiScopedLabel); @@ -61,10 +71,10 @@ protected Component buildContent() { @Override public void buttonClick(ClickEvent event) { - uiScopedLabel.setValue( - String.valueOf(uiScopedBean.getUnderlyingInstance())); - viewScopedLabel.setValue( - String.valueOf(viewScopedBean.getUnderlyingInstance())); + uiScopedLabel.setValue(String.valueOf(uiScopedBean + .getUnderlyingInstance())); + viewScopedLabel.setValue(String.valueOf(viewScopedBean + .getUnderlyingInstance())); } }); layout.addComponent(refreshButton); @@ -82,6 +92,7 @@ public static class DependentBean { private void preDestroy() { counter.increment(DESTROY_COUNT); } + } } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ViewScopedView.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ViewScopedView.java index 4bffea52..d6edd0f8 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ViewScopedView.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/views/ViewScopedView.java @@ -1,11 +1,15 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ package com.vaadin.cdi.views; -import java.util.logging.Logger; - -import javax.annotation.PreDestroy; -import javax.enterprise.context.Dependent; -import javax.inject.Inject; - import com.vaadin.cdi.CDIView; import com.vaadin.cdi.internal.Counter; import com.vaadin.cdi.internal.UIScopedBean; @@ -18,9 +22,13 @@ import com.vaadin.ui.Label; import com.vaadin.ui.VerticalLayout; +import jakarta.annotation.PreDestroy; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import java.util.logging.Logger; + @CDIView(value = AbstractScopedInstancesView.VIEWSCOPED_VIEW) -public class ViewScopedView extends AbstractScopedInstancesView - implements View { +public class ViewScopedView extends AbstractScopedInstancesView implements View { public static final String DESCRIPTION_LABEL = "label"; public static final String INSTANCE_LABEL = "view-instance"; @@ -47,13 +55,13 @@ protected Component buildContent() { instanceLabel.setId(INSTANCE_LABEL); layout.addComponent(instanceLabel); - final Label viewScopedLabel = new Label( - String.valueOf(viewScopedBean.getUnderlyingInstance())); + final Label viewScopedLabel = new Label(String.valueOf(viewScopedBean + .getUnderlyingInstance())); viewScopedLabel.setId(ViewScopedBean.ID); layout.addComponent(viewScopedLabel); - final Label uiScopedLabel = new Label( - String.valueOf(uiScopedBean.getUnderlyingInstance())); + final Label uiScopedLabel = new Label(String.valueOf(uiScopedBean + .getUnderlyingInstance())); uiScopedLabel.setId(UIScopedBean.ID); layout.addComponent(uiScopedLabel); @@ -62,10 +70,10 @@ protected Component buildContent() { @Override public void buttonClick(ClickEvent event) { - uiScopedLabel.setValue( - String.valueOf(uiScopedBean.getUnderlyingInstance())); - viewScopedLabel.setValue( - String.valueOf(viewScopedBean.getUnderlyingInstance())); + uiScopedLabel.setValue(String.valueOf(uiScopedBean + .getUnderlyingInstance())); + viewScopedLabel.setValue(String.valueOf(viewScopedBean + .getUnderlyingInstance())); } }); layout.addComponent(refreshButton); @@ -73,6 +81,10 @@ public void buttonClick(ClickEvent event) { return layout; } + private Logger getLogger() { + return Logger.getLogger(this.getClass().getCanonicalName()); + } + @Dependent public static class DependentBean { public static final String DESTROY_COUNT = "ViewDependentBeanDestroy"; @@ -86,8 +98,4 @@ private void preDestroy() { } - private Logger getLogger() { - return Logger.getLogger(this.getClass().getCanonicalName()); - } - } diff --git a/vaadin-cdi/src/test/resources/arquillian.xml b/vaadin-cdi/src/test/resources/arquillian.xml index 5a7c9504..1f2b7b88 100644 --- a/vaadin-cdi/src/test/resources/arquillian.xml +++ b/vaadin-cdi/src/test/resources/arquillian.xml @@ -1,20 +1,60 @@ - - + + - phantomjs + chromeHeadless false true - - - - false - - + + \ No newline at end of file diff --git a/vaadin-cdi/src/test/resources/tomeecluster/conf/server1.xml b/vaadin-cdi/src/test/resources/tomeecluster/conf/server1.xml new file mode 100644 index 00000000..53172da6 --- /dev/null +++ b/vaadin-cdi/src/test/resources/tomeecluster/conf/server1.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vaadin-cdi/src/test/resources/tomeecluster/conf/server2.xml b/vaadin-cdi/src/test/resources/tomeecluster/conf/server2.xml new file mode 100644 index 00000000..49cae5bc --- /dev/null +++ b/vaadin-cdi/src/test/resources/tomeecluster/conf/server2.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 01a6c9ace953f1190071df0fff141f6b0c060c24 Mon Sep 17 00:00:00 2001 From: Rodolfo Felipe Date: Mon, 22 Jun 2026 01:57:06 -0400 Subject: [PATCH 2/4] Additional changes and cleanup of test cases --- .../com/vaadin/cdi/ViewNavigationTest.java | 29 --------------- .../com/vaadin/cdi/uis/ViewNavigationUI.java | 36 +++---------------- 2 files changed, 5 insertions(+), 60 deletions(-) diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java index 340d7582..1b91b342 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/ViewNavigationTest.java @@ -19,9 +19,7 @@ import jakarta.enterprise.context.ContextNotActiveException; -import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; public class ViewNavigationTest extends AbstractManagedCDIIntegrationTest { @@ -81,13 +79,6 @@ private void assertBeanValue(String expectedValue) { assertEquals(expectedValue, value); } - @Test - public void testBeforeLeaveFiredInOldContext() throws Exception { - clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); - String value = findElement(ViewNavigationUI.BEFORE_LEAVE_VALUE_LABEL_ID).getText(); - assertEquals(ViewNavigationUI.DEFAULTVIEW_VALUE, value); - } - @Test public void testShowViewCalledInNewContext() throws Exception { clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); @@ -95,24 +86,4 @@ public void testShowViewCalledInNewContext() throws Exception { assertEquals(ViewNavigationUI.SUCCESSVIEW_VALUE, value); } - @Test - public void testDelayedNavigationFindsInactiveOpeningContext() throws Exception { - resetCounts(); - clickAndWait(ViewNavigationUI.DELAY_NAV_BTN_ID); - assertBeanValue(ViewNavigationUI.DELAYVIEW_VALUE); - assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(0)); - - // navigation is delayed in DelayNavigationView.beforeLeave() - clickAndWait(ViewNavigationUI.SUCCESS_NAV_BTN_ID); - // target view is constructed - assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(1)); - // actual context remains active - assertBeanValue(ViewNavigationUI.DELAYVIEW_VALUE); - - // perform delayed navigation. The target view now belongs to the inactive opening context. - clickAndWait(ViewNavigationUI.DelayNavigationView.PREFORM_DELAYED_NAV_BTN_ID); - assertBeanValue(ViewNavigationUI.SUCCESSVIEW_VALUE); - assertThat(getCount(ViewNavigationUI.SuccessView.CONSTRUCT_COUNT), is(1)); - } - } diff --git a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java index bc8450c9..a95c3f05 100644 --- a/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java +++ b/vaadin-cdi/src/test/java/com/vaadin/cdi/uis/ViewNavigationUI.java @@ -11,7 +11,6 @@ package com.vaadin.cdi.uis; import com.vaadin.cdi.*; -import com.vaadin.cdi.internal.Counter; import com.vaadin.navigator.View; import com.vaadin.navigator.ViewChangeListener; import com.vaadin.server.VaadinRequest; @@ -19,32 +18,28 @@ import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ContextNotActiveException; +import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; @CDIUI("") public class ViewNavigationUI extends UI { public static final String REVERTED_NAV_BTN_ID = "revertednavbtn"; public static final String SUCCESS_NAV_BTN_ID = "successnavbtn"; - public static final String DELAY_NAV_BTN_ID = "delayednavbtn"; public static final String VALUE_LABEL_ID = "valuelabel"; public static final String DEFAULTVIEW_VALUE = "defaultview"; private static final String LABEL_ID = "label"; private static final String REVERTME = "revertme"; private static final String SUCCESS = "success"; - private static final String DELAY = "delay"; public static final String SUCCESSVIEW_VALUE = "successview"; - public static final String DELAYVIEW_VALUE = "delayview"; public static final String BEFORE_VALUE_LABEL_ID = "beforevaluelabel"; public static final String AFTER_VALUE_LABEL_ID = "aftervaluelabel"; public static final String CDIAFTER_VALUE_LABEL_ID = "cdiaftervaluelabel"; - public static final String BEFORE_LEAVE_VALUE_LABEL_ID = "beforeleavevaluelabel"; public static final String SHOW_VIEW_VALUE_LABEL_ID = "viewcomponentvaluelabel"; @Inject CDINavigator navigator; @Inject ViewScopedBean bean; - private Label beforeLeaveValue; private Label showViewValue; private Label value; private Label cdiAfterValue; @@ -68,10 +63,6 @@ protected void init(VaadinRequest request) { beforeValue.setId(BEFORE_VALUE_LABEL_ID); layout.addComponent(beforeValue); - beforeLeaveValue = new Label(); - beforeLeaveValue.setId(BEFORE_LEAVE_VALUE_LABEL_ID); - layout.addComponent(beforeLeaveValue); - showViewValue = new Label(); showViewValue.setId(SHOW_VIEW_VALUE_LABEL_ID); layout.addComponent(showViewValue); @@ -123,7 +114,6 @@ public void afterViewChange(ViewChangeEvent event) { createNavBtn(layout, REVERTED_NAV_BTN_ID, REVERTME); createNavBtn(layout, SUCCESS_NAV_BTN_ID, SUCCESS); - createNavBtn(layout, DELAY_NAV_BTN_ID, DELAY); setContent(layout); } @@ -170,34 +160,14 @@ public void enter(ViewChangeListener.ViewChangeEvent event) { public static class SuccessView implements View { @Inject ViewScopedBean bean; - @Inject - Counter counter; - public static String CONSTRUCT_COUNT = "successconstructcount"; @PostConstruct private void init() { bean.setValue(SUCCESSVIEW_VALUE); - counter.increment(CONSTRUCT_COUNT); - } - - @Override - public void enter(ViewChangeListener.ViewChangeEvent event) { } - } - - @CDIView(DELAY) - public static class DelayNavigationView extends VerticalLayout implements View { - @Inject - ViewScopedBean bean; - Button performDelayedNavBtn; - public static final String PREFORM_DELAYED_NAV_BTN_ID = "performDelayedNavBtn"; @Override public void enter(ViewChangeListener.ViewChangeEvent event) { - bean.setValue(DELAYVIEW_VALUE); - performDelayedNavBtn = new Button(PREFORM_DELAYED_NAV_BTN_ID); - performDelayedNavBtn.setId(PREFORM_DELAYED_NAV_BTN_ID); - addComponent(performDelayedNavBtn); } } @@ -214,4 +184,8 @@ public void setValue(String value) { } } + private void onAfterViewChange(@Observes @AfterViewChange ViewChangeListener.ViewChangeEvent event) { + cdiAfterValue.setValue(bean.getValue()); + } + } From a6e141962b6e0653bedf6a7c082abb9e39405bcb Mon Sep 17 00:00:00 2001 From: Rodolfo Felipe Date: Mon, 22 Jun 2026 02:12:57 -0400 Subject: [PATCH 3/4] Backport of https://github.com/vaadin/cdi/pull/522 to V7 branch. --- .../internal/DeltaSpikeConfigBootstrap.java | 87 +++++++++++++++++++ .../jakarta.enterprise.inject.spi.Extension | 3 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 vaadin-cdi/src/main/java/com/vaadin/cdi/internal/DeltaSpikeConfigBootstrap.java diff --git a/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/DeltaSpikeConfigBootstrap.java b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/DeltaSpikeConfigBootstrap.java new file mode 100644 index 00000000..c2314112 --- /dev/null +++ b/vaadin-cdi/src/main/java/com/vaadin/cdi/internal/DeltaSpikeConfigBootstrap.java @@ -0,0 +1,87 @@ +/* + * Vaadin CDI Integration + * + * Copyright (C) 2012-2026 Vaadin Ltd + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See for the full + * license. + */ +package com.vaadin.cdi.internal; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import jakarta.annotation.Priority; +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.interceptor.Interceptor; + +import org.apache.deltaspike.core.api.config.ConfigResolver; + +/** + * Works around a DeltaSpike + EAR classloading problem on Jakarta EE servers + * (e.g. WildFly / JBoss EAP 8). + *

+ * DeltaSpike's JMX {@code MBeanExtension} observes {@link BeforeBeanDiscovery} + * and, during that callback, resolves the DeltaSpike ProjectStage via + * {@link ConfigResolver#getConfigProvider()}. That method discovers its + * {@code ConfigProvider} implementation with {@code ServiceLoader} against the + * thread context classloader. When this add-on's WAR is nested inside + * an EAR, the TCCL active during CDI bootstrap is the EAR (parent) classloader, + * which cannot see {@code deltaspike-core-impl} in the WAR's {@code WEB-INF/lib}. + * The lookup then finds no provider and deployment fails with + * {@code java.lang.RuntimeException: Could not load ConfigProvider}. + *

+ * This extension primes and caches the {@code ConfigProvider} early, while the + * TCCL is set to this class's classloader (the WAR module classloader, which can + * see {@code WEB-INF/lib}). {@link ConfigResolver} caches the provider in a + * static field, so DeltaSpike's later lookup returns the cached instance and + * never re-runs the failing {@code ServiceLoader} scan. DeltaSpike stays in the + * WAR, so runtime bean resolution is unaffected. + *

+ * Ordering: Weld instantiates all extensions (their constructors) before firing + * {@link BeforeBeanDiscovery}, so the constructor below is guaranteed to run + * before DeltaSpike's {@code MBeanExtension.init}. The high-priority observer is + * a defensive fallback. The priming is a no-op cost (one cached lookup) for + * standalone WAR deployments, where the problem does not occur. + */ +public class DeltaSpikeConfigBootstrap implements Extension { + + public DeltaSpikeConfigBootstrap() { + primeConfigProvider(); + } + + void primeBeforeBeanDiscovery( + @Observes @Priority(Interceptor.Priority.PLATFORM_BEFORE) BeforeBeanDiscovery beforeBeanDiscovery) { + primeConfigProvider(); + } + + private static void primeConfigProvider() { + final Thread thread = Thread.currentThread(); + final ClassLoader previous = thread.getContextClassLoader(); + try { + thread.setContextClassLoader( + DeltaSpikeConfigBootstrap.class.getClassLoader()); + // Triggers (and caches) the ServiceLoader-based ConfigProvider + // lookup now, with a TCCL that can see deltaspike-core-impl. + ConfigResolver.getConfigProvider(); + } catch (RuntimeException e) { + // Priming is best-effort: if it fails, fall through and let the + // normal DeltaSpike code path run and surface the original error. + getLogger().log(Level.FINE, + "Could not pre-initialize the DeltaSpike ConfigProvider; " + + "falling back to the default bootstrap.", + e); + } finally { + thread.setContextClassLoader(previous); + } + } + + private static Logger getLogger() { + return Logger.getLogger(DeltaSpikeConfigBootstrap.class.getCanonicalName()); + } + +} diff --git a/vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension b/vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension index 7c7c1e34..90119dc4 100644 --- a/vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension +++ b/vaadin-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension @@ -1 +1,2 @@ -com.vaadin.cdi.internal.VaadinExtension \ No newline at end of file +com.vaadin.cdi.internal.VaadinExtension +com.vaadin.cdi.internal.DeltaSpikeConfigBootstrap \ No newline at end of file From d02230053e7af43fcfa96fca596f99e36bba5eb8 Mon Sep 17 00:00:00 2001 From: Rodolfo Felipe Date: Tue, 23 Jun 2026 01:13:11 -0400 Subject: [PATCH 4/4] Added validation workflow from V8 branch. --- .github/workflows/validation.yml | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .github/workflows/validation.yml diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml new file mode 100644 index 00000000..dd9897c7 --- /dev/null +++ b/.github/workflows/validation.yml @@ -0,0 +1,65 @@ +name: Validation + +on: + pull_request: + paths-ignore: + - '**/*.md' + - '.travis*' + - '.gitignore' + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + validate: + name: Compile & static checks + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '21' + cache: maven + - name: Compile + run: mvn -B -ntp -fae compile test-compile + + tests: + name: Tests (${{ matrix.profile }}) + needs: validate + runs-on: ubuntu-latest + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + profile: [wildfly] + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: '21' + cache: maven + + - name: Set vaadin proKey + env: + TB_LICENSE: ${{secrets.TB_LICENSE}} + run: | + mkdir -p ~/.vaadin/ + echo '{"username":"'`echo $TB_LICENSE | cut -d / -f1`'","proKey":"'`echo $TB_LICENSE | cut -d / -f2`'"}' > ~/.vaadin/proKey + + - name: Run tests (${{ matrix.profile }}) + run: mvn -B -ntp verify -P${{ matrix.profile }} + - name: Upload surefire reports + if: failure() + uses: actions/upload-artifact@v6 + with: + name: surefire-reports-${{ matrix.profile }} + path: vaadin-cdi/target/surefire-reports/ + if-no-files-found: ignore