Repository: apache/deltaspike Branch: master Commit: b330c0d9f498 Files: 2135 Total size: 6.0 MB Directory structure: gitextract_n34ve_sb/ ├── .github/ │ └── workflows/ │ ├── ci.yml │ └── integration.yml ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── buildall.sh ├── deltaspike/ │ ├── LICENSE │ ├── NOTICE │ ├── README.md │ ├── cdictrl/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── cdise/ │ │ │ └── api/ │ │ │ ├── CdiContainer.java │ │ │ ├── CdiContainerLoader.java │ │ │ └── ContextControl.java │ │ ├── impl-openejb/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── cdise/ │ │ │ │ │ └── openejb/ │ │ │ │ │ └── OpenEjbContainerControl.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ └── org.apache.deltaspike.cdise.api.CdiContainer │ │ │ └── test/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── cdise/ │ │ │ └── openejb/ │ │ │ ├── OpenEJbContainerControlConfigurationTest.java │ │ │ └── bean/ │ │ │ └── Foo.java │ │ ├── impl-owb/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── cdise/ │ │ │ │ └── owb/ │ │ │ │ ├── MockHttpSession.java │ │ │ │ ├── MockServletContext.java │ │ │ │ ├── OpenWebBeansContainerControl.java │ │ │ │ ├── OpenWebBeansContextControl.java │ │ │ │ └── OwbHelper.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── beans.xml │ │ │ └── services/ │ │ │ └── org.apache.deltaspike.cdise.api.CdiContainer │ │ ├── impl-weld/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── cdise/ │ │ │ │ └── weld/ │ │ │ │ ├── WeldContainerControl.java │ │ │ │ └── WeldContextControl.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── beans.xml │ │ │ └── services/ │ │ │ └── org.apache.deltaspike.cdise.api.CdiContainer │ │ ├── pom.xml │ │ └── tck/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── cdise/ │ │ │ └── tck/ │ │ │ ├── ContainerCtrlTckTest.java │ │ │ └── beans/ │ │ │ ├── Car.java │ │ │ ├── CarRepair.java │ │ │ └── TestUser.java │ │ └── resources/ │ │ └── META-INF/ │ │ └── beans.xml │ ├── checkstyle-rules/ │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ └── resources/ │ │ └── deltaspike/ │ │ ├── asf-header.txt │ │ └── default-checks.xml │ ├── core/ │ │ ├── api/ │ │ │ ├── obsolete/ │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ └── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── core/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── common/ │ │ │ │ │ │ │ └── DeltaSpike.java │ │ │ │ │ │ ├── control/ │ │ │ │ │ │ │ ├── BeforeHandles.java │ │ │ │ │ │ │ ├── ExceptionHandler.java │ │ │ │ │ │ │ ├── ExceptionHandlingFlow.java │ │ │ │ │ │ │ ├── ExceptionStackItem.java │ │ │ │ │ │ │ ├── HandlerMethod.java │ │ │ │ │ │ │ ├── Handles.java │ │ │ │ │ │ │ └── event/ │ │ │ │ │ │ │ ├── ExceptionEvent.java │ │ │ │ │ │ │ ├── ExceptionStackEvent.java │ │ │ │ │ │ │ └── ExceptionToCatchEvent.java │ │ │ │ │ │ ├── lifecycle/ │ │ │ │ │ │ │ ├── Destroyed.java │ │ │ │ │ │ │ └── Initialized.java │ │ │ │ │ │ ├── literal/ │ │ │ │ │ │ │ ├── AlternativeLiteral.java │ │ │ │ │ │ │ ├── AnyLiteral.java │ │ │ │ │ │ │ ├── ApplicationScopedLiteral.java │ │ │ │ │ │ │ ├── ConversationScopedLiteral.java │ │ │ │ │ │ │ ├── DefaultLiteral.java │ │ │ │ │ │ │ ├── DeltaSpikeLiteral.java │ │ │ │ │ │ │ ├── DependentScopeLiteral.java │ │ │ │ │ │ │ ├── DestroyedLiteral.java │ │ │ │ │ │ │ ├── InitializedLiteral.java │ │ │ │ │ │ │ ├── InjectableResourceLiteral.java │ │ │ │ │ │ │ ├── ModelLiteral.java │ │ │ │ │ │ │ ├── NamedLiteral.java │ │ │ │ │ │ │ ├── NewLiteral.java │ │ │ │ │ │ │ ├── RequestScopedLiteral.java │ │ │ │ │ │ │ ├── SessionScopeLiteral.java │ │ │ │ │ │ │ ├── SingletonLiteral.java │ │ │ │ │ │ │ ├── SpecializesLiteral.java │ │ │ │ │ │ │ └── TypedLiteral.java │ │ │ │ │ │ └── resourceloader/ │ │ │ │ │ │ ├── AbstractResourceProvider.java │ │ │ │ │ │ ├── ClasspathResourceProvider.java │ │ │ │ │ │ ├── FileResourceProvider.java │ │ │ │ │ │ ├── InjectableResource.java │ │ │ │ │ │ └── InjectableResourceProvider.java │ │ │ │ │ ├── spi/ │ │ │ │ │ │ └── event/ │ │ │ │ │ │ └── IntrospectiveExceptionEvent.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── AnnotationUtils.java │ │ │ │ │ ├── CollectionUtils.java │ │ │ │ │ ├── ParentExtensionStorage.java │ │ │ │ │ ├── bean/ │ │ │ │ │ │ ├── BaseImmutableBean.java │ │ │ │ │ │ ├── BeanBuilder.java │ │ │ │ │ │ ├── ImmutableBean.java │ │ │ │ │ │ ├── ImmutableBeanWrapper.java │ │ │ │ │ │ ├── ImmutablePassivationCapableBean.java │ │ │ │ │ │ ├── ImmutablePassivationCapableBeanWrapper.java │ │ │ │ │ │ └── WrappingBeanBuilder.java │ │ │ │ │ └── metadata/ │ │ │ │ │ ├── InjectionPointWrapper.java │ │ │ │ │ └── builder/ │ │ │ │ │ ├── AnnotatedCallableImpl.java │ │ │ │ │ ├── AnnotatedConstructorImpl.java │ │ │ │ │ ├── AnnotatedFieldImpl.java │ │ │ │ │ ├── AnnotatedImpl.java │ │ │ │ │ ├── AnnotatedMemberImpl.java │ │ │ │ │ ├── AnnotatedMethodImpl.java │ │ │ │ │ ├── AnnotatedParameterImpl.java │ │ │ │ │ ├── AnnotatedTypeBuilder.java │ │ │ │ │ ├── AnnotatedTypeImpl.java │ │ │ │ │ ├── AnnotationBuilder.java │ │ │ │ │ ├── AnnotationStore.java │ │ │ │ │ ├── ContextualLifecycle.java │ │ │ │ │ ├── DelegatingContextualLifecycle.java │ │ │ │ │ └── DummyInjectionTarget.java │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── test/ │ │ │ │ └── api/ │ │ │ │ └── metadata/ │ │ │ │ ├── AnnotatedTypeBuilderTest.java │ │ │ │ ├── Cat.java │ │ │ │ └── Small.java │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── core/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ ├── Config.java │ │ │ │ │ │ │ ├── ConfigProperty.java │ │ │ │ │ │ │ ├── ConfigResolver.java │ │ │ │ │ │ │ ├── ConfigSnapshot.java │ │ │ │ │ │ │ ├── Configuration.java │ │ │ │ │ │ │ ├── DeltaSpikeConfig.java │ │ │ │ │ │ │ ├── Filter.java │ │ │ │ │ │ │ ├── PropertyFileConfig.java │ │ │ │ │ │ │ ├── PropertyLoader.java │ │ │ │ │ │ │ ├── Source.java │ │ │ │ │ │ │ ├── base/ │ │ │ │ │ │ │ │ ├── CoreBaseConfig.java │ │ │ │ │ │ │ │ └── DeltaSpikeBaseConfig.java │ │ │ │ │ │ │ └── view/ │ │ │ │ │ │ │ ├── DefaultErrorView.java │ │ │ │ │ │ │ ├── ViewConfig.java │ │ │ │ │ │ │ ├── ViewRef.java │ │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ │ ├── InitView.java │ │ │ │ │ │ │ │ ├── PostRenderView.java │ │ │ │ │ │ │ │ ├── PreRenderView.java │ │ │ │ │ │ │ │ ├── PreViewAction.java │ │ │ │ │ │ │ │ └── ViewControllerRef.java │ │ │ │ │ │ │ ├── metadata/ │ │ │ │ │ │ │ │ ├── Aggregated.java │ │ │ │ │ │ │ │ ├── CallbackDescriptor.java │ │ │ │ │ │ │ │ ├── ConfigDescriptor.java │ │ │ │ │ │ │ │ ├── DefaultCallback.java │ │ │ │ │ │ │ │ ├── ExecutableCallbackDescriptor.java │ │ │ │ │ │ │ │ ├── InlineViewMetaData.java │ │ │ │ │ │ │ │ ├── SimpleCallbackDescriptor.java │ │ │ │ │ │ │ │ ├── SkipMetaDataMerge.java │ │ │ │ │ │ │ │ ├── ViewConfigDescriptor.java │ │ │ │ │ │ │ │ ├── ViewConfigResolver.java │ │ │ │ │ │ │ │ └── ViewMetaData.java │ │ │ │ │ │ │ └── navigation/ │ │ │ │ │ │ │ ├── NavigationParameter.java │ │ │ │ │ │ │ ├── NavigationParameterContext.java │ │ │ │ │ │ │ ├── ViewNavigationHandler.java │ │ │ │ │ │ │ └── event/ │ │ │ │ │ │ │ └── PreViewConfigNavigateEvent.java │ │ │ │ │ │ ├── crypto/ │ │ │ │ │ │ │ └── CipherService.java │ │ │ │ │ │ ├── exclude/ │ │ │ │ │ │ │ └── Exclude.java │ │ │ │ │ │ ├── future/ │ │ │ │ │ │ │ └── Futureable.java │ │ │ │ │ │ ├── interpreter/ │ │ │ │ │ │ │ ├── BasePropertyExpressionInterpreter.java │ │ │ │ │ │ │ ├── ExpressionInterpreter.java │ │ │ │ │ │ │ └── SimpleOperationEnum.java │ │ │ │ │ │ ├── jmx/ │ │ │ │ │ │ │ ├── JmxBroadcaster.java │ │ │ │ │ │ │ ├── JmxManaged.java │ │ │ │ │ │ │ ├── JmxParameter.java │ │ │ │ │ │ │ ├── MBean.java │ │ │ │ │ │ │ ├── NotificationInfo.java │ │ │ │ │ │ │ └── Table.java │ │ │ │ │ │ ├── literal/ │ │ │ │ │ │ │ ├── MessageBundleLiteral.java │ │ │ │ │ │ │ ├── MessageContextConfigLiteral.java │ │ │ │ │ │ │ └── ViewControllerRefLiteral.java │ │ │ │ │ │ ├── lock/ │ │ │ │ │ │ │ └── Locked.java │ │ │ │ │ │ ├── message/ │ │ │ │ │ │ │ ├── LocaleResolver.java │ │ │ │ │ │ │ ├── Message.java │ │ │ │ │ │ │ ├── MessageBundle.java │ │ │ │ │ │ │ ├── MessageContext.java │ │ │ │ │ │ │ ├── MessageContextConfig.java │ │ │ │ │ │ │ ├── MessageInterpolator.java │ │ │ │ │ │ │ ├── MessageResolver.java │ │ │ │ │ │ │ └── MessageTemplate.java │ │ │ │ │ │ ├── monitoring/ │ │ │ │ │ │ │ ├── InvocationMonitored.java │ │ │ │ │ │ │ └── MonitorResultEvent.java │ │ │ │ │ │ ├── projectstage/ │ │ │ │ │ │ │ ├── ProjectStage.java │ │ │ │ │ │ │ ├── ProjectStageHolder.java │ │ │ │ │ │ │ └── TestStage.java │ │ │ │ │ │ ├── provider/ │ │ │ │ │ │ │ ├── BeanManagerProvider.java │ │ │ │ │ │ │ ├── BeanProvider.java │ │ │ │ │ │ │ └── DependentProvider.java │ │ │ │ │ │ ├── scope/ │ │ │ │ │ │ │ ├── ConversationGroup.java │ │ │ │ │ │ │ ├── ConversationSubGroup.java │ │ │ │ │ │ │ ├── GroupedConversation.java │ │ │ │ │ │ │ ├── GroupedConversationScoped.java │ │ │ │ │ │ │ ├── ViewAccessScoped.java │ │ │ │ │ │ │ └── WindowScoped.java │ │ │ │ │ │ └── throttling/ │ │ │ │ │ │ ├── Throttled.java │ │ │ │ │ │ └── Throttling.java │ │ │ │ │ ├── spi/ │ │ │ │ │ │ ├── InterceptorStrategy.java │ │ │ │ │ │ ├── activation/ │ │ │ │ │ │ │ ├── ClassDeactivator.java │ │ │ │ │ │ │ └── Deactivatable.java │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ ├── BaseConfigPropertyProducer.java │ │ │ │ │ │ │ ├── ConfigFilter.java │ │ │ │ │ │ │ ├── ConfigSource.java │ │ │ │ │ │ │ ├── ConfigSourceProvider.java │ │ │ │ │ │ │ ├── ConfigValidator.java │ │ │ │ │ │ │ └── view/ │ │ │ │ │ │ │ ├── ConfigDescriptorValidator.java │ │ │ │ │ │ │ ├── ConfigNodeConverter.java │ │ │ │ │ │ │ ├── ConfigPreProcessor.java │ │ │ │ │ │ │ ├── InlineMetaDataTransformer.java │ │ │ │ │ │ │ ├── TargetViewConfigProvider.java │ │ │ │ │ │ │ ├── ViewConfigInheritanceStrategy.java │ │ │ │ │ │ │ ├── ViewConfigNode.java │ │ │ │ │ │ │ └── ViewConfigRoot.java │ │ │ │ │ │ ├── filter/ │ │ │ │ │ │ │ └── ClassFilter.java │ │ │ │ │ │ ├── future/ │ │ │ │ │ │ │ └── FutureableStrategy.java │ │ │ │ │ │ ├── lock/ │ │ │ │ │ │ │ └── LockedStrategy.java │ │ │ │ │ │ ├── scope/ │ │ │ │ │ │ │ ├── conversation/ │ │ │ │ │ │ │ │ └── GroupedConversationManager.java │ │ │ │ │ │ │ ├── viewaccess/ │ │ │ │ │ │ │ │ └── ViewAccessContextManager.java │ │ │ │ │ │ │ └── window/ │ │ │ │ │ │ │ ├── WindowContext.java │ │ │ │ │ │ │ └── WindowContextQuotaHandler.java │ │ │ │ │ │ └── throttling/ │ │ │ │ │ │ └── ThrottledStrategy.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── AggregatedClassLoader.java │ │ │ │ │ ├── Annotateds.java │ │ │ │ │ ├── AnnotationUtils.java │ │ │ │ │ ├── ArraysUtils.java │ │ │ │ │ ├── BeanConfiguratorUtils.java │ │ │ │ │ ├── BeanUtils.java │ │ │ │ │ ├── ClassDeactivationUtils.java │ │ │ │ │ ├── ClassUtils.java │ │ │ │ │ ├── ContextUtils.java │ │ │ │ │ ├── ExceptionUtils.java │ │ │ │ │ ├── HierarchyDiscovery.java │ │ │ │ │ ├── ParameterUtil.java │ │ │ │ │ ├── ParameterizedTypeImpl.java │ │ │ │ │ ├── ProjectStageProducer.java │ │ │ │ │ ├── PropertyFileUtils.java │ │ │ │ │ ├── ProxyUtils.java │ │ │ │ │ ├── ReflectionUtils.java │ │ │ │ │ ├── ServiceUtils.java │ │ │ │ │ ├── StringUtils.java │ │ │ │ │ ├── context/ │ │ │ │ │ │ ├── AbstractContext.java │ │ │ │ │ │ ├── ContextualInstanceInfo.java │ │ │ │ │ │ └── ContextualStorage.java │ │ │ │ │ ├── interceptor/ │ │ │ │ │ │ └── AbstractInvocationContext.java │ │ │ │ │ └── metadata/ │ │ │ │ │ ├── AnnotationInstanceProvider.java │ │ │ │ │ └── builder/ │ │ │ │ │ ├── ImmutableInjectionPoint.java │ │ │ │ │ ├── InjectableMethod.java │ │ │ │ │ └── ParameterValueRedefiner.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ ├── core/ │ │ │ │ │ └── util/ │ │ │ │ │ ├── ClassUtilsTest.java │ │ │ │ │ ├── ParameterUtilTest.java │ │ │ │ │ └── PropertyFileUtilsTest.java │ │ │ │ └── test/ │ │ │ │ └── api/ │ │ │ │ ├── config/ │ │ │ │ │ └── PropertyLoaderTest.java │ │ │ │ └── util/ │ │ │ │ ├── CustomException.java │ │ │ │ ├── ExceptionUtilsTest.java │ │ │ │ ├── IncompatibleCustomException.java │ │ │ │ ├── StringUtilsTest.java │ │ │ │ └── metadata/ │ │ │ │ ├── AnnotationInstanceProviderTest.java │ │ │ │ ├── NestAnnotation.java │ │ │ │ ├── Stooge.java │ │ │ │ └── TestAnnotation.java │ │ │ └── resources/ │ │ │ ├── test.properties │ │ │ ├── test2-UnitTest.properties │ │ │ └── test2.properties │ │ ├── impl/ │ │ │ ├── obsolete/ │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ └── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── core/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── control/ │ │ │ │ │ │ ├── DefaultExceptionEvent.java │ │ │ │ │ │ ├── ExceptionHandlerBroadcaster.java │ │ │ │ │ │ ├── ExceptionHandlerComparator.java │ │ │ │ │ │ ├── HandlerMethodImpl.java │ │ │ │ │ │ ├── HandlerMethodStorage.java │ │ │ │ │ │ ├── HandlerMethodStorageImpl.java │ │ │ │ │ │ ├── HandlerMethodStorageProducer.java │ │ │ │ │ │ ├── OutboundParameterValueRedefiner.java │ │ │ │ │ │ └── extension/ │ │ │ │ │ │ └── ExceptionControlExtension.java │ │ │ │ │ ├── interceptor/ │ │ │ │ │ │ └── GlobalInterceptorExtension.java │ │ │ │ │ └── resourceloader/ │ │ │ │ │ ├── InjectableResourceProducer.java │ │ │ │ │ └── ResourceLoaderExtension.java │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── test/ │ │ │ │ └── core/ │ │ │ │ ├── api/ │ │ │ │ │ ├── alternative/ │ │ │ │ │ │ ├── global/ │ │ │ │ │ │ │ ├── BaseBean1.java │ │ │ │ │ │ │ ├── BaseInterface1.java │ │ │ │ │ │ │ ├── BaseInterface1AlternativeImplementation.java │ │ │ │ │ │ │ ├── BaseInterface1DefaultImplementation.java │ │ │ │ │ │ │ ├── SubBaseBean1.java │ │ │ │ │ │ │ ├── SubBaseBean2.java │ │ │ │ │ │ │ └── qualifier/ │ │ │ │ │ │ │ ├── AlternativeBaseBeanB.java │ │ │ │ │ │ │ ├── BaseBeanA.java │ │ │ │ │ │ │ ├── BaseBeanB.java │ │ │ │ │ │ │ ├── BaseBeanB2.java │ │ │ │ │ │ │ ├── BaseInterface.java │ │ │ │ │ │ │ ├── QualifierA.java │ │ │ │ │ │ │ ├── QualifierB.java │ │ │ │ │ │ │ ├── QualifierValue1.java │ │ │ │ │ │ │ └── QualifierValue2.java │ │ │ │ │ │ └── local/ │ │ │ │ │ │ ├── BaseBean2.java │ │ │ │ │ │ ├── BaseInterface2.java │ │ │ │ │ │ ├── BaseInterface2AlternativeImplementation.java │ │ │ │ │ │ ├── BaseInterface2DefaultImplementation.java │ │ │ │ │ │ ├── BdaAlternativeTest.java │ │ │ │ │ │ └── SubBaseBean2.java │ │ │ │ │ ├── exclude/ │ │ │ │ │ │ └── ExcludeEarFileTest.java │ │ │ │ │ ├── provider/ │ │ │ │ │ │ └── BeanManagerProviderEarFileTest.java │ │ │ │ │ └── util/ │ │ │ │ │ └── bean/ │ │ │ │ │ ├── BeanBuilderTest.java │ │ │ │ │ ├── SimpleClass.java │ │ │ │ │ └── WithInjectionPoint.java │ │ │ │ └── impl/ │ │ │ │ ├── activation/ │ │ │ │ │ └── ClassDeactivationEarFileTest.java │ │ │ │ ├── custom/ │ │ │ │ │ └── spi/ │ │ │ │ │ └── PartialBeanAsInterfaceEarFileTest.java │ │ │ │ ├── exception/ │ │ │ │ │ └── control/ │ │ │ │ │ ├── event/ │ │ │ │ │ │ ├── EventQualifier.java │ │ │ │ │ │ ├── EventTest.java │ │ │ │ │ │ └── literal/ │ │ │ │ │ │ └── EventQualifierLiteral.java │ │ │ │ │ ├── extension/ │ │ │ │ │ │ ├── Account.java │ │ │ │ │ │ ├── Arquillian.java │ │ │ │ │ │ ├── CatchQualifier.java │ │ │ │ │ │ └── literal/ │ │ │ │ │ │ └── CatchQualifierLiteral.java │ │ │ │ │ ├── flow/ │ │ │ │ │ │ ├── AbortingBreadthFirstHandler.java │ │ │ │ │ │ ├── AbortingDepthHandler.java │ │ │ │ │ │ ├── BreadthFirstAbortControlTest.java │ │ │ │ │ │ ├── DepthAbortControlTest.java │ │ │ │ │ │ ├── ExceptionHandledHandler.java │ │ │ │ │ │ ├── HandledExceptionHandlerTest.java │ │ │ │ │ │ ├── ProceedCauseHandler.java │ │ │ │ │ │ ├── ProceedCauseHandlerTest.java │ │ │ │ │ │ ├── RethrowHandler.java │ │ │ │ │ │ ├── RethrowTest.java │ │ │ │ │ │ ├── ThrowingNewExceptionTest.java │ │ │ │ │ │ └── ThrowingNewHandler.java │ │ │ │ │ ├── handler/ │ │ │ │ │ │ ├── BadInjectionPointHandler.java │ │ │ │ │ │ ├── CalledExceptionHandler.java │ │ │ │ │ │ ├── CallingHandlersTest.java │ │ │ │ │ │ ├── ExtensionExceptionHandler.java │ │ │ │ │ │ ├── HandlerComparatorTest.java │ │ │ │ │ │ ├── HandlerWhichThrowsExceptions.java │ │ │ │ │ │ ├── UnMuteHandler.java │ │ │ │ │ │ └── UnMuteHandlerTest.java │ │ │ │ │ └── traversal/ │ │ │ │ │ ├── ExceptionHandlerMethods.java │ │ │ │ │ ├── Exceptions.java │ │ │ │ │ └── TraversalPathTest.java │ │ │ │ ├── jmx/ │ │ │ │ │ └── SimpleRegistrationEarFileTest.java │ │ │ │ ├── resourceloader/ │ │ │ │ │ ├── ClasspathResourceTest.java │ │ │ │ │ ├── ClasspathWebProfileTest.java │ │ │ │ │ └── FileResourceTest.java │ │ │ │ └── util/ │ │ │ │ └── JndiUtilsEarFileTest.java │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── core/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── activation/ │ │ │ │ │ │ └── DefaultClassDeactivator.java │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── BaseConfigSource.java │ │ │ │ │ │ ├── ConfigHelperImpl.java │ │ │ │ │ │ ├── ConfigImpl.java │ │ │ │ │ │ ├── ConfigProviderImpl.java │ │ │ │ │ │ ├── ConfigResolverContext.java │ │ │ │ │ │ ├── ConfigSnapshotImpl.java │ │ │ │ │ │ ├── ConfigurationExtension.java │ │ │ │ │ │ ├── DefaultConfigPropertyProducer.java │ │ │ │ │ │ ├── DefaultConfigSourceProvider.java │ │ │ │ │ │ ├── DeltaSpikeConfigInfo.java │ │ │ │ │ │ ├── DeltaSpikeConfigInfoMBean.java │ │ │ │ │ │ ├── EnvironmentPropertyConfigSource.java │ │ │ │ │ │ ├── EnvironmentPropertyConfigSourceProvider.java │ │ │ │ │ │ ├── LocalJndiConfigSource.java │ │ │ │ │ │ ├── MapConfigSource.java │ │ │ │ │ │ ├── PropertiesConfigSource.java │ │ │ │ │ │ ├── PropertyFileConfigSource.java │ │ │ │ │ │ ├── ProxyConfigurationLifecycle.java │ │ │ │ │ │ ├── SystemPropertyConfigSource.java │ │ │ │ │ │ ├── TypedResolverImpl.java │ │ │ │ │ │ └── converter/ │ │ │ │ │ │ ├── BeanConverterFactory.java │ │ │ │ │ │ ├── CtInjectionBeanConverter.java │ │ │ │ │ │ └── FieldInjectionBeanConverter.java │ │ │ │ │ ├── crypto/ │ │ │ │ │ │ ├── CdiCipherService.java │ │ │ │ │ │ ├── CipherCli.java │ │ │ │ │ │ └── DefaultCipherService.java │ │ │ │ │ ├── exclude/ │ │ │ │ │ │ ├── CustomProjectStageBeanFilter.java │ │ │ │ │ │ └── extension/ │ │ │ │ │ │ └── ExcludeExtension.java │ │ │ │ │ ├── future/ │ │ │ │ │ │ ├── DefaultFutureableStrategy.java │ │ │ │ │ │ ├── FutureableInterceptor.java │ │ │ │ │ │ ├── J8PromiseCompanionTask.java │ │ │ │ │ │ └── ThreadPoolManager.java │ │ │ │ │ ├── interceptor/ │ │ │ │ │ │ ├── GlobalInterceptorWrapper.java │ │ │ │ │ │ └── interdyn/ │ │ │ │ │ │ ├── AnnotationRule.java │ │ │ │ │ │ └── InterDynExtension.java │ │ │ │ │ ├── interpreter/ │ │ │ │ │ │ └── PropertyExpressionInterpreter.java │ │ │ │ │ ├── jmx/ │ │ │ │ │ │ ├── AttributeAccessor.java │ │ │ │ │ │ ├── BroadcasterProducer.java │ │ │ │ │ │ ├── DynamicMBeanWrapper.java │ │ │ │ │ │ ├── MBeanExtension.java │ │ │ │ │ │ └── Operation.java │ │ │ │ │ ├── lock/ │ │ │ │ │ │ ├── DefaultLockedStrategy.java │ │ │ │ │ │ ├── LockSupplier.java │ │ │ │ │ │ ├── LockSupplierStorage.java │ │ │ │ │ │ └── LockedInterceptor.java │ │ │ │ │ ├── message/ │ │ │ │ │ │ ├── DefaultLocaleResolver.java │ │ │ │ │ │ ├── DefaultMessage.java │ │ │ │ │ │ ├── DefaultMessageContext.java │ │ │ │ │ │ ├── DefaultMessageInterpolator.java │ │ │ │ │ │ ├── DefaultMessageResolver.java │ │ │ │ │ │ ├── MessageBundleContext.java │ │ │ │ │ │ ├── MessageBundleExtension.java │ │ │ │ │ │ ├── MessageBundleInvocationHandler.java │ │ │ │ │ │ └── MessageFormatMessageInterpolator.java │ │ │ │ │ ├── monitoring/ │ │ │ │ │ │ ├── InvocationMonitorInterceptor.java │ │ │ │ │ │ ├── InvocationResultLogger.java │ │ │ │ │ │ └── RequestInvocationCounter.java │ │ │ │ │ ├── scope/ │ │ │ │ │ │ ├── AbstractBeanHolder.java │ │ │ │ │ │ ├── DeltaSpikeContextExtension.java │ │ │ │ │ │ ├── conversation/ │ │ │ │ │ │ │ ├── ConversationBeanHolder.java │ │ │ │ │ │ │ ├── ConversationKey.java │ │ │ │ │ │ │ ├── GroupedConversationArtifactProducer.java │ │ │ │ │ │ │ ├── GroupedConversationContext.java │ │ │ │ │ │ │ ├── InjectableGroupedConversation.java │ │ │ │ │ │ │ └── InjectableGroupedConversationManager.java │ │ │ │ │ │ ├── viewaccess/ │ │ │ │ │ │ │ ├── InjectableViewAccessContextManager.java │ │ │ │ │ │ │ ├── ViewAccessBeanAccessHistory.java │ │ │ │ │ │ │ ├── ViewAccessBeanHolder.java │ │ │ │ │ │ │ ├── ViewAccessContext.java │ │ │ │ │ │ │ ├── ViewAccessContextArtifactProducer.java │ │ │ │ │ │ │ └── ViewAccessViewHistory.java │ │ │ │ │ │ └── window/ │ │ │ │ │ │ ├── DefaultWindowContextQuotaHandler.java │ │ │ │ │ │ ├── InjectableWindowContext.java │ │ │ │ │ │ ├── WindowBeanHolder.java │ │ │ │ │ │ ├── WindowContextImpl.java │ │ │ │ │ │ ├── WindowContextProducer.java │ │ │ │ │ │ ├── WindowContextQuotaHandlerCache.java │ │ │ │ │ │ └── WindowIdHolder.java │ │ │ │ │ ├── throttling/ │ │ │ │ │ │ ├── DefaultThrottledStrategy.java │ │ │ │ │ │ ├── Invoker.java │ │ │ │ │ │ ├── InvokerStorage.java │ │ │ │ │ │ └── ThrottledInterceptor.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── AnnotatedMethods.java │ │ │ │ │ ├── ConversationUtils.java │ │ │ │ │ └── JndiUtils.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── MANIFEST.MF │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ ├── jakarta.enterprise.inject.spi.Extension │ │ │ │ ├── org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider │ │ │ │ └── org.apache.deltaspike.core.spi.config.ConfigSourceProvider │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── test/ │ │ │ │ ├── core/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ ├── BeanConfigResolverTest.java │ │ │ │ │ │ │ ├── ConfigHelperTest.java │ │ │ │ │ │ │ ├── ConfigResolverTest.java │ │ │ │ │ │ │ ├── ConfigSnapshotTest.java │ │ │ │ │ │ │ ├── ConfigSourceTest.java │ │ │ │ │ │ │ ├── ConfigurableTestConfigSource.java │ │ │ │ │ │ │ ├── SecretTestConfigFilter.java │ │ │ │ │ │ │ ├── TestConfigSource.java │ │ │ │ │ │ │ ├── TestConfigSourceProvider.java │ │ │ │ │ │ │ ├── TypedResolverTest.java │ │ │ │ │ │ │ ├── beans/ │ │ │ │ │ │ │ │ ├── ServerEndpointPojoWithCt.java │ │ │ │ │ │ │ │ └── ServerEndpointPojoWithFields.java │ │ │ │ │ │ │ ├── injectable/ │ │ │ │ │ │ │ │ ├── CdiFilter.java │ │ │ │ │ │ │ │ ├── CdiSource.java │ │ │ │ │ │ │ │ ├── ConfigBean.java │ │ │ │ │ │ │ │ ├── CustomConfigAnnotationWithMetaData.java │ │ │ │ │ │ │ │ ├── CustomConfigAnnotationWithMetaDataProducer.java │ │ │ │ │ │ │ │ ├── InjectableConfigPropertyTest.java │ │ │ │ │ │ │ │ ├── PrefixedConfigBean.java │ │ │ │ │ │ │ │ ├── SettingsBean.java │ │ │ │ │ │ │ │ └── numberconfig/ │ │ │ │ │ │ │ │ ├── NumberConfig.java │ │ │ │ │ │ │ │ ├── NumberConfigPropertyProducer.java │ │ │ │ │ │ │ │ └── NumberConfiguredBean.java │ │ │ │ │ │ │ └── propertyconfigsource/ │ │ │ │ │ │ │ ├── BaseTestConfigProperty.java │ │ │ │ │ │ │ ├── ConfigPropertyWARTest.java │ │ │ │ │ │ │ ├── FileConfigSourceTest.java │ │ │ │ │ │ │ ├── MyCustomBootTimePropertyFileConfig.java │ │ │ │ │ │ │ ├── MyCustomEarPropertyFileConfig.java │ │ │ │ │ │ │ ├── MyCustomPropertyFileConfig.java │ │ │ │ │ │ │ ├── MyNotPickedUpPropertyFileConfig.java │ │ │ │ │ │ │ └── PropertyConfigSourceTest.java │ │ │ │ │ │ ├── exclude/ │ │ │ │ │ │ │ ├── AlwaysActiveBean.java │ │ │ │ │ │ │ ├── CustomExpressionBasedBean.java │ │ │ │ │ │ │ ├── CustomExpressionBasedNoBean.java │ │ │ │ │ │ │ ├── DevBean.java │ │ │ │ │ │ │ ├── DevDbBean.java │ │ │ │ │ │ │ ├── ExcludeTest.java │ │ │ │ │ │ │ ├── ExcludeTestProjectStageDevelopment.java │ │ │ │ │ │ │ ├── ExcludeTestProjectStageEarFileDevelopment.java │ │ │ │ │ │ │ ├── ExcludeTestProjectStageWarFileDevelopment.java │ │ │ │ │ │ │ ├── ExcludeWarFileTest.java │ │ │ │ │ │ │ ├── NoBean.java │ │ │ │ │ │ │ ├── ProdDbBean.java │ │ │ │ │ │ │ ├── SimpleTestExpressionInterpreter.java │ │ │ │ │ │ │ ├── StdBean.java │ │ │ │ │ │ │ └── uc001/ │ │ │ │ │ │ │ ├── BaseEntity1.java │ │ │ │ │ │ │ ├── BaseEntity2.java │ │ │ │ │ │ │ ├── BaseEntity3.java │ │ │ │ │ │ │ ├── Entity1.java │ │ │ │ │ │ │ ├── Entity2.java │ │ │ │ │ │ │ ├── Entity3.java │ │ │ │ │ │ │ └── EntityExcludeTest.java │ │ │ │ │ │ ├── interpreter/ │ │ │ │ │ │ │ └── PropertyExpressionInterpreterTest.java │ │ │ │ │ │ ├── message/ │ │ │ │ │ │ │ ├── CustomMinimalMessages.java │ │ │ │ │ │ │ ├── ElPickedUpMessages.java │ │ │ │ │ │ │ ├── FixedEnglishLocalResolver.java │ │ │ │ │ │ │ ├── FixedGermanLocaleResolver.java │ │ │ │ │ │ │ ├── Jay.java │ │ │ │ │ │ │ ├── MessageContextTest.java │ │ │ │ │ │ │ ├── MessageFormattedMessage.java │ │ │ │ │ │ │ ├── MessageFormattedMessageTest.java │ │ │ │ │ │ │ ├── MessageTest.java │ │ │ │ │ │ │ ├── MessageUser.java │ │ │ │ │ │ │ ├── MinimalMessages.java │ │ │ │ │ │ │ ├── MinimalMessagesTest.java │ │ │ │ │ │ │ ├── SimpleMessage.java │ │ │ │ │ │ │ ├── SimpleMessageTest.java │ │ │ │ │ │ │ ├── TestConfiguration.java │ │ │ │ │ │ │ ├── TestLocalResolver.java │ │ │ │ │ │ │ ├── TestMessageInterpolator.java │ │ │ │ │ │ │ ├── TestMessageResolver.java │ │ │ │ │ │ │ ├── TestMessages.java │ │ │ │ │ │ │ ├── TypedMessageWithCustomName.java │ │ │ │ │ │ │ ├── broken/ │ │ │ │ │ │ │ │ ├── BrokenMessageBundleClass.java │ │ │ │ │ │ │ │ └── BrokenMessageBundleOnClassTest.java │ │ │ │ │ │ │ └── locale/ │ │ │ │ │ │ │ ├── ConfigurableLocaleMessageTest.java │ │ │ │ │ │ │ ├── ConfigurableLocaleResolver.java │ │ │ │ │ │ │ └── MessageWithLocale.java │ │ │ │ │ │ ├── projectstage/ │ │ │ │ │ │ │ ├── ProjectStageProducerTest.java │ │ │ │ │ │ │ ├── ProjectStageTest.java │ │ │ │ │ │ │ └── TestProjectStages.java │ │ │ │ │ │ ├── provider/ │ │ │ │ │ │ │ ├── BeanManagerProviderTest.java │ │ │ │ │ │ │ ├── BeanManagerProviderWarFileTest.java │ │ │ │ │ │ │ ├── BeanProviderTest.java │ │ │ │ │ │ │ ├── DependentTestBean.java │ │ │ │ │ │ │ ├── MBean01.java │ │ │ │ │ │ │ ├── MBean02.java │ │ │ │ │ │ │ ├── ManualBean.java │ │ │ │ │ │ │ ├── MultiBean.java │ │ │ │ │ │ │ ├── NoBean.java │ │ │ │ │ │ │ └── TestBean.java │ │ │ │ │ │ ├── scope/ │ │ │ │ │ │ │ ├── conversation/ │ │ │ │ │ │ │ │ ├── grouped/ │ │ │ │ │ │ │ │ │ ├── explicit/ │ │ │ │ │ │ │ │ │ │ ├── ExplicitTestGroup.java │ │ │ │ │ │ │ │ │ │ ├── ExplicitlyGroupedBeanX.java │ │ │ │ │ │ │ │ │ │ ├── ExplicitlyGroupedBeanY.java │ │ │ │ │ │ │ │ │ │ └── ExplicitlyGroupedConversationsTest.java │ │ │ │ │ │ │ │ │ └── implicit/ │ │ │ │ │ │ │ │ │ ├── ImplicitlyGroupedBean.java │ │ │ │ │ │ │ │ │ └── ImplicitlyGroupedConversationsTest.java │ │ │ │ │ │ │ │ └── subgroup/ │ │ │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ │ │ ├── TestBaseBean.java │ │ │ │ │ │ │ │ │ ├── TestBeanA.java │ │ │ │ │ │ │ │ │ ├── TestBeanB.java │ │ │ │ │ │ │ │ │ ├── TestBeanC.java │ │ │ │ │ │ │ │ │ └── TestGroup.java │ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ │ ├── GroupedConversationSubGroupTest.java │ │ │ │ │ │ │ │ │ └── TestSubGroup.java │ │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ │ ├── GroupedConversationSubGroupTest.java │ │ │ │ │ │ │ │ │ └── TestSubGroup.java │ │ │ │ │ │ │ │ └── uc003/ │ │ │ │ │ │ │ │ ├── GroupedConversationSubGroupTest.java │ │ │ │ │ │ │ │ ├── TestBeanX.java │ │ │ │ │ │ │ │ ├── TestBeanY.java │ │ │ │ │ │ │ │ ├── TestBeanZ.java │ │ │ │ │ │ │ │ ├── TestImplicitSubGroup.java │ │ │ │ │ │ │ │ └── TestSubGroupContract.java │ │ │ │ │ │ │ └── viewaccess/ │ │ │ │ │ │ │ ├── ViewAccessScopedBeanX.java │ │ │ │ │ │ │ ├── ViewAccessScopedBeanY.java │ │ │ │ │ │ │ └── ViewAccessScopedTest.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── MyBean.java │ │ │ │ │ │ ├── MyInterface.java │ │ │ │ │ │ ├── MyInterfaceImpl.java │ │ │ │ │ │ ├── ProxyUtilsTest.java │ │ │ │ │ │ └── context/ │ │ │ │ │ │ ├── AbstractContextTest.java │ │ │ │ │ │ ├── DummyBean.java │ │ │ │ │ │ ├── DummyContext.java │ │ │ │ │ │ ├── DummyScopeExtension.java │ │ │ │ │ │ └── DummyScoped.java │ │ │ │ │ └── impl/ │ │ │ │ │ ├── activation/ │ │ │ │ │ │ ├── ActivatedClass.java │ │ │ │ │ │ ├── ClassDeactivationTest.java │ │ │ │ │ │ ├── ClassDeactivationWarFileTest.java │ │ │ │ │ │ ├── DeactivatedClass.java │ │ │ │ │ │ ├── DefaultClassDeactivatorTest.java │ │ │ │ │ │ └── TestClassDeactivator.java │ │ │ │ │ ├── cipher/ │ │ │ │ │ │ └── DefaultCipherServiceTest.java │ │ │ │ │ ├── custom/ │ │ │ │ │ │ └── spi/ │ │ │ │ │ │ ├── MyImpl.java │ │ │ │ │ │ ├── MyInterface.java │ │ │ │ │ │ ├── ServiceUtilsTest.java │ │ │ │ │ │ └── ServiceUtilsWarFileTest.java │ │ │ │ │ ├── future/ │ │ │ │ │ │ ├── FutureableTest.java │ │ │ │ │ │ ├── Service.java │ │ │ │ │ │ └── ThreadPoolManagerTest.java │ │ │ │ │ ├── interdyn/ │ │ │ │ │ │ ├── InterDynTest.java │ │ │ │ │ │ └── SomeTestService.java │ │ │ │ │ ├── jmx/ │ │ │ │ │ │ ├── CustomProperties.java │ │ │ │ │ │ ├── CustomProperties2.java │ │ │ │ │ │ ├── CustomPropertiesTest.java │ │ │ │ │ │ ├── CustomType.java │ │ │ │ │ │ ├── CustomTypeTest.java │ │ │ │ │ │ ├── MyMBean.java │ │ │ │ │ │ ├── SimpleRegistrationTest.java │ │ │ │ │ │ └── SimpleRegistrationWarFileTest.java │ │ │ │ │ ├── lock/ │ │ │ │ │ │ ├── LockedTest.java │ │ │ │ │ │ └── Service.java │ │ │ │ │ ├── scope/ │ │ │ │ │ │ └── window/ │ │ │ │ │ │ ├── DefaultWindowContextTest.java │ │ │ │ │ │ └── SomeWindowScopedBean.java │ │ │ │ │ ├── throttling/ │ │ │ │ │ │ ├── Service.java │ │ │ │ │ │ ├── Service2.java │ │ │ │ │ │ └── ThrottledTest.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── JndiUtilsTest.java │ │ │ │ │ └── JndiUtilsWarFileTest.java │ │ │ │ └── util/ │ │ │ │ ├── ArchiveUtils.java │ │ │ │ ├── FileUtils.java │ │ │ │ └── activation/ │ │ │ │ ├── EditableTestDeactivator.java │ │ │ │ └── ProjectStageDependentClassDeactivationTest.java │ │ │ └── resources/ │ │ │ ├── META-INF/ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ ├── jakarta.enterprise.inject.spi.Extension │ │ │ │ ├── org.apache.deltaspike.core.api.config.PropertyFileConfig │ │ │ │ ├── org.apache.deltaspike.core.api.projectstage.ProjectStageHolder │ │ │ │ ├── org.apache.deltaspike.core.spi.config.ConfigFilter │ │ │ │ ├── org.apache.deltaspike.core.spi.config.ConfigSource │ │ │ │ └── org.apache.deltaspike.core.spi.config.ConfigSourceProvider │ │ │ ├── application.xml │ │ │ ├── customMinimalMessage_en.properties │ │ │ ├── myboottimeconfig.properties │ │ │ ├── myconfig.properties │ │ │ ├── mynotpickedupconfig.properties │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── test/ │ │ │ └── core/ │ │ │ └── api/ │ │ │ └── message/ │ │ │ ├── MessageFormattedMessage.properties │ │ │ ├── MinimalMessages_en.properties │ │ │ ├── TestMessages_de.properties │ │ │ └── TestMessages_en.properties │ │ └── pom.xml │ ├── dist/ │ │ ├── bom/ │ │ │ └── pom.xml │ │ ├── full/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── distribution/ │ │ │ ├── assembly.xml │ │ │ ├── cdictrl-module.xml │ │ │ ├── core-module.xml │ │ │ └── modules-module.xml │ │ └── pom.xml │ ├── examples/ │ │ ├── data-examples/ │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ ├── Article.java │ │ │ │ ├── ArticleController.java │ │ │ │ ├── ArticleRepository.java │ │ │ │ ├── HttpParam.java │ │ │ │ ├── HttpParams.java │ │ │ │ ├── LogProducer.java │ │ │ │ └── Resources.java │ │ │ ├── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ └── persistence.xml │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── faces-config.xml │ │ │ │ └── web.xml │ │ │ ├── add.xhtml │ │ │ ├── index.xhtml │ │ │ └── list.xhtml │ │ ├── jpa-examples/ │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ ├── Article.java │ │ │ │ ├── ArticleController.java │ │ │ │ ├── HttpParam.java │ │ │ │ ├── HttpParams.java │ │ │ │ ├── LogProducer.java │ │ │ │ └── Resources.java │ │ │ ├── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── persistence.xml │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── faces-config.xml │ │ │ │ └── web.xml │ │ │ ├── add.xhtml │ │ │ ├── index.xhtml │ │ │ └── list.xhtml │ │ ├── jse-examples/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ ├── beanmanagement/ │ │ │ │ │ └── SimpleBeanLookupExample.java │ │ │ │ ├── config/ │ │ │ │ │ ├── ConfigExample.java │ │ │ │ │ ├── CustomConfigPropertyProducer.java │ │ │ │ │ ├── CustomPropertyFileConfig.java │ │ │ │ │ ├── Location.java │ │ │ │ │ ├── LocationId.java │ │ │ │ │ ├── Property2.java │ │ │ │ │ ├── Property2WithInverseSupport.java │ │ │ │ │ └── SettingsBean.java │ │ │ │ ├── echo/ │ │ │ │ │ ├── DefaultEchoService.java │ │ │ │ │ ├── EchoService.java │ │ │ │ │ ├── NoEchoService.java │ │ │ │ │ ├── ToLowerCaseEchoService.java │ │ │ │ │ └── ToUpperCaseEchoService.java │ │ │ │ ├── metadata/ │ │ │ │ │ └── NamingConventionAwareMetadataFilter.java │ │ │ │ └── optional/ │ │ │ │ └── OptionalService.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── apache-deltaspike.properties │ │ │ ├── beans.xml │ │ │ ├── location.properties │ │ │ └── services/ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ ├── jsf-examples/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ ├── message/ │ │ │ │ │ ├── ApplicationMessages.java │ │ │ │ │ ├── ControllerView.java │ │ │ │ │ ├── Custom.java │ │ │ │ │ ├── CustomMessageResolver.java │ │ │ │ │ ├── CustomizedMessages.java │ │ │ │ │ ├── LanguageView.java │ │ │ │ │ └── MessageFormatMessageInterpolator.java │ │ │ │ ├── scope/ │ │ │ │ │ ├── ApplicationScopedBean.java │ │ │ │ │ ├── RequestScopedBean.java │ │ │ │ │ ├── ScopedBean.java │ │ │ │ │ ├── SessionScopedBean.java │ │ │ │ │ ├── ViewAccessScopedBean.java │ │ │ │ │ ├── ViewScopedBean.java │ │ │ │ │ └── WindowScopedBean.java │ │ │ │ ├── viewconfig/ │ │ │ │ │ ├── DenyAllAccessDecisionVoter.java │ │ │ │ │ ├── MyBean.java │ │ │ │ │ ├── PageController.java │ │ │ │ │ └── Pages.java │ │ │ │ └── window/ │ │ │ │ └── SampleClientWindowConfig.java │ │ │ ├── resources/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ └── message/ │ │ │ │ ├── ApplicationMessages_en.properties │ │ │ │ ├── ApplicationMessages_fr.properties │ │ │ │ ├── ApplicationMessages_nl.properties │ │ │ │ └── FacesMessages.properties │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── faces-config.xml │ │ │ │ └── web.xml │ │ │ ├── index.xhtml │ │ │ └── pages/ │ │ │ ├── message/ │ │ │ │ └── jsfMessage.xhtml │ │ │ ├── scopes/ │ │ │ │ ├── scopePage1.xhtml │ │ │ │ └── scopePage2.xhtml │ │ │ └── viewconfig/ │ │ │ ├── allowedPage.xhtml │ │ │ ├── navigationParameterPage.xhtml │ │ │ ├── redirectedPage.xhtml │ │ │ ├── securedPage.xhtml │ │ │ └── viewConfigPage.xhtml │ │ ├── jsf-playground/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── playground/ │ │ │ │ ├── PlaygroundClientWindowConfig.java │ │ │ │ ├── scope/ │ │ │ │ │ └── viewaccess/ │ │ │ │ │ └── ViewAccessScopedBean.java │ │ │ │ └── windowhandling/ │ │ │ │ └── ViewActionController.java │ │ │ ├── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── faces-config.xml │ │ │ │ └── web.xml │ │ │ ├── index.xhtml │ │ │ └── views/ │ │ │ ├── scope/ │ │ │ │ └── viewaccess/ │ │ │ │ ├── test1.xhtml │ │ │ │ ├── test2.xhtml │ │ │ │ └── test3.xhtml │ │ │ └── windowhandling/ │ │ │ ├── clientwindow/ │ │ │ │ └── test.xhtml │ │ │ └── lazy/ │ │ │ ├── test.xhtml │ │ │ ├── testWithoutJS.xhtml │ │ │ └── viewAction.xhtml │ │ ├── pom.xml │ │ ├── scheduler-playground/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ └── scheduler/ │ │ │ │ ├── GlobalResultHolder.java │ │ │ │ ├── RequestScopedNumberProvider.java │ │ │ │ ├── SimpleSchedulerExample.java │ │ │ │ ├── SimpleSchedulerJob1.java │ │ │ │ └── SimpleSchedulerJob2.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ └── beans.xml │ │ ├── security-requested-page-after-login-cdi/ │ │ │ ├── README.md │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── example/ │ │ │ │ └── security/ │ │ │ │ └── requestedpage/ │ │ │ │ └── cdi/ │ │ │ │ ├── AuthenticationListener.java │ │ │ │ ├── LoggedInAccessDecisionVoter.java │ │ │ │ ├── LoginController.java │ │ │ │ ├── Pages.java │ │ │ │ └── UserEvent.java │ │ │ └── webapp/ │ │ │ ├── WEB-INF/ │ │ │ │ ├── beans.xml │ │ │ │ ├── faces-config.xml │ │ │ │ └── web.xml │ │ │ ├── index.html │ │ │ ├── login.xhtml │ │ │ └── secured/ │ │ │ └── home.xhtml │ │ └── security-requested-page-after-login-picketlink/ │ │ ├── README.md │ │ ├── pom.xml │ │ └── src/ │ │ └── main/ │ │ ├── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── example/ │ │ │ └── security/ │ │ │ └── requestedpage/ │ │ │ └── picketlink/ │ │ │ ├── AuthenticationListener.java │ │ │ ├── Initializer.java │ │ │ ├── LoggedInAccessDecisionVoter.java │ │ │ └── Pages.java │ │ └── webapp/ │ │ ├── WEB-INF/ │ │ │ ├── beans.xml │ │ │ ├── faces-config.xml │ │ │ └── web.xml │ │ ├── index.html │ │ ├── login.xhtml │ │ └── secured/ │ │ ├── home.xhtml │ │ └── test.xhtml │ ├── javadoc.sh │ ├── modules/ │ │ ├── data/ │ │ │ ├── README.adoc │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ └── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── data/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── AbstractEntityRepository.java │ │ │ │ │ │ ├── AbstractFullEntityRepository.java │ │ │ │ │ │ ├── EntityCountRepository.java │ │ │ │ │ │ ├── EntityGraph.java │ │ │ │ │ │ ├── EntityGraphType.java │ │ │ │ │ │ ├── EntityManagerConfig.java │ │ │ │ │ │ ├── EntityManagerDelegate.java │ │ │ │ │ │ ├── EntityManagerResolver.java │ │ │ │ │ │ ├── EntityPersistenceRepository.java │ │ │ │ │ │ ├── EntityRepository.java │ │ │ │ │ │ ├── FirstResult.java │ │ │ │ │ │ ├── FullEntityRepository.java │ │ │ │ │ │ ├── MaxResults.java │ │ │ │ │ │ ├── Modifying.java │ │ │ │ │ │ ├── Query.java │ │ │ │ │ │ ├── QueryInvocationException.java │ │ │ │ │ │ ├── QueryParam.java │ │ │ │ │ │ ├── QueryResult.java │ │ │ │ │ │ ├── Repository.java │ │ │ │ │ │ ├── SingleResultType.java │ │ │ │ │ │ ├── audit/ │ │ │ │ │ │ │ ├── CreatedBy.java │ │ │ │ │ │ │ ├── CreatedOn.java │ │ │ │ │ │ │ ├── CurrentUser.java │ │ │ │ │ │ │ ├── ModifiedBy.java │ │ │ │ │ │ │ └── ModifiedOn.java │ │ │ │ │ │ ├── criteria/ │ │ │ │ │ │ │ ├── Criteria.java │ │ │ │ │ │ │ ├── CriteriaSupport.java │ │ │ │ │ │ │ └── QuerySelection.java │ │ │ │ │ │ └── mapping/ │ │ │ │ │ │ ├── MappingConfig.java │ │ │ │ │ │ ├── QueryInOutMapper.java │ │ │ │ │ │ └── SimpleQueryInOutMapperBase.java │ │ │ │ │ └── spi/ │ │ │ │ │ ├── DelegateQueryHandler.java │ │ │ │ │ └── QueryInvocationContext.java │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── data/ │ │ │ │ └── api/ │ │ │ │ └── mapping/ │ │ │ │ └── SimpleQueryInOutMapperBaseTest.java │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── data/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── RepositoryExtension.java │ │ │ │ │ │ ├── audit/ │ │ │ │ │ │ │ ├── AuditEntityListener.java │ │ │ │ │ │ │ ├── AuditPropertyException.java │ │ │ │ │ │ │ ├── AuditProvider.java │ │ │ │ │ │ │ ├── PrePersistAuditListener.java │ │ │ │ │ │ │ ├── PreUpdateAuditListener.java │ │ │ │ │ │ │ ├── PrincipalProvider.java │ │ │ │ │ │ │ └── TimestampsProvider.java │ │ │ │ │ │ ├── builder/ │ │ │ │ │ │ │ ├── AnnotatedQueryBuilder.java │ │ │ │ │ │ │ ├── DelegateQueryBuilder.java │ │ │ │ │ │ │ ├── MethodExpressionException.java │ │ │ │ │ │ │ ├── MethodQueryBuilder.java │ │ │ │ │ │ │ ├── OrderDirection.java │ │ │ │ │ │ │ ├── QueryBuilder.java │ │ │ │ │ │ │ ├── QueryBuilderContext.java │ │ │ │ │ │ │ ├── QueryBuilderFactory.java │ │ │ │ │ │ │ ├── QueryOperator.java │ │ │ │ │ │ │ ├── WrappedQueryBuilder.java │ │ │ │ │ │ │ ├── part/ │ │ │ │ │ │ │ │ ├── AndQueryPart.java │ │ │ │ │ │ │ │ ├── BasePropertyQueryPart.java │ │ │ │ │ │ │ │ ├── ConnectingQueryPart.java │ │ │ │ │ │ │ │ ├── OrQueryPart.java │ │ │ │ │ │ │ │ ├── OrderByQueryPart.java │ │ │ │ │ │ │ │ ├── PropertyQueryPart.java │ │ │ │ │ │ │ │ ├── QueryPart.java │ │ │ │ │ │ │ │ └── QueryRoot.java │ │ │ │ │ │ │ ├── postprocessor/ │ │ │ │ │ │ │ │ ├── CountQueryPostProcessor.java │ │ │ │ │ │ │ │ ├── FirstResultPostProcessor.java │ │ │ │ │ │ │ │ ├── FlushModePostProcessor.java │ │ │ │ │ │ │ │ ├── HintPostProcessor.java │ │ │ │ │ │ │ │ ├── LockModePostProcessor.java │ │ │ │ │ │ │ │ ├── MaxResultPostProcessor.java │ │ │ │ │ │ │ │ └── OrderByQueryStringPostProcessor.java │ │ │ │ │ │ │ └── result/ │ │ │ │ │ │ │ ├── DefaultQueryResult.java │ │ │ │ │ │ │ ├── QueryProcessor.java │ │ │ │ │ │ │ └── QueryProcessorFactory.java │ │ │ │ │ │ ├── criteria/ │ │ │ │ │ │ │ ├── QueryCriteria.java │ │ │ │ │ │ │ ├── predicate/ │ │ │ │ │ │ │ │ ├── Between.java │ │ │ │ │ │ │ │ ├── Eq.java │ │ │ │ │ │ │ │ ├── EqIgnoreCase.java │ │ │ │ │ │ │ │ ├── FetchBuilder.java │ │ │ │ │ │ │ │ ├── GreaterThan.java │ │ │ │ │ │ │ │ ├── GreaterThanOrEqual.java │ │ │ │ │ │ │ │ ├── In.java │ │ │ │ │ │ │ │ ├── IsEmpty.java │ │ │ │ │ │ │ │ ├── IsNotEmpty.java │ │ │ │ │ │ │ │ ├── IsNotNull.java │ │ │ │ │ │ │ │ ├── IsNull.java │ │ │ │ │ │ │ │ ├── JoinBuilder.java │ │ │ │ │ │ │ │ ├── LessThan.java │ │ │ │ │ │ │ │ ├── LessThanOrEqual.java │ │ │ │ │ │ │ │ ├── Like.java │ │ │ │ │ │ │ │ ├── NoValueBuilder.java │ │ │ │ │ │ │ │ ├── NotEq.java │ │ │ │ │ │ │ │ ├── NotEqIgnoreCase.java │ │ │ │ │ │ │ │ ├── NotLike.java │ │ │ │ │ │ │ │ ├── OrBuilder.java │ │ │ │ │ │ │ │ ├── PredicateBuilder.java │ │ │ │ │ │ │ │ └── SingleValueBuilder.java │ │ │ │ │ │ │ ├── processor/ │ │ │ │ │ │ │ │ ├── OrderBy.java │ │ │ │ │ │ │ │ └── QueryProcessor.java │ │ │ │ │ │ │ └── selection/ │ │ │ │ │ │ │ ├── AttributeQuerySelection.java │ │ │ │ │ │ │ ├── SingularAttributeSelection.java │ │ │ │ │ │ │ ├── numeric/ │ │ │ │ │ │ │ │ ├── Abs.java │ │ │ │ │ │ │ │ ├── Avg.java │ │ │ │ │ │ │ │ ├── Count.java │ │ │ │ │ │ │ │ ├── CountDistinct.java │ │ │ │ │ │ │ │ ├── Max.java │ │ │ │ │ │ │ │ ├── Min.java │ │ │ │ │ │ │ │ ├── Modulo.java │ │ │ │ │ │ │ │ ├── Neg.java │ │ │ │ │ │ │ │ └── Sum.java │ │ │ │ │ │ │ ├── strings/ │ │ │ │ │ │ │ │ ├── Lower.java │ │ │ │ │ │ │ │ ├── SubstringFrom.java │ │ │ │ │ │ │ │ ├── SubstringFromTo.java │ │ │ │ │ │ │ │ ├── Trim.java │ │ │ │ │ │ │ │ └── Upper.java │ │ │ │ │ │ │ └── temporal/ │ │ │ │ │ │ │ ├── CurrentDate.java │ │ │ │ │ │ │ ├── CurrentTime.java │ │ │ │ │ │ │ └── CurrentTimestamp.java │ │ │ │ │ │ ├── graph/ │ │ │ │ │ │ │ ├── EntityGraphException.java │ │ │ │ │ │ │ └── EntityGraphHelper.java │ │ │ │ │ │ ├── handler/ │ │ │ │ │ │ │ ├── AbstractDelegateQueryHandler.java │ │ │ │ │ │ │ ├── CdiQueryContextHolder.java │ │ │ │ │ │ │ ├── CdiQueryInvocationContext.java │ │ │ │ │ │ │ ├── CriteriaSupportHandler.java │ │ │ │ │ │ │ ├── EntityManagerDelegateHandler.java │ │ │ │ │ │ │ ├── EntityRepositoryHandler.java │ │ │ │ │ │ │ ├── JpaQueryPostProcessor.java │ │ │ │ │ │ │ ├── QueryHandler.java │ │ │ │ │ │ │ ├── QueryRunner.java │ │ │ │ │ │ │ └── QueryStringPostProcessor.java │ │ │ │ │ │ ├── meta/ │ │ │ │ │ │ │ ├── EntityMetadata.java │ │ │ │ │ │ │ ├── EntityMetadataInitializer.java │ │ │ │ │ │ │ ├── RepositoryMetadata.java │ │ │ │ │ │ │ ├── RepositoryMetadataHandler.java │ │ │ │ │ │ │ ├── RepositoryMetadataInitializer.java │ │ │ │ │ │ │ ├── RepositoryMethodMetadata.java │ │ │ │ │ │ │ ├── RepositoryMethodMetadataInitializer.java │ │ │ │ │ │ │ ├── RepositoryMethodPrefix.java │ │ │ │ │ │ │ ├── RepositoryMethodType.java │ │ │ │ │ │ │ └── RequiresTransaction.java │ │ │ │ │ │ ├── param/ │ │ │ │ │ │ │ ├── IndexedParameter.java │ │ │ │ │ │ │ ├── NamedParameter.java │ │ │ │ │ │ │ ├── Parameter.java │ │ │ │ │ │ │ ├── ParameterUpdate.java │ │ │ │ │ │ │ ├── Parameters.java │ │ │ │ │ │ │ └── ToUpperStringParameterUpdate.java │ │ │ │ │ │ ├── property/ │ │ │ │ │ │ │ ├── FieldProperty.java │ │ │ │ │ │ │ ├── FieldPropertyImpl.java │ │ │ │ │ │ │ ├── MethodProperty.java │ │ │ │ │ │ │ ├── MethodPropertyImpl.java │ │ │ │ │ │ │ ├── Properties.java │ │ │ │ │ │ │ ├── Property.java │ │ │ │ │ │ │ ├── Reflections.java │ │ │ │ │ │ │ └── query/ │ │ │ │ │ │ │ ├── AnnotatedPropertyCriteria.java │ │ │ │ │ │ │ ├── NamedPropertyCriteria.java │ │ │ │ │ │ │ ├── PropertyCriteria.java │ │ │ │ │ │ │ ├── PropertyQueries.java │ │ │ │ │ │ │ ├── PropertyQuery.java │ │ │ │ │ │ │ └── TypedPropertyCriteria.java │ │ │ │ │ │ ├── tx/ │ │ │ │ │ │ │ ├── InvocationContextWrapper.java │ │ │ │ │ │ │ ├── ThreadLocalEntityManagerHolder.java │ │ │ │ │ │ │ └── TransactionalQueryRunner.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── EntityUtils.java │ │ │ │ │ │ ├── QueryUtils.java │ │ │ │ │ │ ├── bean/ │ │ │ │ │ │ │ ├── BeanDestroyable.java │ │ │ │ │ │ │ ├── DependentProviderDestroyable.java │ │ │ │ │ │ │ └── Destroyable.java │ │ │ │ │ │ └── jpa/ │ │ │ │ │ │ ├── BaseQueryStringExtractor.java │ │ │ │ │ │ ├── EclipseLinkEjbQueryStringExtractor.java │ │ │ │ │ │ ├── Hibernate6QueryStringExtractor.java │ │ │ │ │ │ ├── HibernateQueryStringExtractor.java │ │ │ │ │ │ ├── OpenJpaPersistenceUnitUtilDelegate.java │ │ │ │ │ │ ├── OpenJpaQueryStringExtractor.java │ │ │ │ │ │ ├── PersistenceUnitUtilDelegateFactory.java │ │ │ │ │ │ ├── ProviderSpecific.java │ │ │ │ │ │ ├── QueryStringExtractor.java │ │ │ │ │ │ └── QueryStringExtractorFactory.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── data/ │ │ │ │ │ ├── impl/ │ │ │ │ │ │ ├── DisabledRepositoryTest.java │ │ │ │ │ │ ├── QueryResultTest.java │ │ │ │ │ │ ├── RepositoryDeactivator.java │ │ │ │ │ │ ├── RepositoryExtensionTest.java │ │ │ │ │ │ ├── audit/ │ │ │ │ │ │ │ ├── AuditEntityListenerTest.java │ │ │ │ │ │ │ ├── PrincipalProviderTest.java │ │ │ │ │ │ │ └── TimestampsProviderTest.java │ │ │ │ │ │ ├── builder/ │ │ │ │ │ │ │ └── part/ │ │ │ │ │ │ │ └── QueryRootTest.java │ │ │ │ │ │ ├── criteria/ │ │ │ │ │ │ │ └── CriteriaTest.java │ │ │ │ │ │ ├── handler/ │ │ │ │ │ │ │ ├── CdiQueryContextHolderTest.java │ │ │ │ │ │ │ ├── EntityManagerDelegateHandlerTest.java │ │ │ │ │ │ │ ├── EntityManagerTest.java │ │ │ │ │ │ │ ├── EntityRepositoryHandlerInheritedTest.java │ │ │ │ │ │ │ ├── EntityRepositoryHandlerTest.java │ │ │ │ │ │ │ ├── FullEntityRepositoryTest.java │ │ │ │ │ │ │ ├── NamedQualifiedEntityManagerTestProducer.java │ │ │ │ │ │ │ ├── NonQualifiedEntityManagerTestProducer.java │ │ │ │ │ │ │ ├── QualifiedEntityManagerTestProducer.java │ │ │ │ │ │ │ └── QueryHandlerTest.java │ │ │ │ │ │ ├── mapping/ │ │ │ │ │ │ │ └── MappedRepositoryTest.java │ │ │ │ │ │ ├── meta/ │ │ │ │ │ │ │ ├── MethodPrefixTest.java │ │ │ │ │ │ │ └── unit/ │ │ │ │ │ │ │ ├── DescriptorHierarchyBuilderTest.java │ │ │ │ │ │ │ ├── OrmXmlBasedRepositoryTest.java │ │ │ │ │ │ │ └── PersistenceUnitsTest.java │ │ │ │ │ │ ├── property/ │ │ │ │ │ │ │ ├── ClassToIntrospect.java │ │ │ │ │ │ │ ├── PropertyFromFieldTest.java │ │ │ │ │ │ │ ├── PropertyFromMethodTest.java │ │ │ │ │ │ │ └── query/ │ │ │ │ │ │ │ └── PropertyQueryTest.java │ │ │ │ │ │ ├── spi/ │ │ │ │ │ │ │ └── CdiQuerySpiTest.java │ │ │ │ │ │ ├── tx/ │ │ │ │ │ │ │ ├── TransactionalQueryRunnerTest.java │ │ │ │ │ │ │ └── TransactionalQueryRunnerWrapper.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── EntityUtilsTest.java │ │ │ │ │ │ └── jpa/ │ │ │ │ │ │ └── QueryStringExtractorFactoryTest.java │ │ │ │ │ └── test/ │ │ │ │ │ ├── BMTransactionStrategy.java │ │ │ │ │ ├── JpaTransactionStrategy.java │ │ │ │ │ ├── TestTransactionStrategy.java │ │ │ │ │ ├── TransactionalTestCase.java │ │ │ │ │ ├── domain/ │ │ │ │ │ │ ├── AuditedEntity.java │ │ │ │ │ │ ├── EmbeddedSimple.java │ │ │ │ │ │ ├── Home.java │ │ │ │ │ │ ├── NamedEntity.java │ │ │ │ │ │ ├── OneToMany.java │ │ │ │ │ │ ├── OneToOne.java │ │ │ │ │ │ ├── Parent.java │ │ │ │ │ │ ├── Principal.java │ │ │ │ │ │ ├── Simple.java │ │ │ │ │ │ ├── Simple2.java │ │ │ │ │ │ ├── Simple3.java │ │ │ │ │ │ ├── Simple4.java │ │ │ │ │ │ ├── Simple5.java │ │ │ │ │ │ ├── SimpleBase.java │ │ │ │ │ │ ├── SimpleBuilder.java │ │ │ │ │ │ ├── SimpleStringId.java │ │ │ │ │ │ ├── SimpleStringIdBuilder.java │ │ │ │ │ │ ├── SuperSimple.java │ │ │ │ │ │ ├── Tee.java │ │ │ │ │ │ ├── Tee2.java │ │ │ │ │ │ ├── TeeId.java │ │ │ │ │ │ ├── dto/ │ │ │ │ │ │ │ ├── BooleanWrapper.java │ │ │ │ │ │ │ ├── SimpleDto.java │ │ │ │ │ │ │ └── SimpleId.java │ │ │ │ │ │ └── mapped/ │ │ │ │ │ │ ├── MappedId.java │ │ │ │ │ │ ├── MappedOne.java │ │ │ │ │ │ ├── MappedSuperclass.java │ │ │ │ │ │ ├── MappedThree.java │ │ │ │ │ │ └── MappedTwo.java │ │ │ │ │ ├── java8/ │ │ │ │ │ │ ├── entity/ │ │ │ │ │ │ │ └── Simple.java │ │ │ │ │ │ ├── repo/ │ │ │ │ │ │ │ ├── SimpleRepository.java │ │ │ │ │ │ │ └── SimpleRepository2.java │ │ │ │ │ │ ├── test/ │ │ │ │ │ │ │ └── Java8Test.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── EntityManagerProducer.java │ │ │ │ │ │ └── TestDeployments.java │ │ │ │ │ ├── service/ │ │ │ │ │ │ ├── BaseRepositoryInterface.java │ │ │ │ │ │ ├── BasicEntityManagerResolver.java │ │ │ │ │ │ ├── DisabledRepository.java │ │ │ │ │ │ ├── ExtendedRepositoryAbstract.java │ │ │ │ │ │ ├── ExtendedRepositoryAbstract2.java │ │ │ │ │ │ ├── ExtendedRepositoryAbstract4.java │ │ │ │ │ │ ├── ExtendedRepositoryAbstractInherited.java │ │ │ │ │ │ ├── ExtendedRepositoryAbstractIntermediate.java │ │ │ │ │ │ ├── ExtendedRepositoryInterface.java │ │ │ │ │ │ ├── ExtendedRepositoryInterface2.java │ │ │ │ │ │ ├── FullRepositoryAbstract.java │ │ │ │ │ │ ├── FullRepositoryInterface.java │ │ │ │ │ │ ├── HomeRepository.java │ │ │ │ │ │ ├── LegacyRepositoryWithEntityManagerResolver.java │ │ │ │ │ │ ├── MappedOneRepository.java │ │ │ │ │ │ ├── MyEntityRepository.java │ │ │ │ │ │ ├── MyEntityRepositoryDelegate.java │ │ │ │ │ │ ├── MySimpleRepository.java │ │ │ │ │ │ ├── ParentRepository.java │ │ │ │ │ │ ├── RepositoryInterface.java │ │ │ │ │ │ ├── Simple2Repository.java │ │ │ │ │ │ ├── SimpleCriteriaRepository.java │ │ │ │ │ │ ├── SimpleFetchRepository.java │ │ │ │ │ │ ├── SimpleIntermediateRepository.java │ │ │ │ │ │ ├── SimpleMappedDtoRepository.java │ │ │ │ │ │ ├── SimpleMappedRepository.java │ │ │ │ │ │ ├── SimpleMapper.java │ │ │ │ │ │ ├── SimpleQueryInOutMapper.java │ │ │ │ │ │ ├── SimpleRepository.java │ │ │ │ │ │ ├── SimpleRepositoryWithEntityManager.java │ │ │ │ │ │ ├── SimpleRepositoryWithEntityManagerResolver.java │ │ │ │ │ │ ├── SimpleStringIdRepository.java │ │ │ │ │ │ ├── Simplistic.java │ │ │ │ │ │ ├── SimplisticEntityManagerResolver.java │ │ │ │ │ │ ├── Statistics.java │ │ │ │ │ │ └── WrappedMapper.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── EntityManagerProducer.java │ │ │ │ │ ├── Logging.java │ │ │ │ │ ├── TestData.java │ │ │ │ │ └── TestDeployments.java │ │ │ │ ├── resources/ │ │ │ │ │ ├── disabled/ │ │ │ │ │ │ └── META-INF/ │ │ │ │ │ │ └── apache-deltaspike.properties │ │ │ │ │ ├── log4j.xml │ │ │ │ │ ├── logging.properties │ │ │ │ │ ├── test-custom-orm.xml │ │ │ │ │ ├── test-default-orm.xml │ │ │ │ │ └── test-orm.xml │ │ │ │ ├── resources-openejb/ │ │ │ │ │ ├── test-mapped-persistence.xml │ │ │ │ │ └── test-persistence.xml │ │ │ │ ├── resources-payara/ │ │ │ │ │ ├── test-mapped-persistence.xml │ │ │ │ │ └── test-persistence.xml │ │ │ │ ├── resources-weblogic/ │ │ │ │ │ ├── test-mapped-persistence.xml │ │ │ │ │ └── test-persistence.xml │ │ │ │ └── resources-wildfly/ │ │ │ │ ├── test-mapped-persistence.xml │ │ │ │ └── test-persistence.xml │ │ │ └── pom.xml │ │ ├── jpa/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── jpa/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ └── base/ │ │ │ │ │ │ │ └── JpaBaseConfig.java │ │ │ │ │ │ ├── entitymanager/ │ │ │ │ │ │ │ ├── EntityManagerConfig.java │ │ │ │ │ │ │ ├── EntityManagerResolver.java │ │ │ │ │ │ │ └── PersistenceUnitName.java │ │ │ │ │ │ └── transaction/ │ │ │ │ │ │ ├── TransactionConfig.java │ │ │ │ │ │ ├── TransactionHelper.java │ │ │ │ │ │ ├── TransactionScoped.java │ │ │ │ │ │ └── Transactional.java │ │ │ │ │ └── spi/ │ │ │ │ │ ├── descriptor/ │ │ │ │ │ │ └── xml/ │ │ │ │ │ │ ├── AbstractEntityDescriptor.java │ │ │ │ │ │ ├── AbstractEntityHierarchyBuilder.java │ │ │ │ │ │ ├── Descriptor.java │ │ │ │ │ │ ├── DescriptorReader.java │ │ │ │ │ │ ├── EntityDescriptor.java │ │ │ │ │ │ ├── EntityMappingsDescriptor.java │ │ │ │ │ │ ├── EntityMappingsDescriptorParser.java │ │ │ │ │ │ ├── MappedSuperclassDescriptor.java │ │ │ │ │ │ ├── PersistenceUnitDescriptor.java │ │ │ │ │ │ ├── PersistenceUnitDescriptorParser.java │ │ │ │ │ │ └── PersistenceUnitDescriptorProvider.java │ │ │ │ │ ├── entitymanager/ │ │ │ │ │ │ ├── ActiveEntityManagerHolder.java │ │ │ │ │ │ ├── PersistenceConfigurationProvider.java │ │ │ │ │ │ └── QualifierBackedEntityManagerResolver.java │ │ │ │ │ └── transaction/ │ │ │ │ │ └── TransactionStrategy.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── jpa/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── descriptor/ │ │ │ │ │ │ │ └── xml/ │ │ │ │ │ │ │ └── PersistenceUnitDescriptorInitExtension.java │ │ │ │ │ │ ├── entitymanager/ │ │ │ │ │ │ │ ├── DefaultEntityManagerHolder.java │ │ │ │ │ │ │ ├── EntityManagerFactoryProducer.java │ │ │ │ │ │ │ ├── EntityManagerMetadata.java │ │ │ │ │ │ │ ├── EntityManagerRef.java │ │ │ │ │ │ │ ├── EntityManagerRefLookup.java │ │ │ │ │ │ │ └── PersistenceConfigurationProviderImpl.java │ │ │ │ │ │ └── transaction/ │ │ │ │ │ │ ├── BeanManagedUserTransactionStrategy.java │ │ │ │ │ │ ├── ContainerManagedTransactionStrategy.java │ │ │ │ │ │ ├── EnvironmentAwareTransactionStrategy.java │ │ │ │ │ │ ├── ManagedUserTransactionResolver.java │ │ │ │ │ │ ├── ResourceLocalTransactionStrategy.java │ │ │ │ │ │ ├── TransactionStrategyHelper.java │ │ │ │ │ │ ├── TransactionalInterceptor.java │ │ │ │ │ │ ├── UserTransactionResolver.java │ │ │ │ │ │ └── context/ │ │ │ │ │ │ ├── EntityManagerEntry.java │ │ │ │ │ │ ├── TransactionBeanEntry.java │ │ │ │ │ │ ├── TransactionBeanStorage.java │ │ │ │ │ │ ├── TransactionContext.java │ │ │ │ │ │ └── TransactionContextExtension.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ ├── jpa/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── entitymanager/ │ │ │ │ │ │ │ │ ├── EntityManagerFactoryProducerTest.java │ │ │ │ │ │ │ │ ├── PersistenceConfigurationProviderTest.java │ │ │ │ │ │ │ │ ├── SampleDb.java │ │ │ │ │ │ │ │ ├── SampleEntityManagerProducer.java │ │ │ │ │ │ │ │ └── TestPersistenceProviderResolver.java │ │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ │ ├── First.java │ │ │ │ │ │ │ │ ├── Second.java │ │ │ │ │ │ │ │ ├── TestEntityManager.java │ │ │ │ │ │ │ │ ├── TestEntityTransaction.java │ │ │ │ │ │ │ │ └── TestException.java │ │ │ │ │ │ │ ├── transactional/ │ │ │ │ │ │ │ │ ├── aggregation/ │ │ │ │ │ │ │ │ │ ├── AggregatedDefaultEntityManagerInjectionTest.java │ │ │ │ │ │ │ │ │ ├── BeanA.java │ │ │ │ │ │ │ │ │ ├── BeanB.java │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ │ │ ├── defaultinjection/ │ │ │ │ │ │ │ │ │ ├── DefaultEntityManagerInjectionTest.java │ │ │ │ │ │ │ │ │ ├── Failed.java │ │ │ │ │ │ │ │ │ ├── FailedFlushTransactionalBean.java │ │ │ │ │ │ │ │ │ ├── FailedTransactionalBean.java │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ │ │ ├── defaultnested/ │ │ │ │ │ │ │ │ │ ├── DefaultNestedTransactionTest.java │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── exception/ │ │ │ │ │ │ │ │ │ ├── catched/ │ │ │ │ │ │ │ │ │ │ ├── multipleinjection/ │ │ │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ ├── NestedMultiTransactionCatchedExceptionTest.java │ │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionCatchedExceptionTest.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── uncatched/ │ │ │ │ │ │ │ │ │ ├── multipleinjection/ │ │ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ │ │ └── UncatchedExceptionTest.java │ │ │ │ │ │ │ │ │ │ ├── flush/ │ │ │ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ │ │ │ └── UncatchedFlushExceptionTest.java │ │ │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ │ │ └── UncatchedFlushExceptionTest.java │ │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ │ └── UncatchedExceptionTest.java │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionWithExceptionTest.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── getRollbackOnly/ │ │ │ │ │ │ │ │ │ └── multipleinjection/ │ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── RollbackOnly1Test.java │ │ │ │ │ │ │ │ │ │ ├── RollbackOnly2Test.java │ │ │ │ │ │ │ │ │ │ ├── RollbackOnlyTest.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedMultiTransactionRollbackOnlyTest.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── multipleinjection/ │ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── MultipleEntityManagerInjectionTest.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ ├── manual/ │ │ │ │ │ │ │ │ │ │ ├── BeanManagedlTransactionTest.java │ │ │ │ │ │ │ │ │ │ ├── ManualTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── ManualTransactionTest.java │ │ │ │ │ │ │ │ │ │ ├── MockUserTransactionResolver.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedMultiTransactionTest.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── nested/ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionTest.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── noentitymanager/ │ │ │ │ │ │ │ │ │ ├── NoEntityManagerProducerTest.java │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ │ │ ├── readonly/ │ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── MultipleEntityManagerInjectionReadOnlyTest.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ │ ├── norollback/ │ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ │ ├── NestedMultiTransactionReadOnlyNoRollbackTest.java │ │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── rollback/ │ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ │ ├── NestedMultiTransactionReadOnlyRollbackTest.java │ │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── stereotype/ │ │ │ │ │ │ │ │ │ ├── Repository.java │ │ │ │ │ │ │ │ │ ├── StereotypeTransactionalTest.java │ │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ │ │ └── transactionhelper/ │ │ │ │ │ │ │ │ ├── TransactionHelperTest.java │ │ │ │ │ │ │ │ └── TransactionScopedEntityManagerProducer.java │ │ │ │ │ │ │ └── transactionscoped/ │ │ │ │ │ │ │ ├── defaultinjection/ │ │ │ │ │ │ │ │ ├── DefaultTransactionScopedEntityManagerInjectionTest.java │ │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ │ ├── defaultnested/ │ │ │ │ │ │ │ │ ├── DefaultTransactionScopedNestedTransactionTest.java │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ ├── multipleinjection/ │ │ │ │ │ │ │ │ ├── auto/ │ │ │ │ │ │ │ │ │ ├── MultiTransactionBean.java │ │ │ │ │ │ │ │ │ ├── MultipleTransactionScopedEntityManagerInjectionTest.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ ├── manual/ │ │ │ │ │ │ │ │ │ ├── ManualTransactionBean.java │ │ │ │ │ │ │ │ │ ├── ManualTransactionScopedTransactionTest.java │ │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ │ └── nested/ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ ├── NestedMultiTransactionScopedTransactionTest.java │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ ├── nested/ │ │ │ │ │ │ │ │ ├── FirstLevelTransactionBean.java │ │ │ │ │ │ │ │ ├── NestedTransactionBean.java │ │ │ │ │ │ │ │ ├── NestedTransactionScopedTransactionTest.java │ │ │ │ │ │ │ │ └── TestEntityManagerProducer.java │ │ │ │ │ │ │ └── stereotype/ │ │ │ │ │ │ │ ├── Repository.java │ │ │ │ │ │ │ ├── StereotypeTransactionScopedTransactionalTest.java │ │ │ │ │ │ │ ├── TestEntityManagerProducer.java │ │ │ │ │ │ │ ├── TestEntityTransactionHolder.java │ │ │ │ │ │ │ └── TransactionalBean.java │ │ │ │ │ │ ├── datasource/ │ │ │ │ │ │ │ ├── DummyConnection.java │ │ │ │ │ │ │ └── DummyJdbcDriver.java │ │ │ │ │ │ └── spi/ │ │ │ │ │ │ └── descriptor/ │ │ │ │ │ │ └── xml/ │ │ │ │ │ │ ├── EntityMappingsDescriptorParserTest.java │ │ │ │ │ │ ├── MappedId.java │ │ │ │ │ │ ├── MappedOne.java │ │ │ │ │ │ ├── MappedSuperclass.java │ │ │ │ │ │ ├── MappedThree.java │ │ │ │ │ │ ├── MappedTwo.java │ │ │ │ │ │ ├── PersistenceUnitDescriptorParserTest.java │ │ │ │ │ │ ├── PersistenceUnitDescriptorProviderTest.java │ │ │ │ │ │ └── TeeId.java │ │ │ │ │ └── util/ │ │ │ │ │ └── ArchiveUtils.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ │ ├── beans.xml │ │ │ │ │ ├── persistence.xml │ │ │ │ │ └── test-orm.xml │ │ │ │ └── persistence-MyUnit.properties │ │ │ └── pom.xml │ │ ├── jsf/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── jsf/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ │ ├── JsfModuleConfig.java │ │ │ │ │ │ │ │ ├── base/ │ │ │ │ │ │ │ │ │ └── JsfBaseConfig.java │ │ │ │ │ │ │ │ └── view/ │ │ │ │ │ │ │ │ ├── Folder.java │ │ │ │ │ │ │ │ └── View.java │ │ │ │ │ │ │ ├── listener/ │ │ │ │ │ │ │ │ └── phase/ │ │ │ │ │ │ │ │ ├── AfterPhase.java │ │ │ │ │ │ │ │ ├── BeforePhase.java │ │ │ │ │ │ │ │ ├── JsfPhaseId.java │ │ │ │ │ │ │ │ └── JsfPhaseListener.java │ │ │ │ │ │ │ ├── literal/ │ │ │ │ │ │ │ │ ├── FolderLiteral.java │ │ │ │ │ │ │ │ └── ViewLiteral.java │ │ │ │ │ │ │ └── message/ │ │ │ │ │ │ │ └── JsfMessage.java │ │ │ │ │ │ ├── spi/ │ │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ │ └── view/ │ │ │ │ │ │ │ │ └── navigation/ │ │ │ │ │ │ │ │ └── NavigationParameterStrategy.java │ │ │ │ │ │ │ └── scope/ │ │ │ │ │ │ │ └── window/ │ │ │ │ │ │ │ ├── ClientWindowConfig.java │ │ │ │ │ │ │ └── DefaultClientWindowConfig.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── NamingConventionUtils.java │ │ │ │ │ │ └── ValueExpressionEvaluationInputStream.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── beans.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── jsf/ │ │ │ │ └── util/ │ │ │ │ └── ValueExpressionEvaluationInputStreamTest.java │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── jsf/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── clientwindow/ │ │ │ │ │ │ │ ├── ClientSideClientWindow.java │ │ │ │ │ │ │ ├── DeltaSpikeClientWindow.java │ │ │ │ │ │ │ └── LazyClientWindow.java │ │ │ │ │ │ ├── component/ │ │ │ │ │ │ │ ├── token/ │ │ │ │ │ │ │ │ ├── PostRequestTokenComponent.java │ │ │ │ │ │ │ │ └── RequestTokenHtmlRenderer.java │ │ │ │ │ │ │ └── window/ │ │ │ │ │ │ │ ├── WindowIdComponent.java │ │ │ │ │ │ │ └── WindowIdHtmlRenderer.java │ │ │ │ │ │ ├── config/ │ │ │ │ │ │ │ └── view/ │ │ │ │ │ │ │ ├── AbstractConfigNode.java │ │ │ │ │ │ │ ├── AbstractPathConfigDescriptor.java │ │ │ │ │ │ │ ├── DefaultConfigNodeConverter.java │ │ │ │ │ │ │ ├── DefaultErrorViewAwareExceptionHandlerWrapper.java │ │ │ │ │ │ │ ├── DefaultFolderConfigDescriptor.java │ │ │ │ │ │ │ ├── DefaultViewConfigInheritanceStrategy.java │ │ │ │ │ │ │ ├── DefaultViewConfigResolver.java │ │ │ │ │ │ │ ├── DefaultViewPathConfigDescriptor.java │ │ │ │ │ │ │ ├── FolderConfigNode.java │ │ │ │ │ │ │ ├── PageViewConfigNode.java │ │ │ │ │ │ │ ├── ViewConfigExtension.java │ │ │ │ │ │ │ ├── ViewConfigPathValidator.java │ │ │ │ │ │ │ ├── ViewConfigResolverProducer.java │ │ │ │ │ │ │ ├── ViewControllerActionListener.java │ │ │ │ │ │ │ └── navigation/ │ │ │ │ │ │ │ ├── DefaultNavigationParameterContext.java │ │ │ │ │ │ │ ├── DefaultNavigationParameterStrategy.java │ │ │ │ │ │ │ ├── DefaultViewNavigationHandler.java │ │ │ │ │ │ │ ├── NavigationCaseMapWrapper.java │ │ │ │ │ │ │ ├── NavigationParameterInterceptor.java │ │ │ │ │ │ │ ├── NavigationParameterListInterceptor.java │ │ │ │ │ │ │ └── ViewConfigAwareNavigationHandler.java │ │ │ │ │ │ ├── exception/ │ │ │ │ │ │ │ └── control/ │ │ │ │ │ │ │ └── BridgeExceptionHandlerWrapper.java │ │ │ │ │ │ ├── listener/ │ │ │ │ │ │ │ ├── action/ │ │ │ │ │ │ │ │ └── DeltaSpikeActionListener.java │ │ │ │ │ │ │ ├── phase/ │ │ │ │ │ │ │ │ ├── AfterPhaseBinding.java │ │ │ │ │ │ │ │ ├── BeforePhaseBinding.java │ │ │ │ │ │ │ │ ├── DeltaSpikePhaseListener.java │ │ │ │ │ │ │ │ ├── JsfRequestLifecycleBroadcaster.java │ │ │ │ │ │ │ │ ├── JsfRequestLifecyclePhaseListener.java │ │ │ │ │ │ │ │ └── WindowMetaData.java │ │ │ │ │ │ │ ├── request/ │ │ │ │ │ │ │ │ ├── DeltaSpikeApplicationWrapper.java │ │ │ │ │ │ │ │ ├── DeltaSpikeExternalContextWrapper.java │ │ │ │ │ │ │ │ ├── DeltaSpikeFacesContextFactory.java │ │ │ │ │ │ │ │ ├── DeltaSpikeFacesContextWrapper.java │ │ │ │ │ │ │ │ ├── DeltaSpikeLifecycleFactoryWrapper.java │ │ │ │ │ │ │ │ ├── DeltaSpikeLifecycleWrapper.java │ │ │ │ │ │ │ │ └── JsfRequestBroadcaster.java │ │ │ │ │ │ │ └── system/ │ │ │ │ │ │ │ └── JsfSystemEventBroadcaster.java │ │ │ │ │ │ ├── message/ │ │ │ │ │ │ │ ├── DefaultJsfMessage.java │ │ │ │ │ │ │ ├── FacesMessageEntry.java │ │ │ │ │ │ │ ├── JsfAwareLocaleResolver.java │ │ │ │ │ │ │ ├── JsfMessageBundleInvocationHandler.java │ │ │ │ │ │ │ ├── JsfMessageProducer.java │ │ │ │ │ │ │ └── JsfMessageResolver.java │ │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ │ ├── DeltaSpikeNavigationHandler.java │ │ │ │ │ │ │ ├── DeltaSpikeNavigationHandlerWrapper.java │ │ │ │ │ │ │ └── NavigationHandlerAwareApplication.java │ │ │ │ │ │ ├── resource/ │ │ │ │ │ │ │ ├── DeltaSpikeResource.java │ │ │ │ │ │ │ └── DeltaSpikeResourceHandler.java │ │ │ │ │ │ ├── scope/ │ │ │ │ │ │ │ ├── viewaccess/ │ │ │ │ │ │ │ │ └── ViewAccessScopedAwareNavigationHandler.java │ │ │ │ │ │ │ └── window/ │ │ │ │ │ │ │ └── JsfWindowContextQuotaHandler.java │ │ │ │ │ │ ├── security/ │ │ │ │ │ │ │ ├── SecurityAwareViewHandler.java │ │ │ │ │ │ │ └── ViewRootAccessHandler.java │ │ │ │ │ │ ├── token/ │ │ │ │ │ │ │ ├── DoubleSubmitAwarePhaseListener.java │ │ │ │ │ │ │ ├── PostRequestTokenManager.java │ │ │ │ │ │ │ └── PostRequestTokenMarker.java │ │ │ │ │ │ ├── util/ │ │ │ │ │ │ │ ├── ClientWindowHelper.java │ │ │ │ │ │ │ ├── JsfUtils.java │ │ │ │ │ │ │ ├── RequestParameter.java │ │ │ │ │ │ │ ├── SecurityUtils.java │ │ │ │ │ │ │ ├── SharedStringBuilder.java │ │ │ │ │ │ │ ├── ViewConfigUtils.java │ │ │ │ │ │ │ └── ViewControllerUtils.java │ │ │ │ │ │ └── view/ │ │ │ │ │ │ └── DeltaSpikeViewHandler.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── beans.xml │ │ │ │ │ │ ├── deltaspike.taglib.xml │ │ │ │ │ │ ├── faces-config.xml │ │ │ │ │ │ ├── resources/ │ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ │ └── windowhandler.js │ │ │ │ │ │ ├── services/ │ │ │ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ │ │ │ └── web-fragment.xml │ │ │ │ │ └── static/ │ │ │ │ │ └── windowhandler.html │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ └── jsf/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── config/ │ │ │ │ │ │ ├── TestJsfModuleConfig.java │ │ │ │ │ │ └── view/ │ │ │ │ │ │ ├── controller/ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ ├── PageBean001.java │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── ViewConfigTest.java │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ ├── PageBean002.java │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── ViewConfigTest.java │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ ├── PageBean003.java │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── ViewConfigTest.java │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ ├── PageBean004.java │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── SimpleTestAccessDecisionVoter.java │ │ │ │ │ │ │ │ ├── TestAccessDecisionVoter.java │ │ │ │ │ │ │ │ ├── TestSecured.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ └── uc005/ │ │ │ │ │ │ │ ├── PageBean005.java │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ ├── SecuredStereotype1.java │ │ │ │ │ │ │ ├── SecuredStereotype2.java │ │ │ │ │ │ │ ├── SimpleTestAccessDecisionVoter1.java │ │ │ │ │ │ │ ├── SimpleTestAccessDecisionVoter2.java │ │ │ │ │ │ │ ├── TestAccessDecisionVoter.java │ │ │ │ │ │ │ ├── TestSecured.java │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ ├── custom/ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── TestEntryPoint.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ ├── CustomMetaData.java │ │ │ │ │ │ │ │ ├── PageBean002.java │ │ │ │ │ │ │ │ └── Pages.java │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ ├── CustomStaticQuota.java │ │ │ │ │ │ │ │ ├── CustomUrlMapping.java │ │ │ │ │ │ │ │ ├── PageBean003.java │ │ │ │ │ │ │ │ └── Pages.java │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ ├── PageBean004.java │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── TestFacesRedirect.java │ │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ │ ├── InvalidPageConfig.java │ │ │ │ │ │ │ │ ├── TestInvalidConfigDescriptorValidator.java │ │ │ │ │ │ │ │ ├── TestValidConfigDescriptorValidator.java │ │ │ │ │ │ │ │ ├── ValidPageConfig.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ ├── TestConfigPreProcessor.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc007/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ └── uc008/ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ ├── TestMenuEntry.java │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ ├── folder/ │ │ │ │ │ │ │ └── uc001/ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ ├── navigation/ │ │ │ │ │ │ │ ├── destination/ │ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ │ ├── PageBean001.java │ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ │ ├── PageBean002.java │ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ │ ├── PageBean003.java │ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ │ ├── PagesViolation.java │ │ │ │ │ │ │ │ │ ├── ViewConfigTest.java │ │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ │ ├── PageBean004.java │ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ │ ├── ViewConfigTest.java │ │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ │ ├── ViewConfigPathTest.java │ │ │ │ │ │ │ │ │ └── ViewConfigPreProcessorWithoutValidation.java │ │ │ │ │ │ │ │ └── uc006/ │ │ │ │ │ │ │ │ ├── PageBean006.java │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ ├── PagesViolation.java │ │ │ │ │ │ │ │ ├── ViewConfigBasePathValidationTest.java │ │ │ │ │ │ │ │ └── ViewConfigTestDrone.java │ │ │ │ │ │ │ ├── event/ │ │ │ │ │ │ │ │ └── uc001/ │ │ │ │ │ │ │ │ ├── PageBean002.java │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── PreViewConfigNavigateEventTest.java │ │ │ │ │ │ │ ├── parameter/ │ │ │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ │ │ └── TestClassDeactivator.java │ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ │ ├── NoNavigationParameterWarFileTest.java │ │ │ │ │ │ │ │ │ ├── PageBean001.java │ │ │ │ │ │ │ │ │ └── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ │ ├── PageBean002.java │ │ │ │ │ │ │ │ │ ├── SimplePageConfig.java │ │ │ │ │ │ │ │ │ └── StaticNavigationParameterWarFileTest.java │ │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ │ ├── NavigationParameterTest.java │ │ │ │ │ │ │ │ │ ├── PageBean003.java │ │ │ │ │ │ │ │ │ └── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ │ ├── DynamicNavigationParameterWarFileTest.java │ │ │ │ │ │ │ │ │ ├── NavigationParameterTest.java │ │ │ │ │ │ │ │ │ ├── PageBean004.java │ │ │ │ │ │ │ │ │ └── SimplePageConfig.java │ │ │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ │ │ ├── NavigationParameterTest.java │ │ │ │ │ │ │ │ │ ├── PageBean005.java │ │ │ │ │ │ │ │ │ └── Pages.java │ │ │ │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ │ │ │ ├── NavigationParameterTest.java │ │ │ │ │ │ │ │ │ ├── PageBean006.java │ │ │ │ │ │ │ │ │ └── Pages.java │ │ │ │ │ │ │ │ └── uc007/ │ │ │ │ │ │ │ │ ├── PageBean007.java │ │ │ │ │ │ │ │ └── ViewConfigForIncludeViewParams.java │ │ │ │ │ │ │ └── syntax/ │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ ├── SimplePageConfig001.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ ├── SimplePageConfig002.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc007/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ ├── TestFacesRedirect.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc008/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc009/ │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ ├── uc010/ │ │ │ │ │ │ │ │ ├── MyView.java │ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ │ └── uc011/ │ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ │ └── ViewConfigTest.java │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ ├── Pages.java │ │ │ │ │ │ └── ViewConfigPathValidatorTest.java │ │ │ │ │ ├── injection/ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ ├── AnotherBean.java │ │ │ │ │ │ │ ├── AnotherBeanConverter.java │ │ │ │ │ │ │ ├── InjectionDroneTest.java │ │ │ │ │ │ │ ├── MyBean.java │ │ │ │ │ │ │ └── MyBeanValidator.java │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ ├── AnotherBean.java │ │ │ │ │ │ │ ├── AnotherBeanConverter.java │ │ │ │ │ │ │ ├── InjectionDroneTest.java │ │ │ │ │ │ │ ├── MyBean.java │ │ │ │ │ │ │ └── MyBeanValidator.java │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ ├── AbstractStateHolder.java │ │ │ │ │ │ │ ├── AnotherBean.java │ │ │ │ │ │ │ ├── AnotherBeanConverter.java │ │ │ │ │ │ │ ├── InjectionDroneTest.java │ │ │ │ │ │ │ ├── MyBean.java │ │ │ │ │ │ │ └── MyBeanValidator.java │ │ │ │ │ │ └── uc004/ │ │ │ │ │ │ ├── AnotherBean.java │ │ │ │ │ │ ├── AnotherBeanConverter.java │ │ │ │ │ │ ├── InjectionDroneTest.java │ │ │ │ │ │ ├── MyBean.java │ │ │ │ │ │ └── MyBeanValidator.java │ │ │ │ │ ├── message/ │ │ │ │ │ │ ├── JsfMessageTest.java │ │ │ │ │ │ └── beans/ │ │ │ │ │ │ ├── JsfMessageBackingBean.java │ │ │ │ │ │ └── UserMessage.java │ │ │ │ │ ├── scope/ │ │ │ │ │ │ ├── view/ │ │ │ │ │ │ │ └── beans/ │ │ │ │ │ │ │ └── ViewScopedBackingBean.java │ │ │ │ │ │ ├── viewaccess/ │ │ │ │ │ │ │ ├── ViewAccessScopedWebAppTest.java │ │ │ │ │ │ │ ├── ViewAccessScopedWithFViewActionWebAppTest.java │ │ │ │ │ │ │ └── beans/ │ │ │ │ │ │ │ ├── ViewAccessScopedBeanX.java │ │ │ │ │ │ │ └── ViewAccessScopedBeanY.java │ │ │ │ │ │ └── window/ │ │ │ │ │ │ ├── MyWindowScopedBean.java │ │ │ │ │ │ ├── WindowMaxCountTest.java │ │ │ │ │ │ ├── WindowScopedContextFrameTest.java │ │ │ │ │ │ ├── WindowScopedContextTest.java │ │ │ │ │ │ └── beans/ │ │ │ │ │ │ ├── WindowAccessBean.java │ │ │ │ │ │ └── WindowScopedBackingBean.java │ │ │ │ │ └── util/ │ │ │ │ │ ├── ArchiveUtils.java │ │ │ │ │ ├── FileUtils.java │ │ │ │ │ └── JsfUtilsTest.java │ │ │ │ └── resources/ │ │ │ │ ├── META-INF/ │ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── test.taglib.xml │ │ │ │ ├── controller/ │ │ │ │ │ └── simplePageConfig.xhtml │ │ │ │ ├── default/ │ │ │ │ │ └── WEB-INF/ │ │ │ │ │ ├── faces-config.xml │ │ │ │ │ └── web.xml │ │ │ │ ├── injection/ │ │ │ │ │ ├── testValidatorConverter.xhtml │ │ │ │ │ ├── testValidatorConverterTag.xhtml │ │ │ │ │ └── testValidatorTagParameter.xhtml │ │ │ │ ├── jsfMessageTest/ │ │ │ │ │ ├── UserMessage_de.properties │ │ │ │ │ ├── UserMessage_en.properties │ │ │ │ │ └── page.xhtml │ │ │ │ ├── mappedJsfContextTest/ │ │ │ │ │ └── page.xhtml │ │ │ │ ├── navigation/ │ │ │ │ │ ├── origin.xhtml │ │ │ │ │ ├── pages/ │ │ │ │ │ │ ├── customErrorPage.xhtml │ │ │ │ │ │ ├── home.xhtml │ │ │ │ │ │ ├── index.xhtml │ │ │ │ │ │ └── overview.xhtml │ │ │ │ │ ├── simplePageConfig.xhtml │ │ │ │ │ └── wizard1/ │ │ │ │ │ └── step1.xhtml │ │ │ │ ├── navigationParameterTest/ │ │ │ │ │ └── apache-deltaspike.properties │ │ │ │ ├── viewAccessScopedContextTest/ │ │ │ │ │ ├── index.xhtml │ │ │ │ │ ├── next.xhtml │ │ │ │ │ ├── page1.xhtml │ │ │ │ │ └── page2.xhtml │ │ │ │ └── windowScopedContextTest/ │ │ │ │ ├── frame.xhtml │ │ │ │ ├── framecontainer.xhtml │ │ │ │ ├── page.xhtml │ │ │ │ ├── page2.xhtml │ │ │ │ └── windowcount.xhtml │ │ │ └── pom.xml │ │ ├── partial-bean/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── partialbean/ │ │ │ │ │ └── api/ │ │ │ │ │ └── PartialBeanBinding.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── partialbean/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── PartialBeanBindingExtension.java │ │ │ │ │ │ ├── PartialBeanDescriptor.java │ │ │ │ │ │ └── PartialBeanProxyFactory.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ └── core/ │ │ │ │ │ └── api/ │ │ │ │ │ └── partialbean/ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ ├── CustomInterceptor.java │ │ │ │ │ │ ├── CustomInterceptorImpl.java │ │ │ │ │ │ ├── CustomInterceptorState.java │ │ │ │ │ │ ├── TestBean.java │ │ │ │ │ │ ├── TestInterceptorAware.java │ │ │ │ │ │ ├── TestPartialBeanBinding.java │ │ │ │ │ │ ├── ThrowExceptionPartialBeanBinding.java │ │ │ │ │ │ └── ThrowExceptionPartialBeanHandler.java │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ ├── PartialBean.java │ │ │ │ │ │ ├── PartialBeanAsInterfaceEarFileTest.java │ │ │ │ │ │ ├── PartialBeanAsInterfaceTest.java │ │ │ │ │ │ ├── PartialBeanAsInterfaceWarFileTest.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ ├── PartialBean.java │ │ │ │ │ │ ├── PartialBeanAsAbstractClassTest.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ ├── PartialBean.java │ │ │ │ │ │ ├── PartialBeanTest.java │ │ │ │ │ │ ├── SuperInterface.java │ │ │ │ │ │ ├── SuperInterface2.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ ├── AbstractSuper.java │ │ │ │ │ │ ├── ApplicationScopedPartialBean.java │ │ │ │ │ │ ├── DependentScopedPartialBean.java │ │ │ │ │ │ ├── ScopedPartialBeanTest.java │ │ │ │ │ │ ├── SuperInterface.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ ├── AbstractSuper.java │ │ │ │ │ │ ├── ApplicationScopedPartialBean.java │ │ │ │ │ │ ├── ScopedPartialBeanTest.java │ │ │ │ │ │ ├── SuperInterface.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ ├── AbstractSuper.java │ │ │ │ │ │ ├── AbstractSuperSuper.java │ │ │ │ │ │ ├── ApplicationScopedPartialBean.java │ │ │ │ │ │ ├── ScopedPartialBeanTest.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc007/ │ │ │ │ │ │ ├── CustomInterceptorStereotype.java │ │ │ │ │ │ ├── MethodLevelInterceptorTest.java │ │ │ │ │ │ ├── PartialBean.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc008/ │ │ │ │ │ │ ├── ClassLevelInterceptorTest.java │ │ │ │ │ │ ├── PartialBean.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc009/ │ │ │ │ │ │ ├── PartialBeanWithProducerEarFileTest.java │ │ │ │ │ │ ├── PartialBeanWithProducerTest.java │ │ │ │ │ │ ├── PartialBeanWithProducerWarFileTest.java │ │ │ │ │ │ ├── TestBaseConfig.java │ │ │ │ │ │ ├── TestConfig.java │ │ │ │ │ │ ├── TestCustomType.java │ │ │ │ │ │ ├── TestTypeSafeConfig.java │ │ │ │ │ │ ├── TestTypeSafeConfigHandler.java │ │ │ │ │ │ └── TestValue.java │ │ │ │ │ ├── uc010/ │ │ │ │ │ │ ├── PartialBeanAsAbstractClassTest.java │ │ │ │ │ │ ├── PartialBeanWrapper.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc011/ │ │ │ │ │ │ ├── BaseRepository.java │ │ │ │ │ │ ├── CustomerRepository.java │ │ │ │ │ │ ├── EntityRepository.java │ │ │ │ │ │ ├── ScopedPartialBeanTest.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ ├── uc012/ │ │ │ │ │ │ ├── BlockPolicy.java │ │ │ │ │ │ ├── ConcurrencyBugTest.java │ │ │ │ │ │ ├── MyPartialBeanBinding.java │ │ │ │ │ │ ├── MyPartialBeanHandler.java │ │ │ │ │ │ └── PartialBean.java │ │ │ │ │ ├── uc013/ │ │ │ │ │ │ ├── MethodLevelInterceptorTest.java │ │ │ │ │ │ ├── MyRepository.java │ │ │ │ │ │ ├── SimpleCache.java │ │ │ │ │ │ ├── SimpleCacheExtension.java │ │ │ │ │ │ ├── SimpleCacheInterceptor.java │ │ │ │ │ │ ├── SimpleCacheManager.java │ │ │ │ │ │ └── TestPartialBeanHandler.java │ │ │ │ │ └── util/ │ │ │ │ │ └── ArchiveUtils.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── pom.xml │ │ ├── pom.xml │ │ ├── proxy/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── proxy/ │ │ │ │ │ │ ├── api/ │ │ │ │ │ │ │ ├── DeltaSpikeProxyBeanConfigurator.java │ │ │ │ │ │ │ └── DeltaSpikeProxyFactory.java │ │ │ │ │ │ ├── spi/ │ │ │ │ │ │ │ ├── DeltaSpikeProxy.java │ │ │ │ │ │ │ ├── DeltaSpikeProxyClassGenerator.java │ │ │ │ │ │ │ ├── DeltaSpikeProxyClassGeneratorHolder.java │ │ │ │ │ │ │ └── invocation/ │ │ │ │ │ │ │ ├── DeltaSpikeProxyInterceptorLookup.java │ │ │ │ │ │ │ ├── DeltaSpikeProxyInvocationContext.java │ │ │ │ │ │ │ ├── DeltaSpikeProxyInvocationHandler.java │ │ │ │ │ │ │ └── DeltaSpikeProxyInvocationWrapperException.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ └── EnableInterceptorsProxyFactory.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ └── beans.xml │ │ │ │ │ └── OSGI-INF/ │ │ │ │ │ └── DeltaSpikeProxyClassGeneratorHolder.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── proxy/ │ │ │ │ └── api/ │ │ │ │ └── DeltaSpikeProxyFactoryTest.java │ │ │ ├── impl-asm/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── proxy/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── AsmDeltaSpikeProxyClassGenerator.java │ │ │ │ │ │ ├── ClassDefiner.java │ │ │ │ │ │ └── CopyAnnotationVisitorAdapter.java │ │ │ │ │ └── resources/ │ │ │ │ │ ├── META-INF/ │ │ │ │ │ │ ├── beans.xml │ │ │ │ │ │ └── services/ │ │ │ │ │ │ └── org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator │ │ │ │ │ └── OSGI-INF/ │ │ │ │ │ └── AsmDeltaSpikeProxyClassGenerator.xml │ │ │ │ └── test/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ ├── proxy/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── AsmProxyClassGeneratorTest.java │ │ │ │ │ ├── TestAnnotation.java │ │ │ │ │ ├── TestClass.java │ │ │ │ │ └── TestInvocationHandler.java │ │ │ │ └── test/ │ │ │ │ └── proxy/ │ │ │ │ └── impl/ │ │ │ │ └── util/ │ │ │ │ └── ArchiveUtils.java │ │ │ └── pom.xml │ │ ├── scheduler/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── scheduler/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ └── Scheduled.java │ │ │ │ │ └── spi/ │ │ │ │ │ ├── Scheduler.java │ │ │ │ │ └── SchedulerControl.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── scheduler/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── AbstractJobAdapter.java │ │ │ │ │ │ ├── AbstractQuartzScheduler.java │ │ │ │ │ │ ├── CdiAwareJobFactory.java │ │ │ │ │ │ ├── DynamicExpressionObserverJob.java │ │ │ │ │ │ ├── JobAdapter.java │ │ │ │ │ │ ├── JobQuartzScheduler.java │ │ │ │ │ │ ├── JobRunnableAdapter.java │ │ │ │ │ │ ├── QuartzSchedulerProducer.java │ │ │ │ │ │ ├── RunnableQuartzScheduler.java │ │ │ │ │ │ ├── SchedulerBaseConfig.java │ │ │ │ │ │ ├── SchedulerExtension.java │ │ │ │ │ │ └── SchedulerProducer.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ ├── jakarta.enterprise.inject.spi.Extension │ │ │ │ │ └── org.apache.deltaspike.scheduler.spi.Scheduler │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ ├── scheduler/ │ │ │ │ │ │ └── custom/ │ │ │ │ │ │ ├── AutoRegisteredJob.java │ │ │ │ │ │ ├── CustomConfigSource.java │ │ │ │ │ │ ├── CustomDeactivatedConfigSource.java │ │ │ │ │ │ ├── CustomJob.java │ │ │ │ │ │ ├── CustomSchedulerEarFileTest.java │ │ │ │ │ │ ├── CustomSchedulerTest.java │ │ │ │ │ │ ├── CustomSchedulerWarFileTest.java │ │ │ │ │ │ ├── DeleteJob.java │ │ │ │ │ │ ├── ManualJob.java │ │ │ │ │ │ ├── MockedScheduler.java │ │ │ │ │ │ ├── QuartzDeactivator.java │ │ │ │ │ │ ├── RequestScopedJob.java │ │ │ │ │ │ ├── ScopeNotStartedTest.java │ │ │ │ │ │ └── TestJobManager.java │ │ │ │ │ └── util/ │ │ │ │ │ └── ArchiveUtils.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ ├── org.apache.deltaspike.core.spi.config.ConfigSource │ │ │ │ └── org.apache.deltaspike.scheduler.spi.Scheduler │ │ │ └── pom.xml │ │ ├── security/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── security/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── SecurityException.java │ │ │ │ │ │ └── authorization/ │ │ │ │ │ │ ├── AbstractAccessDecisionVoter.java │ │ │ │ │ │ ├── AbstractDecisionVoter.java │ │ │ │ │ │ ├── AccessDecisionState.java │ │ │ │ │ │ ├── AccessDecisionVoter.java │ │ │ │ │ │ ├── AccessDecisionVoterContext.java │ │ │ │ │ │ ├── AccessDeniedException.java │ │ │ │ │ │ ├── ErrorViewAwareAccessDeniedException.java │ │ │ │ │ │ ├── Secured.java │ │ │ │ │ │ ├── SecuredReturn.java │ │ │ │ │ │ ├── Secures.java │ │ │ │ │ │ ├── SecurityBindingType.java │ │ │ │ │ │ ├── SecurityDefinitionException.java │ │ │ │ │ │ ├── SecurityParameterBinding.java │ │ │ │ │ │ ├── SecurityViolation.java │ │ │ │ │ │ └── SimpleSecurityViolation.java │ │ │ │ │ └── spi/ │ │ │ │ │ └── authorization/ │ │ │ │ │ ├── EditableAccessDecisionVoterContext.java │ │ │ │ │ ├── SecurityStrategy.java │ │ │ │ │ └── SecurityViolationHandler.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ ├── impl/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── security/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── authorization/ │ │ │ │ │ │ │ ├── AccessDeniedExceptionBroadcaster.java │ │ │ │ │ │ │ ├── DefaultAccessDecisionVoterContext.java │ │ │ │ │ │ │ ├── SecuredAnnotationAuthorizer.java │ │ │ │ │ │ │ ├── SecurityParameterValueRedefiner.java │ │ │ │ │ │ │ └── SkipInternalProcessingException.java │ │ │ │ │ │ ├── extension/ │ │ │ │ │ │ │ ├── AuthorizationParameter.java │ │ │ │ │ │ │ ├── Authorizer.java │ │ │ │ │ │ │ ├── DefaultSecurityStrategy.java │ │ │ │ │ │ │ ├── SecurityExtension.java │ │ │ │ │ │ │ ├── SecurityInterceptor.java │ │ │ │ │ │ │ ├── SecurityInterceptorBinding.java │ │ │ │ │ │ │ ├── SecurityInterceptorBindingLiteral.java │ │ │ │ │ │ │ └── SecurityMetaDataStorage.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ └── SecurityUtils.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ ├── security/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ └── authorization/ │ │ │ │ │ │ ├── nonbinding/ │ │ │ │ │ │ │ ├── CustomAuthorizer.java │ │ │ │ │ │ │ ├── CustomSecurityBinding.java │ │ │ │ │ │ │ ├── ParamBindingWithNonbindingMember.java │ │ │ │ │ │ │ ├── ParameterValue.java │ │ │ │ │ │ │ ├── SecuredBean.java │ │ │ │ │ │ │ └── SecurityParameterWithNonbindingMemberTest.java │ │ │ │ │ │ ├── secured/ │ │ │ │ │ │ │ ├── SecuredAnnotationEarFileTest.java │ │ │ │ │ │ │ ├── SecuredAnnotationTest.java │ │ │ │ │ │ │ ├── SecuredAnnotationWarFileTest.java │ │ │ │ │ │ │ ├── SecuredBean1.java │ │ │ │ │ │ │ ├── SecuredBean2.java │ │ │ │ │ │ │ ├── SecuredBean3.java │ │ │ │ │ │ │ ├── SecuredBean4.java │ │ │ │ │ │ │ ├── SecuredBean5.java │ │ │ │ │ │ │ ├── SecuredBeanWithStereotype.java │ │ │ │ │ │ │ ├── SecuredBeanWithStereotype1.java │ │ │ │ │ │ │ ├── SecuredBeanWithStereotype2.java │ │ │ │ │ │ │ ├── SecuredBeanWithStereotype3.java │ │ │ │ │ │ │ ├── SomeParentClass.java │ │ │ │ │ │ │ ├── TestAccessDecisionVoter.java │ │ │ │ │ │ │ ├── TestAccessDecisionVoter1.java │ │ │ │ │ │ │ └── TestAccessDecisionVoter2.java │ │ │ │ │ │ ├── securitybinding/ │ │ │ │ │ │ │ ├── CustomAuthorizer.java │ │ │ │ │ │ │ ├── CustomSecurityBinding.java │ │ │ │ │ │ │ ├── SecuredBean1.java │ │ │ │ │ │ │ ├── SecuredBean2.java │ │ │ │ │ │ │ ├── SecurityBindingTest.java │ │ │ │ │ │ │ └── SomeParentClass.java │ │ │ │ │ │ ├── securityparameterbinding/ │ │ │ │ │ │ │ ├── CustomAuthorizer.java │ │ │ │ │ │ │ ├── CustomSecurityBinding.java │ │ │ │ │ │ │ ├── MethodInvocationParameter.java │ │ │ │ │ │ │ ├── MockObject.java │ │ │ │ │ │ │ ├── MockObject2.java │ │ │ │ │ │ │ ├── MockParamBinding.java │ │ │ │ │ │ │ ├── SecuredBean1.java │ │ │ │ │ │ │ ├── SecuredBean2.java │ │ │ │ │ │ │ └── SecurityParameterBindingTest.java │ │ │ │ │ │ └── util/ │ │ │ │ │ │ ├── Annotation1.java │ │ │ │ │ │ ├── Annotation2.java │ │ │ │ │ │ ├── Annotation3.java │ │ │ │ │ │ ├── AnnotationA.java │ │ │ │ │ │ ├── AnnotationB.java │ │ │ │ │ │ ├── AnnotationC.java │ │ │ │ │ │ ├── AnnotationX.java │ │ │ │ │ │ ├── DirectCycle.java │ │ │ │ │ │ ├── IndirectCycle.java │ │ │ │ │ │ ├── IndirectCycleWithAnnotationMemberValues.java │ │ │ │ │ │ └── SecurityUtilsTest.java │ │ │ │ │ └── util/ │ │ │ │ │ └── ArchiveUtils.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ └── beans.xml │ │ │ └── pom.xml │ │ ├── test-control/ │ │ │ ├── api/ │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ └── main/ │ │ │ │ └── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── testcontrol/ │ │ │ │ ├── api/ │ │ │ │ │ ├── TestControl.java │ │ │ │ │ ├── junit/ │ │ │ │ │ │ ├── CdiTestRunner.java │ │ │ │ │ │ ├── CdiTestSuiteRunner.java │ │ │ │ │ │ └── TestBaseConfig.java │ │ │ │ │ ├── literal/ │ │ │ │ │ │ └── TestControlLiteral.java │ │ │ │ │ └── mock/ │ │ │ │ │ ├── ApplicationMockManager.java │ │ │ │ │ ├── DynamicMockManager.java │ │ │ │ │ └── TypedMock.java │ │ │ │ └── spi/ │ │ │ │ ├── ExternalContainer.java │ │ │ │ ├── TestAware.java │ │ │ │ ├── TestControlValidator.java │ │ │ │ ├── junit/ │ │ │ │ │ └── TestStatementDecoratorFactory.java │ │ │ │ └── mock/ │ │ │ │ └── MockFilter.java │ │ │ ├── impl/ │ │ │ │ ├── obsolete/ │ │ │ │ │ └── src/ │ │ │ │ │ ├── main/ │ │ │ │ │ │ └── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── testcontrol/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── jsf/ │ │ │ │ │ │ │ ├── MockedJsf2TestContainer.java │ │ │ │ │ │ │ ├── MockedJsfTestContainerAdapter.java │ │ │ │ │ │ │ ├── MyFacesContainerAdapter.java │ │ │ │ │ │ │ ├── MyFacesContainerPerTestMethodAdapter.java │ │ │ │ │ │ │ └── MyFacesTestBaseConfig.java │ │ │ │ │ │ └── transaction/ │ │ │ │ │ │ └── TransactionStatementDecoratorFactory.java │ │ │ │ │ └── test/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── test/ │ │ │ │ │ │ └── testcontrol/ │ │ │ │ │ │ ├── InternalMyFacesTestContainerAdapter.java │ │ │ │ │ │ ├── mock/ │ │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ │ ├── ApplicationScopedBean.java │ │ │ │ │ │ │ │ ├── MyQualifier.java │ │ │ │ │ │ │ │ ├── RequestScopedBean.java │ │ │ │ │ │ │ │ └── SessionScopedBean.java │ │ │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ │ │ └── MockedRequestScopedBeanTest.java │ │ │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ │ │ └── MockedSessionScopedBeanTest.java │ │ │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ │ │ ├── MockedSessionScopedBean.java │ │ │ │ │ │ │ │ └── MockedSessionScopedBeanAcrossMethodsTest.java │ │ │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ │ │ ├── MockedApplicationScopedBean.java │ │ │ │ │ │ │ │ └── MockedApplicationScopedBeanTest.java │ │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ │ ├── MockedProducedBeanTest.java │ │ │ │ │ │ │ │ ├── ProducedBean.java │ │ │ │ │ │ │ │ └── ProducedBeanProducer.java │ │ │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ │ │ ├── MockedRequestScopedQualifiedBeanTest.java │ │ │ │ │ │ │ │ └── QualifiedBean.java │ │ │ │ │ │ │ ├── uc007/ │ │ │ │ │ │ │ │ ├── MockedProducedQualifiedBeanTest.java │ │ │ │ │ │ │ │ ├── ProducedBean.java │ │ │ │ │ │ │ │ └── ProducedBeanProducer.java │ │ │ │ │ │ │ ├── uc008/ │ │ │ │ │ │ │ │ ├── MockedTypedBeanTest.java │ │ │ │ │ │ │ │ ├── T1.java │ │ │ │ │ │ │ │ ├── T2.java │ │ │ │ │ │ │ │ ├── T3.java │ │ │ │ │ │ │ │ ├── TypedBean1and2.java │ │ │ │ │ │ │ │ └── TypedBean3.java │ │ │ │ │ │ │ ├── uc009/ │ │ │ │ │ │ │ │ ├── MockedTypedProducedBeanTest.java │ │ │ │ │ │ │ │ ├── T1.java │ │ │ │ │ │ │ │ ├── T2.java │ │ │ │ │ │ │ │ ├── T3.java │ │ │ │ │ │ │ │ ├── TypedBean1and2.java │ │ │ │ │ │ │ │ ├── TypedBean3.java │ │ │ │ │ │ │ │ └── TypedBeanProducer.java │ │ │ │ │ │ │ ├── uc010/ │ │ │ │ │ │ │ │ └── MockedRequestScopedBeanTest.java │ │ │ │ │ │ │ ├── uc011/ │ │ │ │ │ │ │ │ ├── MockedRequestScopedBeanWithInjection.java │ │ │ │ │ │ │ │ └── MockedRequestScopedBeanWithInjectionTest.java │ │ │ │ │ │ │ ├── uc012/ │ │ │ │ │ │ │ │ ├── MockedRequestScopedBeanWithInjection.java │ │ │ │ │ │ │ │ └── MockedRequestScopedBeanWithInjectionTest.java │ │ │ │ │ │ │ ├── uc013/ │ │ │ │ │ │ │ │ ├── MockedTypedProducedBeanTest.java │ │ │ │ │ │ │ │ ├── T1.java │ │ │ │ │ │ │ │ ├── T2.java │ │ │ │ │ │ │ │ ├── T3.java │ │ │ │ │ │ │ │ ├── TypedBean1and2.java │ │ │ │ │ │ │ │ ├── TypedBean3.java │ │ │ │ │ │ │ │ └── TypedBeanProducer.java │ │ │ │ │ │ │ ├── uc014/ │ │ │ │ │ │ │ │ ├── MockedTypedProducedBeanTest.java │ │ │ │ │ │ │ │ ├── T1.java │ │ │ │ │ │ │ │ ├── T2.java │ │ │ │ │ │ │ │ ├── T3.java │ │ │ │ │ │ │ │ ├── TypedBean1and2.java │ │ │ │ │ │ │ │ ├── TypedBean3.java │ │ │ │ │ │ │ │ └── TypedBeanProducer.java │ │ │ │ │ │ │ └── uc016/ │ │ │ │ │ │ │ └── CustomMockManagerTest.java │ │ │ │ │ │ ├── uc005/ │ │ │ │ │ │ │ └── MockedJsfContainerTest.java │ │ │ │ │ │ ├── uc006/ │ │ │ │ │ │ │ └── SkipExternalContainerTest.java │ │ │ │ │ │ ├── uc009/ │ │ │ │ │ │ │ └── JsfContainerTest.java │ │ │ │ │ │ ├── uc010/ │ │ │ │ │ │ │ └── JsfContainerPerTestMethodTest.java │ │ │ │ │ │ ├── uc014/ │ │ │ │ │ │ │ ├── DefaultTestService.java │ │ │ │ │ │ │ ├── TestLabelX.java │ │ │ │ │ │ │ ├── TestService.java │ │ │ │ │ │ │ ├── TestServiceLabelX.java │ │ │ │ │ │ │ ├── TestServiceLabelY.java │ │ │ │ │ │ │ ├── TestServiceLabelYTest.java │ │ │ │ │ │ │ ├── TestServiceNoLabelTest.java │ │ │ │ │ │ │ └── TestServiceTestLabelXTest.java │ │ │ │ │ │ ├── uc015/ │ │ │ │ │ │ │ ├── AlternativeServiceTest.java │ │ │ │ │ │ │ ├── DefaultTestService.java │ │ │ │ │ │ │ ├── LabeledServiceTest.java │ │ │ │ │ │ │ ├── LabeledTestService.java │ │ │ │ │ │ │ └── TestService.java │ │ │ │ │ │ ├── uc016/ │ │ │ │ │ │ │ ├── DefaultTestService.java │ │ │ │ │ │ │ ├── TestLabel.java │ │ │ │ │ │ │ ├── TestQualifierBinding.java │ │ │ │ │ │ │ ├── TestService.java │ │ │ │ │ │ │ ├── TestServiceLabelX.java │ │ │ │ │ │ │ ├── TestServiceLabelXTest.java │ │ │ │ │ │ │ ├── TestServiceLabelY.java │ │ │ │ │ │ │ └── TestServiceLabelYTest.java │ │ │ │ │ │ ├── uc017/ │ │ │ │ │ │ │ ├── DefaultServiceTest.java │ │ │ │ │ │ │ ├── DefaultTestServiceProducer.java │ │ │ │ │ │ │ ├── LabeledServiceTest.java │ │ │ │ │ │ │ ├── LabeledTestServiceProducer.java │ │ │ │ │ │ │ └── TestService.java │ │ │ │ │ │ └── uc018/ │ │ │ │ │ │ ├── DefaultServiceTest.java │ │ │ │ │ │ ├── DefaultTestServiceProducer.java │ │ │ │ │ │ ├── InterceptedDefaultTestService.java │ │ │ │ │ │ ├── InterceptedLabeledTestService.java │ │ │ │ │ │ ├── InterceptedTestService.java │ │ │ │ │ │ ├── InterceptedTestServiceProducer.java │ │ │ │ │ │ ├── LabeledServiceTest.java │ │ │ │ │ │ ├── LabeledTestServiceProducer.java │ │ │ │ │ │ ├── TestServiceQualifier.java │ │ │ │ │ │ ├── TestUpperCaseInterceptor.java │ │ │ │ │ │ └── TestUpperCaseInterceptorImplementation.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ └── services/ │ │ │ │ │ ├── org.apache.deltaspike.testcontrol.spi.ExternalContainer │ │ │ │ │ └── org.apache.deltaspike.testcontrol.spi.junit.TestStatementDecoratorFactory │ │ │ │ ├── pom.xml │ │ │ │ └── src/ │ │ │ │ ├── main/ │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── org/ │ │ │ │ │ │ └── apache/ │ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ │ └── testcontrol/ │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── mock/ │ │ │ │ │ │ │ ├── AbstractMockManager.java │ │ │ │ │ │ │ ├── BeanCacheKey.java │ │ │ │ │ │ │ ├── DefaultMockFilter.java │ │ │ │ │ │ │ ├── MockAwareInjectionTargetWrapper.java │ │ │ │ │ │ │ ├── MockAwareProducerWrapper.java │ │ │ │ │ │ │ ├── MockExtension.java │ │ │ │ │ │ │ ├── SimpleApplicationMockManager.java │ │ │ │ │ │ │ └── SimpleMockManager.java │ │ │ │ │ │ ├── request/ │ │ │ │ │ │ │ └── ContextControlDecorator.java │ │ │ │ │ │ └── validation/ │ │ │ │ │ │ └── StandardContextTestControlValidator.java │ │ │ │ │ └── resources/ │ │ │ │ │ └── META-INF/ │ │ │ │ │ ├── apache-deltaspike_test-container.properties │ │ │ │ │ ├── beans.xml │ │ │ │ │ └── services/ │ │ │ │ │ ├── jakarta.enterprise.inject.spi.Extension │ │ │ │ │ ├── org.apache.deltaspike.testcontrol.spi.TestControlValidator │ │ │ │ │ └── org.apache.deltaspike.testcontrol.spi.mock.MockFilter │ │ │ │ └── test/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── test/ │ │ │ │ │ └── testcontrol/ │ │ │ │ │ ├── CustomMockManager.java │ │ │ │ │ ├── InternalTestClassDeactivator.java │ │ │ │ │ ├── InternalTestMockFilter.java │ │ │ │ │ ├── mock/ │ │ │ │ │ │ └── uc015/ │ │ │ │ │ │ ├── InterceptedBeanClassLevel.java │ │ │ │ │ │ ├── InterceptedBeanMethodLevel.java │ │ │ │ │ │ ├── InterceptedBeanTest.java │ │ │ │ │ │ ├── InterceptionResultStorage.java │ │ │ │ │ │ ├── TestInterceptor.java │ │ │ │ │ │ └── TestInterceptorImplementation.java │ │ │ │ │ ├── shared/ │ │ │ │ │ │ ├── ApplicationScopedBean.java │ │ │ │ │ │ ├── RequestScopedBean.java │ │ │ │ │ │ ├── SessionScopedBean.java │ │ │ │ │ │ └── TestUtils.java │ │ │ │ │ ├── uc001/ │ │ │ │ │ │ └── RequestAndSessionScopePerTestMethodTest.java │ │ │ │ │ ├── uc002/ │ │ │ │ │ │ └── SessionScopePerTestClassTest.java │ │ │ │ │ ├── uc003/ │ │ │ │ │ │ ├── RequestAndSessionScopePerTestMethodTest.java │ │ │ │ │ │ ├── SessionScopePerTestClassTest.java │ │ │ │ │ │ └── TestSuite.java │ │ │ │ │ ├── uc004/ │ │ │ │ │ │ └── ProjectStageTestControlTest.java │ │ │ │ │ ├── uc007/ │ │ │ │ │ │ ├── BaseTest.java │ │ │ │ │ │ └── ExtendedTest.java │ │ │ │ │ ├── uc008/ │ │ │ │ │ │ └── BeforeAndAfterInjectionTest.java │ │ │ │ │ ├── uc011/ │ │ │ │ │ │ ├── InterceptedBeanClassLevel.java │ │ │ │ │ │ ├── InterceptedBeanMethodLevel.java │ │ │ │ │ │ ├── InterceptedBeanTest.java │ │ │ │ │ │ ├── InterceptionResultStorage.java │ │ │ │ │ │ ├── TestInterceptor.java │ │ │ │ │ │ └── TestInterceptorImplementation.java │ │ │ │ │ ├── uc012/ │ │ │ │ │ │ ├── ApplicationScopedBeanTest.java │ │ │ │ │ │ ├── ApplicationScopedTestBean.java │ │ │ │ │ │ └── ApplicationScopedTestBeanClient.java │ │ │ │ │ ├── uc013/ │ │ │ │ │ │ └── ContainerConfigTest.java │ │ │ │ │ └── uc019/ │ │ │ │ │ ├── DefaultTestService.java │ │ │ │ │ ├── TestBeanClassFilter.java │ │ │ │ │ ├── TestLabeled.java │ │ │ │ │ ├── TestLabeledAlternativeFilter.java │ │ │ │ │ ├── TestService.java │ │ │ │ │ ├── TestServiceLabelX.java │ │ │ │ │ ├── TestServiceLabelXTest.java │ │ │ │ │ ├── TestServiceLabelY.java │ │ │ │ │ └── TestServiceLabelYTest.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── apache-deltaspike.properties │ │ │ │ ├── apache-deltaspike_test-container.properties │ │ │ │ ├── beans.xml │ │ │ │ ├── services/ │ │ │ │ │ ├── org.apache.deltaspike.core.spi.alternative.AlternativeBeanClassProvider │ │ │ │ │ └── org.apache.deltaspike.testcontrol.spi.mock.MockFilter │ │ │ │ └── test/ │ │ │ │ └── dsTestContainerBootConfig.properties │ │ │ └── pom.xml │ │ └── test-control5/ │ │ ├── api/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ └── main/ │ │ │ └── java/ │ │ │ └── org/ │ │ │ └── apache/ │ │ │ └── deltaspike/ │ │ │ └── testcontrol5/ │ │ │ ├── api/ │ │ │ │ ├── TestControl.java │ │ │ │ ├── junit/ │ │ │ │ │ ├── CdiTestExtension.java │ │ │ │ │ ├── CdiTestSuiteExtension.java │ │ │ │ │ ├── TestBaseConfig.java │ │ │ │ │ └── TestConfigSource.java │ │ │ │ ├── literal/ │ │ │ │ │ └── TestControlLiteral.java │ │ │ │ └── mock/ │ │ │ │ ├── ApplicationMockManager.java │ │ │ │ ├── DynamicMockManager.java │ │ │ │ └── TypedMock.java │ │ │ └── spi/ │ │ │ ├── ExternalContainer.java │ │ │ ├── TestAware.java │ │ │ ├── TestControlValidator.java │ │ │ ├── junit/ │ │ │ │ └── TestStatementDecoratorFactory.java │ │ │ └── mock/ │ │ │ └── MockFilter.java │ │ ├── impl/ │ │ │ ├── pom.xml │ │ │ └── src/ │ │ │ ├── main/ │ │ │ │ ├── java/ │ │ │ │ │ └── org/ │ │ │ │ │ └── apache/ │ │ │ │ │ └── deltaspike/ │ │ │ │ │ └── testcontrol5/ │ │ │ │ │ └── impl/ │ │ │ │ │ ├── mock/ │ │ │ │ │ │ ├── AbstractMockManager.java │ │ │ │ │ │ ├── BeanCacheKey.java │ │ │ │ │ │ ├── DefaultMockFilter.java │ │ │ │ │ │ ├── MockAwareInjectionTargetWrapper.java │ │ │ │ │ │ ├── MockAwareProducerWrapper.java │ │ │ │ │ │ ├── MockExtension.java │ │ │ │ │ │ ├── SimpleApplicationMockManager.java │ │ │ │ │ │ └── SimpleMockManager.java │ │ │ │ │ ├── request/ │ │ │ │ │ │ └── ContextControlDecorator.java │ │ │ │ │ └── validation/ │ │ │ │ │ └── StandardContextTestControlValidator.java │ │ │ │ └── resources/ │ │ │ │ └── META-INF/ │ │ │ │ ├── apache-deltaspike_test-container.properties │ │ │ │ ├── beans.xml │ │ │ │ └── services/ │ │ │ │ ├── jakarta.enterprise.inject.spi.Extension │ │ │ │ ├── org.apache.deltaspike.testcontrol.spi.TestControlValidator │ │ │ │ └── org.apache.deltaspike.testcontrol.spi.mock.MockFilter │ │ │ └── test/ │ │ │ ├── java/ │ │ │ │ └── org/ │ │ │ │ └── apache/ │ │ │ │ └── deltaspike/ │ │ │ │ └── test/ │ │ │ │ └── testcontrol5/ │ │ │ │ ├── CustomMockManager.java │ │ │ │ ├── InternalTestClassDeactivator.java │ │ │ │ ├── InternalTestMockFilter.java │ │ │ │ ├── mock/ │ │ │ │ │ └── uc015/ │ │ │ │ │ ├── InterceptedBeanClassLevel.java │ │ │ │ │ ├── InterceptedBeanMethodLevel.java │ │ │ │ │ ├── InterceptedBeanTest.java │ │ │ │ │ ├── InterceptionResultStorage.java │ │ │ │ │ ├── TestInterceptor.java │ │ │ │ │ └── TestInterceptorImplementation.java │ │ │ │ ├── shared/ │ │ │ │ │ ├── ApplicationScopedBean.java │ │ │ │ │ ├── RequestScopedBean.java │ │ │ │ │ ├── SessionScopedBean.java │ │ │ │ │ └── TestUtils.java │ │ │ │ ├── uc001/ │ │ │ │ │ └── RequestAndSessionScopePerTestMethodTest.java │ │ │ │ ├── uc002/ │ │ │ │ │ └── SessionScopePerTestClassTest.java │ │ │ │ ├── uc003/ │ │ │ │ │ ├── RequestAndSessionScopePerTestMethodTest.java │ │ │ │ │ ├── SessionScopePerTestClassTest.java │ │ │ │ │ └── TestSuite.java │ │ │ │ ├── uc004/ │ │ │ │ │ └── ProjectStageTestControlTest.java │ │ │ │ ├── uc007/ │ │ │ │ │ ├── BaseTest.java │ │ │ │ │ └── ExtendedTest.java │ │ │ │ ├── uc008/ │ │ │ │ │ └── BeforeAndAfterInjectionTest.java │ │ │ │ ├── uc011/ │ │ │ │ │ ├── InterceptedBeanClassLevel.java │ │ │ │ │ ├── InterceptedBeanMethodLevel.java │ │ │ │ │ ├── InterceptedBeanTest.java │ │ │ │ │ ├── InterceptionResultStorage.java │ │ │ │ │ ├── TestInterceptor.java │ │ │ │ │ └── TestInterceptorImplementation.java │ │ │ │ ├── uc012/ │ │ │ │ │ ├── ApplicationScopedBeanTest.java │ │ │ │ │ ├── ApplicationScopedTestBean.java │ │ │ │ │ └── ApplicationScopedTestBeanClient.java │ │ │ │ ├── uc013/ │ │ │ │ │ └── ContainerConfigTest.java │ │ │ │ └── uc019/ │ │ │ │ ├── DefaultTestService.java │ │ │ │ ├── TestBeanClassFilter.java │ │ │ │ ├── TestLabeled.java │ │ │ │ ├── TestLabeledAlternativeFilter.java │ │ │ │ ├── TestService.java │ │ │ │ ├── TestServiceLabelX.java │ │ │ │ ├── TestServiceLabelXTest.java │ │ │ │ ├── TestServiceLabelY.java │ │ │ │ └── TestServiceLabelYTest.java │ │ │ └── resources/ │ │ │ └── META-INF/ │ │ │ ├── apache-deltaspike.properties │ │ │ ├── apache-deltaspike_test-container.properties │ │ │ ├── beans.xml │ │ │ ├── services/ │ │ │ │ ├── org.apache.deltaspike.core.spi.alternative.AlternativeBeanClassProvider │ │ │ │ └── org.apache.deltaspike.testcontrol5.spi.mock.MockFilter │ │ │ └── test/ │ │ │ └── dsTestContainerBootConfig.properties │ │ └── pom.xml │ ├── parent/ │ │ ├── code/ │ │ │ └── pom.xml │ │ └── pom.xml │ ├── pom.xml │ ├── readme/ │ │ ├── ReleaseNotes-0.2-incubating.txt │ │ ├── ReleaseNotes-0.3-incubating.txt │ │ ├── ReleaseNotes-0.4-incubating.txt │ │ ├── ReleaseNotes-0.5.txt │ │ ├── ReleaseNotes-0.6.txt │ │ ├── ReleaseNotes-0.7.txt │ │ ├── ReleaseNotes-1.0.0.txt │ │ ├── ReleaseNotes-1.0.1.txt │ │ ├── ReleaseNotes-1.0.2.txt │ │ ├── ReleaseNotes-1.0.3.txt │ │ ├── ReleaseNotes-1.1.0.txt │ │ ├── ReleaseNotes-1.2.0.txt │ │ ├── ReleaseNotes-1.2.1.txt │ │ ├── ReleaseNotes-1.3.0.txt │ │ ├── ReleaseNotes-1.4.0.txt │ │ ├── ReleaseNotes-1.4.1.txt │ │ ├── ReleaseNotes-1.4.2.txt │ │ ├── ReleaseNotes-1.5.0.txt │ │ ├── ReleaseNotes-1.5.1.txt │ │ ├── ReleaseNotes-1.5.2.txt │ │ ├── ReleaseNotes-1.5.3.txt │ │ ├── ReleaseNotes-1.5.4.txt │ │ ├── ReleaseNotes-1.6.0.txt │ │ ├── ReleaseNotes-1.6.1.txt │ │ ├── ReleaseNotes-1.7.0.txt │ │ ├── ReleaseNotes-1.7.1.txt │ │ ├── ReleaseNotes-1.7.2.txt │ │ ├── ReleaseNotes-1.8.2.txt │ │ ├── ReleaseNotes-1.9.5.txt │ │ ├── ReleaseNotes-1.9.6.txt │ │ └── ReleaseNotes-2.0.0.txt │ └── test-utils/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── org/ │ │ └── apache/ │ │ └── deltaspike/ │ │ └── test/ │ │ ├── arquillian/ │ │ │ ├── DeltaSpikeServerUtilAppender.java │ │ │ ├── DeltaSpikeTestUtilExtension.java │ │ │ └── TestUtilDependenciesAppender.java │ │ ├── category/ │ │ │ ├── DeltaSpikeTest.java │ │ │ ├── EnterpriseArchiveProfileCategory.java │ │ │ ├── FullProfileCategory.java │ │ │ ├── SeCategory.java │ │ │ ├── WebEEProfileCategory.java │ │ │ └── WebProfileCategory.java │ │ ├── control/ │ │ │ ├── LockedContainerVersions.java │ │ │ ├── LockedImplementation.java │ │ │ ├── LockedVersionRange.java │ │ │ └── VersionControlRule.java │ │ └── utils/ │ │ ├── BeansXmlUtil.java │ │ ├── CdiContainerUnderTest.java │ │ ├── Implementation.java │ │ ├── Serializer.java │ │ └── ShrinkWrapArchiveUtil.java │ └── resources/ │ ├── META-INF/ │ │ └── services/ │ │ └── org.jboss.arquillian.core.spi.LoadableExtension │ ├── arquillian-jboss.xml │ └── arquillian.xml ├── doap_DeltaSpike.rdf ├── documentation/ │ ├── README.md │ ├── pom.xml │ └── src/ │ └── main/ │ └── asciidoc/ │ ├── build.adoc │ ├── cdiimp.adoc │ ├── configuration.adoc │ ├── configure.adoc │ ├── container-control.adoc │ ├── core.adoc │ ├── data.adoc │ ├── encryption.adoc │ ├── index.adoc │ ├── jpa.adoc │ ├── jsf.adoc │ ├── modules.adoc │ ├── overview.adoc │ ├── partial-bean.adoc │ ├── projectstage.adoc │ ├── proxy.adoc │ ├── scheduler.adoc │ ├── security.adoc │ ├── servlet.adoc │ ├── snapshots.adoc │ ├── spi.adoc │ └── test-control.adoc ├── keys/ │ └── KEYS ├── pom.xml ├── site/ │ ├── README.md │ ├── pom.xml │ └── src/ │ └── main/ │ └── asciidoc/ │ ├── addons.adoc │ ├── articles.adoc │ ├── community.adoc │ ├── documentation.adoc │ ├── download.adoc │ ├── examples.adoc │ ├── external.adoc │ ├── index.adoc │ ├── javadoc.adoc │ ├── migration-guide.adoc │ ├── news.adoc │ ├── release-preparation.adoc │ ├── source.adoc │ ├── steps_for_a_release.adoc │ └── suggested-git-workflows.adoc └── template/ └── document.html.erb ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/ci.yml ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # # 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. # # NOTE https://infra.apache.org/github-actions-secrets.html name: CI on: push: branches: - master - main paths-ignore: - '**.md' - '.travis.yml' - 'Jenkinsfile' pull_request: branches: - master - main paths-ignore: - '**.md' - '.travis.yml' - 'Jenkinsfile' workflow_dispatch: permissions: contents: read jobs: build: name: Build with ${{ matrix.profile }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: profile: [ 'OWB', 'Weld' ] steps: - uses: actions/checkout@v3 with: persist-credentials: false - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 - name: Cache Maven packages uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Build run: mvn clean install -P${{ matrix.profile }} ================================================ FILE: .github/workflows/integration.yml ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # # 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. # # NOTE https://infra.apache.org/github-actions-secrets.html name: Integration on: workflow_dispatch: schedule: - cron: '0 6 * * *' permissions: contents: read jobs: build: name: Build with ${{ matrix.profile }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: profile: [ 'tomee-build-managed', 'wildfly-build-managed', 'payara-build-managed' ] steps: - uses: actions/checkout@v3 with: persist-credentials: false - name: Set up JDK 17 uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 - name: Cache Maven packages uses: actions/cache@v3 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2 - name: Build run: mvn clean install -P${{ matrix.profile }} ================================================ FILE: .gitignore ================================================ target *.iml *.iws *.ipr .project .classpath .settings .metadata .svn .idea .checkstyle atlassian-ide-plugin.xml .sonar-ide.properties *.patch deltaspike/core/impl/data deltaspike/modules/jsf/impl/data deltaspike/modules/security/impl/data *.log ================================================ FILE: .travis.yml ================================================ language: java dist: trusty cache: directories: - '$HOME/.m2/repository' install: # Skip the first maven execution for downloading dependencies by using this command - /bin/true script: - ./build.sh env: global: - MAVEN_SKIP_RC=true matrix: fast_finish: true include: - env: PROFILES=tomee-build-managed jdk: oraclejdk8 # Must run with newer OpenEJB for the OpenEJB conatiner control tests - env: PROFILES=tomee8-build-managed,OpenEJB-TomEE jdk: oraclejdk8 # Must run with newer OpenEJB for the OpenEJB conatiner control tests - env: PROFILES=tomee7-build-managed,OpenEJB-TomEE jdk: oraclejdk8 - env: PROFILES=OWB jdk: oraclejdk8 - env: PROFILES=Weld3 jdk: oraclejdk8 - env: PROFILES=OWB2 jdk: oraclejdk8 - env: PROFILES=Weld2 jdk: oraclejdk8 - env: PROFILES=OWB15 jdk: oraclejdk8 - env: PROFILES=Weld1 jdk: oraclejdk8 ################################################ # The following are tests that compile Java8 bytecode and only check if Deltaspike is capable of running on a newer JVM ################################################ - env: PROFILES=OWB2 JDK=9 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 9 -L BCL # Add new certificates for JDK10 # https://www.deps.co/guides/travis-ci-latest-java/ - env: PROFILES=OWB2 JDK=10 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 10 -L GPL - rm "${JAVA_HOME}/lib/security/cacerts" - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" - env: PROFILES=OWB2 JDK=11 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 11 -L BCL - env: PROFILES=OWB2 JDK=12 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 12 -L GPL - env: PROFILES=OWB2 JDK=13 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 13 -L GPL - env: PROFILES=OWB2 JDK=14 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 14 -L GPL ################################################ # The following are tests that compile to Java9+ bytecode and check if Deltaspike is buildable with newer JDKs as well as if it is capable of handling classes of newer bytecode versions ################################################ - env: PROFILES=OWB2 JDK=9 BUILD_JDK=9 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 9 -L GPL - env: PROFILES=OWB2 JDK=10 BUILD_JDK=10 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 10 -L GPL - rm "${JAVA_HOME}/lib/security/cacerts" - ln -s /etc/ssl/certs/java/cacerts "${JAVA_HOME}/lib/security/cacerts" - env: PROFILES=OWB2 JDK=11 BUILD_JDK=11 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 11 -L BCL - env: PROFILES=OWB2 JDK=12 BUILD_JDK=12 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 12 -L GPL - env: PROFILES=OWB2 JDK=13 BUILD_JDK=13 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 13 -L GPL - env: PROFILES=OWB2 JDK=14 BUILD_JDK=14 before_install: - wget https://raw.githubusercontent.com/sormuras/bach/master/install-jdk.sh - . ./install-jdk.sh -F 14 -L GPL allow_failures: - env: PROFILES=OWB2 JDK=14 BUILD_JDK=14 - env: PROFILES=OWB2 JDK=14 # Not sure why, but these profiles fail in the JSF tests - env: PROFILES=tomee8-build-managed,OpenEJB-TomEE jdk: oraclejdk8 - env: PROFILES=tomee7-build-managed,OpenEJB-TomEE jdk: oraclejdk8 # Fails because it thinks an alternative is not a proper alternative? - env: PROFILES=Weld2 jdk: oraclejdk8 ================================================ FILE: LICENSE.txt ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. ================================================ FILE: README.md ================================================ # Apache DeltaSpike [![Build Status](https://github.com/apache/deltaspike/workflows/DeltaSpike%20CI/badge.svg)](https://github.com/apache/deltaspike/actions/workflows/ds-ci.yml) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) * [Documentation](https://deltaspike.apache.org) * [Mailing Lists](http://deltaspike.apache.org/community.html#Mailinglists) * [Contribution Guide](http://deltaspike.apache.org/source.html) * [JIRA](https://issues.apache.org/jira/browse/DELTASPIKE) * [Apache License v2.0](https://www.apache.org/licenses/LICENSE-2.0) **Apache DeltaSpike** is a suite of portable CDI Extensions intended to make application development easier when working with CDI and Java EE. Contexts and Dependency Injection is a specification, published as: * JSR-299 (CDI-1.0) http://docs.jboss.org/cdi/spec/1.0/html/ * JSR-346 (CDI-1.2) http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html * JSR-365 (CDI-2.0) http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html * Jakarta CDI-3.0 and later https://jakarta.ee/specifications/cdi/ Apache DeltaSpike is compatible with all those specification versions. Until Apache DeltaSpike 1.9.x we did target the ``javax`` package. The current Apache DeltaSpike-2.0.x releases target the ``jakarta`` namespace. Note that Apache DeltaSpike is **not** a CDI container itself, but a set of portable Extensions for it! Some of the key features of Apache DeltaSpike include: - A core module that supports component configuration, type safe messaging and internationalization, and exception handling. - A suite of utilities to make programmatic bean lookup easier. - A plugin for Java SE to bootstrap both JBoss Weld, Apache OpenWebBeans and other CDI containers outside of a JavaEE server. - JSF integration, including backporting of JSF 2.2 features for Java EE 6. - JPA integration and transaction support. - A Data module, to create an easy to use repository pattern on top of JPA. - Scheduler integration Testing support is also provided, to allow you to do low level unit testing of your CDI enabled projects. ## Getting Started The easiest way to get started with DeltaSpike is to use Maven or Gradle as a build tool, as described in [configuring in your project](http://deltaspike.apache.org/documentation/configure.html) ## Requirements to Build - Git - JDK 8 - Maven Just run `mvn clean install` from the top level directory, `deltaspike` to build the source code. ================================================ FILE: buildall.sh ================================================ #!/bin/sh ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### # # this is a small helper script for building a few container constellations locally # you can easily check the output via $> tail mvn-*.log | less # ##################################################################################### rm mvn-*log # CDI-2.0, EE8 # works fine with Java11 mvn clean install -POWB | tee mvn-owb4.0.3.log mvn clean install -PWeld -Dweld.version=5.1.7.Final | tee mvn-weld5.1.7.log # requires Java 17 mvn clean install -Ptomee-build-managed -Dtomee.version=10.1.5 | tee mvn-tomee10.1.5.log mvn clean install -Pwildfly-build-managed -Pwildfly.version=31.0.0.Final | tee mvn-wildfly-31.0.0.log # and now for the result check tail mvn-*.log | less ================================================ FILE: deltaspike/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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. ================================================ FILE: deltaspike/NOTICE ================================================ Apache DeltaSpike Copyright 2011 - 2018 The Apache Software Foundation This product includes software developed by The Apache Software Foundation (http://www.apache.org/). ================================================ FILE: deltaspike/README.md ================================================ title: Apache DeltaSpike Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. About Apache DeltaSpike ----------------------- Apache DeltaSpike is a CDI Extensions Project which contains the best mature features of JBoss Seam3, Apache MyFaces CODI and other CDI Extensions projects. License ------- Apache DeltaSpike is licensed under ALv2. See the LICENSE file for the full license text. Building Apache DeltaSpike -------------------- DeltaSpike is container agnostic. It just needs a working CDI container integration via Arquillian [1]. The different containers get activated via Maven Profiles. The following profiles exist so far: * OWB * Weld For building DeltaSpike with JBoss Weld [2] (Reference Implementation) invoke the following commandline: $> mvn clean install -PWeld For building DeltaSpike with Apache OpenWebBeans [3] execute the following command $> mvn clean install -POWB [1] http://www.jboss.org/arquillian [2] http://docs.jboss.org/weld/reference/1.1.0.Final/en-US/html/ [3] http://openwebbeans.apache.org ================================================ FILE: deltaspike/cdictrl/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.cdictrl cdictrl-project 2.0.2-SNAPSHOT ../pom.xml deltaspike-cdictrl-api jar Apache DeltaSpike CDI ContainerControl API This project provides a way to genericly run CDI containers from inside of unit tests or Java SE applications. jakarta.annotation jakarta.annotation-api jakarta.inject jakarta.inject-api jakarta.enterprise jakarta.enterprise.cdi-api jakarta.interceptor jakarta.interceptor-api org.apache.tomcat tomcat-servlet-api ================================================ FILE: deltaspike/cdictrl/api/src/main/java/org/apache/deltaspike/cdise/api/CdiContainer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.api; import jakarta.enterprise.inject.spi.BeanManager; import java.util.Map; /** *

A CdiTestContainer provides access to an underlying JSR-299 (CDI) * Container. It allows starting and stopping the container and to start * and stop the built-in contexts of that container.

* *

The intention is to provide a portable control for CDI containers in * Java SE environments. It is not intended for environments in which the * CDI container is under full control of the server already, e.g. in * EE-containers.

*/ public interface CdiContainer { /** *

Booting the CdiTestContainer will scan the whole classpath * for Beans and extensions available. * The container might throw a DeploymentException or similar on startup.

* *

Note: booting the container does not automatically * start all CDI Contexts! Depending on the underlying CDI container you * might need to invoke {@link #getContextControl()} and execute * {@link ContextControl#startContext(Class)} or * {@link ContextControl#startContexts()}

*/ void boot(); /** *

Like {@link #boot()} but allows to pass in a configuration Map * for the container.

*

Please note that the configuration is container implementation dependent!

* * @param properties */ void boot(Map properties); /** * This will shutdown the underlying CDI container and stop all contexts. */ void shutdown(); /** * @return the {@link BeanManager} or null it not available */ BeanManager getBeanManager(); /** * @return ContextControl for the started Container. null if the container is not yet started */ ContextControl getContextControl(); } ================================================ FILE: deltaspike/cdictrl/api/src/main/java/org/apache/deltaspike/cdise/api/CdiContainerLoader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.api; import java.util.Iterator; import java.util.ServiceLoader; /** *

This class provides access to the ContainerControl.

*

It uses the {@code java.util.ServiceLoader} mechanism to * automatically pickup the container providers from the classpath.

*

Usage: *

 *     CdiContainer container = CdiContainerLoader.getCdiContainer();
 *     container.boot();
 *     ...
 * 
*

*

CdiContainerLoader internally uses the {@link java.util.ServiceLoader} * to automatically detect the container implementation which should be used. *

*/ public final class CdiContainerLoader { private static CdiContainer cdiContainer = null; private CdiContainerLoader() { // private ct to prevent instantiation } /** * @return the {@link CdiContainer} implementation available on the classpath * @throws IllegalStateException if none or multiple CdiContainer implementations * are found on the classpath. */ public static synchronized CdiContainer getCdiContainer() { if (cdiContainer == null) { // there is no dependency to any cdi implementation, we do all dynamically ServiceLoader cdiContainerLoader = ServiceLoader.load(CdiContainer.class); Iterator cdiIt = cdiContainerLoader.iterator(); if (cdiIt.hasNext()) { cdiContainer = cdiIt.next(); } else { throw new IllegalStateException("Could not find an implementation of " + CdiContainer.class.getName() + " available in the classpath!"); } if (cdiIt.hasNext()) { String foundContainers = getContainerDetails(); throw new IllegalStateException("Too many implementations of " + CdiContainer.class.getName() + " found in the classpath! Details: " + foundContainers); } } return cdiContainer; } private static String getContainerDetails() { StringBuilder result = new StringBuilder(); Class containerClass; for (CdiContainer cdiContainer : ServiceLoader.load(CdiContainer.class)) { containerClass = cdiContainer.getClass(); result.append(containerClass.getProtectionDomain().getCodeSource().getLocation().toExternalForm()); result.append(containerClass.getName()); result.append(System.getProperty("line.separator")); } return result.toString(); } } ================================================ FILE: deltaspike/cdictrl/api/src/main/java/org/apache/deltaspike/cdise/api/ContextControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.api; import java.lang.annotation.Annotation; /** * Control native CDI Container Contexts. * Just inject this interface and you gain manual access over built-in Contexts. * The respective integration code will provide a &064;Dependent scoped instance * which itself is stateless. * * The {@link #startContext(Class)} and {@link #stopContext(Class)} only affect * the current Thread. When leaving a Thread each started context needs to get * stopped as well (best practice is to do that in a finally block. * * If a container supports controlling the Session Context then each Thread will * get a new 'dummy' storage assigned. It is not intended to 'attach' to a real * Session but to allow the re-use of existing beans. * * Many containers make heavy use of ThreadLocals. Thus it might be necessary to * call *
 *     contextControl.startContext(ApplicationScoped.class);
 * 
* to 'attach' or 'activate' the ApplicationContext within your current Thread. */ public interface ContextControl { /** * This will start all container built-in Contexts */ void startContexts(); /** * Stop all container built-in Contexts and destroy all beans properly */ void stopContexts(); /** * Start the specified scope. This only works for scopes which are handled * by the CDI container itself. Custom scoped of 3rd party * Context implementations shall be started directly (they are portable anyway). * * @param scopeClass e.g. RequestScoped.class */ void startContext(Class scopeClass); /** * Stop the specified scope. This only works for scopes which are handled * by the CDI container itself. Custom scoped of 3rd party * Context implementations shall be stopped directly (they are portable anyway). * * @param scopeClass e.g. RequestScoped.class */ void stopContext(Class scopeClass); } ================================================ FILE: deltaspike/cdictrl/impl-openejb/pom.xml ================================================ 4.0.0 org.apache.deltaspike.cdictrl cdictrl-project 2.0.2-SNAPSHOT ../pom.xml deltaspike-cdictrl-openejb jar Apache DeltaSpike CDI OpenEJB-ContainerControl org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} org.apache.deltaspike.test deltaspike-cdictrl-tck ${project.version} test org.apache.openwebbeans openwebbeans-impl ${openejb.owb.version} provided org.apache.openwebbeans openwebbeans-ejb ${openejb.owb.version} provided org.apache.openwebbeans openwebbeans-ee ${openejb.owb.version} provided org.apache.openwebbeans openwebbeans-spi ${openejb.owb.version} provided org.apache.openwebbeans openwebbeans-web ${openejb.owb.version} provided org.apache.openwebbeans openwebbeans-ee-common ${openejb.owb.version} provided default true org.apache.tomee openejb-core ${tomee.version} provided jakarta.xml.bind jakarta.xml.bind-api 3.0.1 jakarta.activation jakarta.activation-api org.glassfish.jaxb jaxb-runtime 3.0.2 runtime jakarta.activation jakarta.activation-api tomee-build-managed org.apache.tomee openejb-core ${tomee.version} provided jakarta.xml.bind jakarta.xml.bind-api 3.0.1 jakarta.activation jakarta.activation-api org.glassfish.jaxb jaxb-runtime 3.0.2 runtime jakarta.activation jakarta.activation-api maven-dependency-plugin org.apache.maven.plugins unpack-context generate-sources unpack **\/META-INF\/**,**\/OpenWebBeansContainerControl.class org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} ${project.build.directory}/classes/ unpack process-test-classes unpack org.apache.deltaspike.test deltaspike-cdictrl-tck ${project.version} ${project.build.directory}/test-classes/ ================================================ FILE: deltaspike/cdictrl/impl-openejb/src/main/java/org/apache/deltaspike/cdise/openejb/OpenEjbContainerControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.openejb; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.openejb.OpenEjbContainer; import org.apache.openejb.core.LocalInitialContext; import org.apache.openejb.core.LocalInitialContextFactory; import org.apache.webbeans.config.WebBeansContext; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.logging.Logger; /** * OpenEJB specific implementation of {@link org.apache.deltaspike.cdise.api.CdiContainer}. */ @SuppressWarnings("UnusedDeclaration") public class OpenEjbContainerControl implements CdiContainer { private static final Logger LOG = Logger.getLogger(OpenEjbContainerControl.class.getName()); // global container config private static final Properties PROPERTIES = new Properties(); static { // global properties PROPERTIES.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName()); PROPERTIES.setProperty(LocalInitialContext.ON_CLOSE, LocalInitialContext.Close.DESTROY.name()); try { OpenEjbContainerControl.class.getClassLoader().loadClass("org.apache.openejb.server.ServiceManager"); PROPERTIES.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true"); } catch (final Exception e) { // ignored } } private ContextControl ctxCtrl = null; private Bean ctxCtrlBean = null; private CreationalContext ctxCtrlCreationalContext = null; private Context context = null; private BeanManager beanManager; @Override public BeanManager getBeanManager() { return beanManager; } @Override public synchronized void boot() { boot(null); } @Override public synchronized void boot(Map properties) { if (context == null) { // this immediately boots the container final Properties p = new Properties(); p.putAll(PROPERTIES); if (properties != null) // override with user config { p.putAll(properties); } try { context = new InitialContext(p); } catch (final NamingException e) { throw new RuntimeException(e); } beanManager = WebBeansContext.currentInstance().getBeanManagerImpl(); } } @Override public synchronized void shutdown() { if (ctxCtrl != null) { try { ctxCtrl.stopContexts(); } catch (Exception e) { // contexts likely already stopped } ctxCtrlBean.destroy(ctxCtrl, ctxCtrlCreationalContext); } if (context != null) { try { context.close(); } catch (final NamingException e) { // no-op } context = null; } ctxCtrl = null; ctxCtrlBean = null; ctxCtrlCreationalContext = null; beanManager = null; } @Override public synchronized ContextControl getContextControl() { if (ctxCtrl == null) { BeanManager beanManager = getBeanManager(); if (beanManager == null) { LOG.warning("If the CDI-container was started by the environment, you can't use this helper." + "Instead you can resolve ContextControl manually " + "(e.g. via BeanProvider.getContextualReference(ContextControl.class) ). " + "If the container wasn't started already, you have to use CdiContainer#boot before."); return null; } Set> beans = beanManager.getBeans(ContextControl.class); ctxCtrlBean = (Bean) beanManager.resolve(beans); ctxCtrlCreationalContext = getBeanManager() .createCreationalContext(ctxCtrlBean); ctxCtrl = (ContextControl) getBeanManager().getReference(ctxCtrlBean, ContextControl.class, ctxCtrlCreationalContext); } return ctxCtrl; } } ================================================ FILE: deltaspike/cdictrl/impl-openejb/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/cdictrl/impl-openejb/src/main/resources/META-INF/services/org.apache.deltaspike.cdise.api.CdiContainer ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.cdise.openejb.OpenEjbContainerControl ================================================ FILE: deltaspike/cdictrl/impl-openejb/src/test/java/org/apache/deltaspike/cdise/openejb/OpenEJbContainerControlConfigurationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.openejb; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.openejb.bean.Foo; import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.spi.ContainerSystem; import org.junit.Test; import jakarta.enterprise.inject.spi.BeanManager; import javax.naming.NamingException; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class OpenEJbContainerControlConfigurationTest { @Test public void ensureDataSourceExist() { final CdiContainer container = CdiContainerLoader.getCdiContainer(); container.boot(new HashMap() {{ put("foo", "new://Resource?type=DataSource"); put("foo.JdbcUrl", "jdbc:hsqldb:mem:foo"); put("foo.JtaManaged", "false"); }}); try { final DataSource ds = DataSource.class.cast(SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext().lookup("java:openejb/Resource/foo")); Connection c = null; try { c = ds.getConnection(); assertEquals("jdbc:hsqldb:mem:foo", c.getMetaData().getURL()); } catch (SQLException e) { fail(e.getMessage()); } finally { try { if (c != null) { c.close(); } } catch (SQLException e) { // no-op } } } catch (final NamingException e) { fail(e.getMessage()); } finally { container.shutdown(); } } @Test public void basicInjection() // useless because of tcks but nice to have when working on this specific container { final CdiContainer container = CdiContainerLoader.getCdiContainer(); container.boot(); try { final BeanManager beanManager = container.getBeanManager(); assertEquals("foo", Foo.class.cast(beanManager.getReference(beanManager.resolve(beanManager.getBeans(Foo.class)), Foo.class, null)).name()); } finally { container.shutdown(); } } } ================================================ FILE: deltaspike/cdictrl/impl-openejb/src/test/java/org/apache/deltaspike/cdise/openejb/bean/Foo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.openejb.bean; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class Foo { public String name() { return "foo"; } } ================================================ FILE: deltaspike/cdictrl/impl-owb/pom.xml ================================================ 4.0.0 org.apache.deltaspike.cdictrl cdictrl-project 2.0.2-SNAPSHOT ../pom.xml deltaspike-cdictrl-owb jar Apache DeltaSpike CDI OWB-ContainerControl org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} org.apache.deltaspike.test test-utils ${project.version} test org.apache.deltaspike.test deltaspike-cdictrl-tck ${project.version} test org.apache.tomcat tomcat-servlet-api maven-dependency-plugin org.apache.maven.plugins unpack process-test-classes unpack org.apache.deltaspike.test deltaspike-cdictrl-tck ${project.version} ${project.build.directory}/test-classes/ OWB true jakarta.annotation jakarta.annotation-api jakarta.inject jakarta.inject-api jakarta.enterprise jakarta.enterprise.cdi-api jakarta.interceptor jakarta.interceptor-api org.apache.openwebbeans openwebbeans-impl ${owb.version} provided org.apache.openwebbeans openwebbeans-spi ${owb.version} provided ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/MockHttpSession.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.owb; import java.util.Enumeration; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import jakarta.enterprise.inject.Vetoed; import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpSession; /** * A simple mock HttpSession */ @Vetoed // ignore this as CDI bean public class MockHttpSession implements HttpSession { private String sessionId; private Map sessionMap = new ConcurrentHashMap(); public MockHttpSession(String sessionId) { this.sessionId = sessionId; } public long getCreationTime() { return 0; } public String getId() { return sessionId; } public long getLastAccessedTime() { return 0; } public ServletContext getServletContext() { return null; } public void setMaxInactiveInterval(int interval) { } public int getMaxInactiveInterval() { return 0; } public Object getAttribute(String name) { return this.sessionMap.get(name); } public Object getValue(String name) { return getAttribute(name); } public Enumeration getAttributeNames() { return null; } public String[] getValueNames() { return new String[0]; } public void setAttribute(String name, Object value) { this.sessionMap.put(name, value); } public void putValue(String name, Object value) { setAttribute(name, value); } public void removeAttribute(String name) { this.sessionMap.remove(name); } public void removeValue(String name) { removeAttribute(name); } public void invalidate() { this.sessionMap.clear(); } public boolean isNew() { return false; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } MockHttpSession that = (MockHttpSession) o; if (sessionId != null ? !sessionId.equals(that.sessionId) : that.sessionId != null) { return false; } return true; } @Override public int hashCode() { return sessionId != null ? sessionId.hashCode() : 0; } @Override public String toString() { return "MockHttpSession{" + "sessionId='" + sessionId + '\'' + '}'; } } ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/MockServletContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.owb; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.EventListener; import java.util.Hashtable; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import jakarta.enterprise.inject.Vetoed; import jakarta.servlet.Filter; import jakarta.servlet.FilterRegistration; import jakarta.servlet.RequestDispatcher; import jakarta.servlet.Servlet; import jakarta.servlet.ServletContext; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRegistration; import jakarta.servlet.SessionCookieConfig; import jakarta.servlet.SessionTrackingMode; import jakarta.servlet.descriptor.JspConfigDescriptor; /** * Mock ServletContext needed to startup the container. * */ @Vetoed // ignore this as CDI bean public class MockServletContext implements ServletContext { private static MockServletContext instance = new MockServletContext(); private Hashtable attributes = new Hashtable(); private MockServletContext() { // this class is only accessible via getInstance } public static synchronized MockServletContext getInstance() { return instance; } public static ServletContextEvent getServletContextEvent() { return new ServletContextEvent(getInstance()); } public Object getAttribute(String name) { return attributes.get(name); } public Enumeration getAttributeNames() { return attributes.keys(); } public ServletContext getContext(String uripath) { return this; } public String getContextPath() { return "mockContextpath"; } public String getInitParameter(String name) { return null; } public Enumeration getInitParameterNames() { return new StringTokenizer(""); // 'standard' empty Enumeration } public int getMajorVersion() { return 2; } public String getMimeType(String file) { return null; } public int getMinorVersion() { return 0; } public RequestDispatcher getNamedDispatcher(String name) { return null; } public String getRealPath(String path) { return "mockRealPath"; } public RequestDispatcher getRequestDispatcher(String path) { return null; } public URL getResource(String path) throws MalformedURLException { return null; } public InputStream getResourceAsStream(String path) { return null; } public Set getResourcePaths(String path) { return null; } public String getServerInfo() { return "mockServer"; } public Servlet getServlet(String name) throws ServletException { return null; } public String getServletContextName() { return null; } public Enumeration getServletNames() { return null; } public Enumeration getServlets() { return null; } public void log(String msg) { // nothing to do } public void log(Exception exception, String msg) { // nothing to do } public void log(String message, Throwable throwable) { // nothing to do } public void removeAttribute(String name) { attributes.remove(name); } @SuppressWarnings("unchecked") public void setAttribute(String name, Object object) { attributes.put(name, object); } @Override public boolean setInitParameter(String name, String value) { return false; } @Override public ServletRegistration.Dynamic addServlet(String servletName, String className) throws IllegalArgumentException, IllegalStateException { return null; } @Override public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) throws IllegalArgumentException, IllegalStateException { return null; } @Override public ServletRegistration.Dynamic addServlet(String servletName, Class clazz) throws IllegalArgumentException, IllegalStateException { return null; } @Override public ServletRegistration.Dynamic addJspFile(String jspName, String jspFile) { return null; } @Override public T createServlet(Class clazz) throws ServletException { return null; } @Override public ServletRegistration getServletRegistration(String servletName) { return null; } @Override public Map getServletRegistrations() { return null; } @Override public FilterRegistration.Dynamic addFilter(String filterName, String className) throws IllegalArgumentException, IllegalStateException { return null; } @Override public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) throws IllegalArgumentException, IllegalStateException { return null; } @Override public FilterRegistration.Dynamic addFilter(String filterName, Class filterClass) throws IllegalArgumentException, IllegalStateException { return null; } @Override public T createFilter(Class clazz) throws ServletException { return null; } @Override public FilterRegistration getFilterRegistration(String filterName) { return null; } @Override public Map getFilterRegistrations() { return null; } @Override public void addListener(Class listenerClass) { } @Override public void addListener(String className) { } @Override public void addListener(T t) { } @Override public T createListener(Class clazz) throws ServletException { return null; } @Override public void declareRoles(String... roleNames) { } @Override public String getVirtualServerName() { return null; } @Override public int getSessionTimeout() { return 0; } @Override public void setSessionTimeout(int sessionTimeout) { } @Override public String getRequestCharacterEncoding() { return null; } @Override public void setRequestCharacterEncoding(String encoding) { } @Override public String getResponseCharacterEncoding() { return null; } @Override public void setResponseCharacterEncoding(String encoding) { } @Override public SessionCookieConfig getSessionCookieConfig() { return null; } @Override public void setSessionTrackingModes(Set sessionTrackingModes) { } @Override public Set getDefaultSessionTrackingModes() { return null; } @Override public int getEffectiveMajorVersion() throws UnsupportedOperationException { return 0; } @Override public int getEffectiveMinorVersion() throws UnsupportedOperationException { return 0; } @Override public Set getEffectiveSessionTrackingModes() { return null; } @Override public ClassLoader getClassLoader() { return null; } @Override public JspConfigDescriptor getJspConfigDescriptor() { return null; } } ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContainerControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.owb; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.spi.ContainerLifecycle; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import java.util.Map; import java.util.Set; import java.util.logging.Logger; /** * OpenWebBeans specific implementation of {@link org.apache.deltaspike.cdise.api.CdiContainer}. */ @SuppressWarnings("UnusedDeclaration") public class OpenWebBeansContainerControl implements CdiContainer { private static final Logger LOG = Logger.getLogger(OpenWebBeansContainerControl.class.getName()); private ContainerLifecycle lifecycle; private ContextControl ctxCtrl = null; private Bean ctxCtrlBean = null; private CreationalContext ctxCtrlCreationalContext = null; @Override public BeanManager getBeanManager() { if (lifecycle == null) { return null; } return lifecycle.getBeanManager(); } @Override public synchronized void boot() { lifecycle = WebBeansContext.currentInstance().getService(ContainerLifecycle.class); Object mockServletContextEvent = null; if (OpenWebBeansContextControl.isServletApiAvailable()) { mockServletContextEvent = OwbHelper.getMockServletContextEvent(); } lifecycle.startApplication(mockServletContextEvent); } @Override public void boot(Map properties) { // we do not yet support any configuration. boot(); } @Override public synchronized void shutdown() { if (ctxCtrl != null) { try { ctxCtrl.stopContexts(); } catch (Exception e) { // contexts likely already stopped } ctxCtrlBean.destroy(ctxCtrl, ctxCtrlCreationalContext); ctxCtrl = null; } if (lifecycle != null) { Object mockServletContextEvent = null; if (OpenWebBeansContextControl.isServletApiAvailable()) { mockServletContextEvent = OwbHelper.getMockServletContextEvent(); } lifecycle.stopApplication(mockServletContextEvent); } lifecycle = null; } @Override public synchronized ContextControl getContextControl() { if (ctxCtrl == null) { BeanManager beanManager = getBeanManager(); if (beanManager == null) { LOG.warning("If the CDI-container was started by the environment, you can't use this helper." + "Instead you can resolve ContextControl manually " + "(e.g. via BeanProvider.getContextualReference(ContextControl.class) ). " + "If the container wasn't started already, you have to use CdiContainer#boot before."); return null; } Set> beans = beanManager.getBeans(ContextControl.class); ctxCtrlBean = (Bean) beanManager.resolve(beans); ctxCtrlCreationalContext = getBeanManager().createCreationalContext(ctxCtrlBean); ctxCtrl = (ContextControl) getBeanManager().getReference(ctxCtrlBean, ContextControl.class, ctxCtrlCreationalContext); } return ctxCtrl; } @Override public String toString() { return "OpenWebBeansContainerControl"; } } ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OpenWebBeansContextControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.owb; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Singleton; import java.lang.annotation.Annotation; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.spi.ContextsService; /** * OWB specific impl of the {@link ContextControl} */ @Dependent @SuppressWarnings("UnusedDeclaration") public class OpenWebBeansContextControl implements ContextControl { /** * we cannot directly link to MockHttpSession as this would lead to * NoClassDefFound errors for cases where no servlet-api is on the classpath. * E.g in pure SE environments. */ private static ThreadLocal mockSessions = new ThreadLocal(); @Override public void startContexts() { ContextsService contextsService = getContextsService(); startSingletonScope(); startApplicationScope(); startSessionScope(); startRequestScope(); startConversationScope(); } public void stopContexts() { stopSessionScope(); stopConversationScope(); stopRequestScope(); stopApplicationScope(); stopSingletonScope(); } @Override public void startContext(Class scopeClass) { if (scopeClass.isAssignableFrom(ApplicationScoped.class)) { startApplicationScope(); } else if (scopeClass.isAssignableFrom(SessionScoped.class)) { startSessionScope(); } else if (scopeClass.isAssignableFrom(RequestScoped.class)) { startRequestScope(); } else if (scopeClass.isAssignableFrom(ConversationScoped.class)) { startConversationScope(); } } public void stopContext(Class scopeClass) { if (scopeClass.isAssignableFrom(ApplicationScoped.class)) { stopApplicationScope(); } else if (scopeClass.isAssignableFrom(SessionScoped.class)) { stopSessionScope(); } else if (scopeClass.isAssignableFrom(RequestScoped.class)) { stopRequestScope(); } else if (scopeClass.isAssignableFrom(ConversationScoped.class)) { stopConversationScope(); } } static boolean isServletApiAvailable() { try { Class servletClass = Class.forName("jakarta.servlet.http.HttpSession"); return servletClass != null; } catch (ClassNotFoundException e) { return false; } } /* * start scopes */ private void startSingletonScope() { ContextsService contextsService = getContextsService(); Object mockServletContext = null; if (isServletApiAvailable()) { mockServletContext = OwbHelper.getMockServletContext(); } contextsService.startContext(Singleton.class, mockServletContext); } private void startApplicationScope() { ContextsService contextsService = getContextsService(); Object mockServletContext = null; if (isServletApiAvailable()) { mockServletContext = OwbHelper.getMockServletContext(); } contextsService.startContext(ApplicationScoped.class, mockServletContext); } private void startSessionScope() { ContextsService contextsService = getContextsService(); Object mockSession = null; if (isServletApiAvailable()) { mockSession = mockSessions.get(); if (mockSession == null) { // we simply use the ThreadName as 'sessionId' mockSession = OwbHelper.getMockSession(Thread.currentThread().getName()); mockSessions.set(mockSession); } } contextsService.startContext(SessionScoped.class, mockSession); } private void startRequestScope() { ContextsService contextsService = getContextsService(); contextsService.startContext(RequestScoped.class, null); } private void startConversationScope() { ContextsService contextsService = getContextsService(); contextsService.startContext(ConversationScoped.class, null); } /* * stop scopes */ private void stopSingletonScope() { ContextsService contextsService = getContextsService(); Object mockServletContext = null; if (isServletApiAvailable()) { mockServletContext = OwbHelper.getMockServletContext(); } contextsService.endContext(Singleton.class, mockServletContext); } private void stopApplicationScope() { ContextsService contextsService = getContextsService(); Object mockServletContext = null; if (isServletApiAvailable()) { mockServletContext = OwbHelper.getMockServletContext(); } contextsService.endContext(ApplicationScoped.class, mockServletContext); } private void stopSessionScope() { ContextsService contextsService = getContextsService(); Object mockSession = null; if (isServletApiAvailable()) { mockSession = mockSessions.get(); mockSessions.set(null); mockSessions.remove(); } contextsService.endContext(SessionScoped.class, mockSession); } private void stopRequestScope() { ContextsService contextsService = getContextsService(); contextsService.endContext(RequestScoped.class, null); } private void stopConversationScope() { ContextsService contextsService = getContextsService(); contextsService.endContext(ConversationScoped.class, null); } private ContextsService getContextsService() { WebBeansContext webBeansContext = WebBeansContext.currentInstance(); return webBeansContext.getContextsService(); } } ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/java/org/apache/deltaspike/cdise/owb/OwbHelper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.owb; import jakarta.servlet.ServletContextEvent; /** * A few utility methods for OWB */ public class OwbHelper { private OwbHelper() { // just to prevent initialisation } public static Object getMockSession(String sessionId) { return new MockHttpSession(sessionId); } public static Object getMockServletContextEvent() { return new ServletContextEvent(MockServletContext.getInstance()); } public static Object getMockServletContext() { return MockServletContext.getInstance(); } } ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/cdictrl/impl-owb/src/main/resources/META-INF/services/org.apache.deltaspike.cdise.api.CdiContainer ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.cdise.owb.OpenWebBeansContainerControl ================================================ FILE: deltaspike/cdictrl/impl-weld/pom.xml ================================================ 4.0.0 org.apache.deltaspike.cdictrl cdictrl-project 2.0.2-SNAPSHOT ../pom.xml deltaspike-cdictrl-weld jar Apache DeltaSpike CDI Weld-ContainerControl org.jboss.weld weld-core-bom ${weld.version} pom import org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} org.jboss.weld.se weld-se-core provided org.jboss.weld weld-api provided jakarta.el jakarta.el-api test org.apache.deltaspike.test test-utils ${project.version} provided Weld maven-dependency-plugin org.apache.maven.plugins unpack process-test-classes unpack org.apache.deltaspike.test deltaspike-cdictrl-tck ${project.version} ${project.build.directory}/test-classes/ ================================================ FILE: deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContainerControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.weld; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.ContextControl; import org.jboss.weld.Container; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import org.jboss.weld.util.reflection.Formats; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collectors; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; /** * Weld specific implementation of {@link org.apache.deltaspike.cdise.api.CdiContainer}. */ @SuppressWarnings("UnusedDeclaration") public class WeldContainerControl implements CdiContainer { private static final Logger LOG = Logger.getLogger(WeldContainerControl.class.getName()); private Weld weld; private WeldContainer weldContainer; private Bean ctxCtrlBean = null; private CreationalContext ctxCtrlCreationalContext = null; private ContextControl ctxCtrl = null; @Override public BeanManager getBeanManager() { if (weldContainer == null) { return null; } return weldContainer.getBeanManager(); } @Override public synchronized void boot() { weld = new Weld(); weldContainer = weld.initialize(); } @Override public void boot(Map properties) { weld = new Weld(); // setProperties only exists from Weld-2.x onwards setProperties(weld, convertProperties(properties)); weldContainer = weld.initialize(); } private void setProperties(Weld weld, Map properties) { if (properties == null || properties.isEmpty()) { return; } Method setPropertiesMethod = extractMethod(Weld.class, "setProperties", Map.class); if (setPropertiesMethod != null) { if (!setPropertiesMethod.isAccessible()) { setPropertiesMethod.setAccessible(true); } try { setPropertiesMethod.invoke(weld, properties); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } } else { LOG.warning("No setProperties method available on this version of Weld - ignoring passed in properties!"); } } /** * Extract a method with the given name and parameterTypes. * Return {@code null} if no such visible method exists on the given class. * * @param clazz * @param methodName * @param parameterTypes * @return */ private static Method extractMethod(Class clazz, String methodName, Class... parameterTypes) { try { return clazz != null ? clazz.getMethod(methodName, parameterTypes) : null; } catch (NoSuchMethodException e) { return null; } } @Override public synchronized void shutdown() { if (ctxCtrl != null) { try { // stops all built-in contexts except for ApplicationScoped as that one is handled by Weld ctxCtrl.stopContext(ConversationScoped.class); ctxCtrl.stopContext(RequestScoped.class); ctxCtrl.stopContext(SessionScoped.class); ctxCtrlBean.destroy(ctxCtrl, ctxCtrlCreationalContext); } catch (Exception e) { // contexts likely already stopped } } try { weld.shutdown(); } catch (Exception e) { // something caused weld to shutdown already. } weld = null; ctxCtrl = null; ctxCtrlBean = null; ctxCtrlCreationalContext = null; } @Override public synchronized ContextControl getContextControl() { if (ctxCtrl == null) { BeanManager beanManager = getBeanManager(); if (beanManager == null) { LOG.warning("If the CDI-container was started by the environment, you can't use this helper." + "Instead you can resolve ContextControl manually " + "(e.g. via BeanProvider.getContextualReference(ContextControl.class) ). " + "If the container wasn't started already, you have to use CdiContainer#boot before."); return null; } Set> beans = beanManager.getBeans(ContextControl.class); ctxCtrlBean = (Bean) beanManager.resolve(beans); ctxCtrlCreationalContext = getBeanManager().createCreationalContext(ctxCtrlBean); ctxCtrl = (ContextControl) getBeanManager().getReference(ctxCtrlBean, ContextControl.class, ctxCtrlCreationalContext); } return ctxCtrl; } @Override public String toString() { return "WeldContainerControl [Weld " + Formats.version(Container.class.getPackage()) + ']'; } private static Map convertProperties(final Map map) { if (map == null) { return Collections.emptyMap(); } return map.entrySet().stream() .collect(Collectors.toMap( entry -> String.valueOf(entry.getKey()), Map.Entry::getValue )); } } ================================================ FILE: deltaspike/cdictrl/impl-weld/src/main/java/org/apache/deltaspike/cdise/weld/WeldContextControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.weld; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.inject.Instance; import jakarta.inject.Inject; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; import org.apache.deltaspike.cdise.api.ContextControl; import org.jboss.weld.context.ApplicationContext; import org.jboss.weld.context.bound.BoundConversationContext; import org.jboss.weld.context.bound.BoundRequestContext; import org.jboss.weld.context.bound.BoundSessionContext; import org.jboss.weld.context.bound.MutableBoundRequest; /** * Weld specific impl of the {@link org.apache.deltaspike.cdise.api.ContextControl} */ @Dependent @SuppressWarnings("UnusedDeclaration") public class WeldContextControl implements ContextControl { private static ThreadLocal requestContexts = new ThreadLocal(); private static ThreadLocal> sessionMaps = new ThreadLocal>(); @Inject private ApplicationContext applicationContext; @Inject private BoundSessionContext sessionContext; @Inject private Instance requestContextFactory; @Inject private BoundConversationContext conversationContext; @Override public void startContexts() { startApplicationScope(); startSessionScope(); startRequestScope(); startConversationScope(null); } @Override public void startContext(Class scopeClass) { if (scopeClass.isAssignableFrom(ApplicationScoped.class)) { startApplicationScope(); } else if (scopeClass.isAssignableFrom(SessionScoped.class)) { startSessionScope(); } else if (scopeClass.isAssignableFrom(RequestScoped.class)) { startRequestScope(); } else if (scopeClass.isAssignableFrom(ConversationScoped.class)) { startConversationScope(null); } } /** * Stops Conversation, Request and Session contexts. * Does NOT stop Application context, only invalidates * App scoped beans, as in Weld this context always active and clears * automatically on shutdown. * * {@inheritDoc} */ @Override public void stopContexts() { stopConversationScope(); stopRequestScope(); stopSessionScope(); stopApplicationScope(); } @Override public void stopContext(Class scopeClass) { if (scopeClass.isAssignableFrom(ApplicationScoped.class)) { stopApplicationScope(); } else if (scopeClass.isAssignableFrom(SessionScoped.class)) { stopSessionScope(); } else if (scopeClass.isAssignableFrom(RequestScoped.class)) { stopRequestScope(); } else if (scopeClass.isAssignableFrom(ConversationScoped.class)) { stopConversationScope(); } } /* * This is a no-op method. In Weld Application Context is active as soon as the container starts */ private void startApplicationScope() { // No-op, in Weld Application context is always active } /** * Weld Application context is active from container start to its shutdown * This method merely clears out all ApplicationScoped beans BUT the context * will still be active which may result in immediate re-creation of some beans. */ private void stopApplicationScope() { // Welds ApplicationContext gets cleaned at shutdown. // Weld App context should be always active if (applicationContext.isActive()) { // destroys the bean instances, but the context stays active applicationContext.invalidate(); } } void startRequestScope() { RequestContextHolder rcHolder = requestContexts.get(); if (rcHolder == null) { rcHolder = new RequestContextHolder(requestContextFactory.get(), new HashMap()); requestContexts.set(rcHolder); rcHolder.getBoundRequestContext().associate(rcHolder.getRequestMap()); rcHolder.getBoundRequestContext().activate(); } } void stopRequestScope() { RequestContextHolder rcHolder = requestContexts.get(); if (rcHolder != null && rcHolder.getBoundRequestContext().isActive()) { rcHolder.getBoundRequestContext().invalidate(); rcHolder.getBoundRequestContext().deactivate(); rcHolder.getBoundRequestContext().dissociate(rcHolder.getRequestMap()); requestContexts.set(null); requestContexts.remove(); } } private void startSessionScope() { Map sessionMap = sessionMaps.get(); if (sessionMap == null) { sessionMap = new HashMap(); sessionMaps.set(sessionMap); } sessionContext.associate(sessionMap); sessionContext.activate(); } private void stopSessionScope() { if (sessionContext.isActive()) { sessionContext.invalidate(); sessionContext.deactivate(); sessionContext.dissociate(sessionMaps.get()); sessionMaps.set(null); sessionMaps.remove(); } } void startConversationScope(String cid) { RequestContextHolder rcHolder = requestContexts.get(); if (rcHolder == null) { startRequestScope(); rcHolder = requestContexts.get(); } conversationContext.associate(new MutableBoundRequest(rcHolder.requestMap, sessionMaps.get())); conversationContext.activate(cid); } void stopConversationScope() { RequestContextHolder rcHolder = requestContexts.get(); if (rcHolder == null) { startRequestScope(); rcHolder = requestContexts.get(); } if (conversationContext.isActive()) { conversationContext.invalidate(); conversationContext.deactivate(); conversationContext.dissociate(new MutableBoundRequest(rcHolder.getRequestMap(), sessionMaps.get())); } } private static class RequestContextHolder { private final BoundRequestContext boundRequestContext; private final Map requestMap; private RequestContextHolder(BoundRequestContext boundRequestContext, Map requestMap) { this.boundRequestContext = boundRequestContext; this.requestMap = requestMap; } public BoundRequestContext getBoundRequestContext() { return boundRequestContext; } public Map getRequestMap() { return requestMap; } } } ================================================ FILE: deltaspike/cdictrl/impl-weld/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/cdictrl/impl-weld/src/main/resources/META-INF/services/org.apache.deltaspike.cdise.api.CdiContainer ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.cdise.weld.WeldContainerControl ================================================ FILE: deltaspike/cdictrl/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent 2.0.2-SNAPSHOT ../parent/pom.xml org.apache.deltaspike.cdictrl cdictrl-project pom Apache DeltaSpike ContainerControl parent api impl-owb impl-weld impl-openejb tck ================================================ FILE: deltaspike/cdictrl/tck/pom.xml ================================================ 4.0.0 org.apache.deltaspike.cdictrl cdictrl-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.test deltaspike-cdictrl-tck jar Apache DeltaSpike CDI ContainerControl TCK The TCK for testing ContainerControl implementations jakarta.annotation jakarta.annotation-api jakarta.inject jakarta.inject-api jakarta.enterprise jakarta.enterprise.cdi-api jakarta.interceptor jakarta.interceptor-api org.apache.tomcat tomcat-servlet-api junit junit compile true org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} org.apache.deltaspike.test test-utils ${project.version} compile ================================================ FILE: deltaspike/cdictrl/tck/src/main/java/org/apache/deltaspike/cdise/tck/ContainerCtrlTckTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.tck; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.cdise.tck.beans.Car; import org.apache.deltaspike.cdise.tck.beans.CarRepair; import org.apache.deltaspike.cdise.tck.beans.TestUser; import org.apache.deltaspike.test.control.LockedImplementation; import org.apache.deltaspike.test.control.LockedVersionRange; import org.apache.deltaspike.test.control.VersionControlRule; import org.apache.deltaspike.test.utils.Implementation; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; /** * TCK test for the {@link org.apache.deltaspike.cdise.api.CdiContainer} */ public class ContainerCtrlTckTest { private static final Logger log = Logger.getLogger(ContainerCtrlTckTest.class.getName()); private static final int NUM_THREADS = 10; @Rule public VersionControlRule versionControlRule = new VersionControlRule(); @Test public void testContainerBoot() { CdiContainer cc = CdiContainerLoader.getCdiContainer(); Assert.assertNotNull(cc); cc.boot(); cc.getContextControl().startContexts(); BeanManager bm = cc.getBeanManager(); Assert.assertNotNull(bm); Set> beans = bm.getBeans(CarRepair.class); Bean bean = bm.resolve(beans); CarRepair carRepair = (CarRepair) bm.getReference(bean, CarRepair.class, bm.createCreationalContext(bean)); Assert.assertNotNull(carRepair); Assert.assertNotNull(carRepair.getCar()); Assert.assertNotNull(carRepair.getCar().getUser()); cc.shutdown(); } @Test public void testParallelThreadExecution() throws Exception { final CdiContainer cc = CdiContainerLoader.getCdiContainer(); Assert.assertNotNull(cc); cc.boot(); cc.getContextControl().startContexts(); final BeanManager bm = cc.getBeanManager(); Assert.assertNotNull(bm); final AtomicInteger numErrors = new AtomicInteger(0); final ContextControl contextControl = cc.getContextControl(); Runnable runnable = new Runnable() { @Override public void run() { try { contextControl.startContext(SessionScoped.class); contextControl.startContext(RequestScoped.class); Set> beans = bm.getBeans(CarRepair.class); Bean bean = bm.resolve(beans); CarRepair carRepair = (CarRepair) bm.getReference(bean, CarRepair.class, bm.createCreationalContext(bean)); Assert.assertNotNull(carRepair); for (int i = 0; i < 100000; i++) { // we need the threads doing something ;) Assert.assertNotNull(carRepair.getCar()); Assert.assertNotNull(carRepair.getCar().getUser()); Assert.assertNull(carRepair.getCar().getUser().getName()); } contextControl.stopContext(RequestScoped.class); contextControl.stopContext(SessionScoped.class); } catch (Throwable e) { log.log(Level.SEVERE, "An exception happened on a new worker thread", e); numErrors.incrementAndGet(); } } }; Thread[] threads = new Thread[NUM_THREADS]; for (int i = 0 ; i < NUM_THREADS; i++) { threads[i] = new Thread(runnable); } for (int i = 0 ; i < NUM_THREADS; i++) { threads[i].start(); } for (int i = 0 ; i < NUM_THREADS; i++) { threads[i].join(); } Assert.assertEquals("An error happened while executing parallel threads", 0, numErrors.get()); cc.shutdown(); } /** * Stops and starts: application-, session- and request-scope. *

* application-scoped instance has a ref to * request-scoped instance which has a ref to * session-scoped instance. *

* If the deepest ref has the expected value, all levels in between were resetted correctly. */ @Test public void testRestartContexts() { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); Assert.assertNotNull(cdiContainer); cdiContainer.boot(); cdiContainer.getContextControl().startContexts(); BeanManager beanManager = cdiContainer.getBeanManager(); Assert.assertNotNull(beanManager); Set> beans = beanManager.getBeans(CarRepair.class); Bean bean = beanManager.resolve(beans); CarRepair carRepair = (CarRepair) beanManager.getReference(bean, CarRepair.class, beanManager.createCreationalContext(bean)); Assert.assertNotNull(carRepair); Car car = carRepair.getCar(); Assert.assertNotNull(car); Assert.assertNotNull(car.getUser()); carRepair.getCar().getUser().setName("tester"); Assert.assertEquals("tester", car.getUser().getName()); Assert.assertFalse(CarRepair.isPreDestroyCalled()); Assert.assertFalse(Car.isPreDestroyCalled()); Assert.assertFalse(TestUser.isPreDestroyCalled()); cdiContainer.getContextControl().stopContexts(); Assert.assertTrue(CarRepair.isPreDestroyCalled()); Assert.assertTrue(Car.isPreDestroyCalled()); Assert.assertTrue(TestUser.isPreDestroyCalled()); try { car.getUser(); // accessing the car should have triggered a ContextNotActiveException Assert.fail(); } catch (ContextNotActiveException e) { //do nothing - exception expected } cdiContainer.getContextControl().startContexts(); carRepair = (CarRepair) beanManager.getReference(bean, CarRepair.class, beanManager.createCreationalContext(bean)); Assert.assertNotNull(carRepair.getCar()); Assert.assertNotNull(carRepair.getCar().getUser()); Assert.assertNull(carRepair.getCar().getUser().getName()); cdiContainer.shutdown(); } @LockedImplementation(versions = { @LockedVersionRange(implementation = Implementation.WELD11, versionRange = "[1.1.14,1.2)"), @LockedVersionRange(implementation = Implementation.WELD20, versionRange = "[2.0.1.Final,2.1)") }) @Test public void testShutdownWithInactiveContexts() { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); Assert.assertNotNull(cdiContainer); cdiContainer.boot(); cdiContainer.getContextControl().startContexts(); // now do some random stuff BeanManager beanManager = cdiContainer.getBeanManager(); Assert.assertNotNull(beanManager); Set> beans = beanManager.getBeans(CarRepair.class); Bean bean = beanManager.resolve(beans); CarRepair carRepair = (CarRepair) beanManager.getReference(bean, CarRepair.class, beanManager.createCreationalContext(bean)); Assert.assertNotNull(carRepair); Car car = carRepair.getCar(); Assert.assertNotNull(car); Assert.assertNotNull(car.getUser()); carRepair.getCar().getUser().setName("tester"); Assert.assertEquals("tester", car.getUser().getName()); Assert.assertFalse(CarRepair.isPreDestroyCalled()); Assert.assertFalse(Car.isPreDestroyCalled()); Assert.assertFalse(TestUser.isPreDestroyCalled()); cdiContainer.getContextControl().stopContexts(); Assert.assertTrue(CarRepair.isPreDestroyCalled()); Assert.assertTrue(Car.isPreDestroyCalled()); Assert.assertTrue(TestUser.isPreDestroyCalled()); cdiContainer.shutdown(); } @Test public void testNewRequests() { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); Assert.assertNotNull(cdiContainer); cdiContainer.boot(); cdiContainer.getContextControl().startContext(SessionScoped.class); cdiContainer.getContextControl().startContext(RequestScoped.class); BeanManager beanManager = cdiContainer.getBeanManager(); Assert.assertNotNull(beanManager); TestUser testUser = resolveInstance(beanManager, TestUser.class); Assert.assertNotNull(testUser); testUser.setName("tester"); CarRepair carRepair = resolveInstance(beanManager, CarRepair.class); Assert.assertNotNull(carRepair); Car car = carRepair.getCar(); Assert.assertNotNull(car); Assert.assertNotNull(car.getUser()); Assert.assertEquals("tester", car.getUser().getName()); carRepair.getCar().getUser().setName("tck-tester"); Assert.assertEquals("tck-tester", testUser.getName()); cdiContainer.getContextControl().stopContext(RequestScoped.class); cdiContainer.getContextControl().startContext(RequestScoped.class); try { testUser = resolveInstance(beanManager, TestUser.class); Assert.assertNotNull(testUser); Assert.assertNotNull(testUser.getName()); Assert.assertEquals("tck-tester", testUser.getName()); } catch (ContextNotActiveException e) { Assert.fail(e.getMessage()); } try { carRepair = resolveInstance(beanManager, CarRepair.class); Assert.assertNotNull(carRepair); car = carRepair.getCar(); Assert.assertNotNull(car); Assert.assertNotNull(car.getUser()); Assert.assertNotNull(car.getUser().getName()); Assert.assertEquals("tck-tester", car.getUser().getName()); } catch (ContextNotActiveException e) { Assert.fail(e.getMessage()); } cdiContainer.shutdown(); } private T resolveInstance(BeanManager beanManager, Class beanClass) { Set> beans = beanManager.getBeans(beanClass); Bean bean = beanManager.resolve(beans); return (T) beanManager.getReference(bean, beanClass, beanManager.createCreationalContext(bean)); } } ================================================ FILE: deltaspike/cdictrl/tck/src/main/java/org/apache/deltaspike/cdise/tck/beans/Car.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.tck.beans; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @RequestScoped public class Car { private static ThreadLocal preDestroyCalled = new ThreadLocal(); @Inject private TestUser user; @PostConstruct protected void onPostConstruct() { //reset it preDestroyCalled.remove(); preDestroyCalled.set(false); } @PreDestroy protected void onPreDestroy() { preDestroyCalled.set(true); } public TestUser getUser() { return user; } public static boolean isPreDestroyCalled() { return preDestroyCalled.get(); } } ================================================ FILE: deltaspike/cdictrl/tck/src/main/java/org/apache/deltaspike/cdise/tck/beans/CarRepair.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.tck.beans; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class CarRepair { private static ThreadLocal preDestroyCalled = new ThreadLocal(); @Inject private Car car; @PostConstruct protected void onPostConstruct() { //reset it preDestroyCalled.remove(); preDestroyCalled.set(false); } @PreDestroy protected void onPreDestroy() { preDestroyCalled.set(true); } public Car getCar() { return car; } public static boolean isPreDestroyCalled() { return preDestroyCalled.get(); } } ================================================ FILE: deltaspike/cdictrl/tck/src/main/java/org/apache/deltaspike/cdise/tck/beans/TestUser.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.cdise.tck.beans; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.SessionScoped; import java.io.Serializable; @SessionScoped public class TestUser implements Serializable { private static final long serialVersionUID = -4171521313675763849L; private static ThreadLocal preDestroyCalled = new ThreadLocal(); private String name; @PostConstruct protected void onPostConstruct() { //reset it preDestroyCalled.remove(); preDestroyCalled.set(false); } @PreDestroy protected void onPreDestroy() { preDestroyCalled.set(true); } public String getName() { return name; } public void setName(String name) { this.name = name; } public static boolean isPreDestroyCalled() { return preDestroyCalled.get(); } } ================================================ FILE: deltaspike/cdictrl/tck/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/checkstyle-rules/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike checkstyle-rules jar Apache DeltaSpike CheckStyle-rules ================================================ FILE: deltaspike/checkstyle-rules/src/main/resources/deltaspike/asf-header.txt ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ ================================================ FILE: deltaspike/checkstyle-rules/src/main/resources/deltaspike/default-checks.xml ================================================  ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/common/DeltaSpike.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.common; import java.lang.annotation.Documented; 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; /** * Common qualifier to manage co-existence of DeltaSpike features and Java EE features. */ @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(value = RetentionPolicy.RUNTIME) @Documented @Qualifier public @interface DeltaSpike { } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/BeforeHandles.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marker annotation for a method to be considered an Exception Handler, handles the exception in the BEFORE traversal * of the exception chain. *

* Handlers methods typically have this form:
*

public void handle(@BeforeHandles @OptionalQualifier ExceptionEvent<TypeOfTheException> evt)
 * 
. *

* * If a handler method has a return type, it is ignored. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) @Documented public @interface BeforeHandles { /** * Precedence relative to callbacks for the same type. Handler with a higher ordinal is invoked before a handler * with a lower ordinal. */ int ordinal() default 0; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/ExceptionHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marker for types containing Exception Handler methods. * * @see BeforeHandles * @see Handles */ @Stereotype @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface ExceptionHandler { } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/ExceptionHandlingFlow.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; /** * Enum of exception handling states. Used in the dispatcher to determine how to markHandled. */ public enum ExceptionHandlingFlow { HANDLED, HANDLED_AND_CONTINUE, SKIP_CAUSE, ABORT, THROW_ORIGINAL, THROW } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/ExceptionStackItem.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; import java.util.Arrays; /** * Container for the exception and it's stack trace. */ @SuppressWarnings("CdiManagedBeanInconsistencyInspection") @Vetoed public final class ExceptionStackItem implements Serializable { private static final long serialVersionUID = 5162936095781886477L; private final Throwable throwable; private final StackTraceElement[] stackTraceElements; public ExceptionStackItem(final Throwable cause) { this(cause, cause.getStackTrace()); } public ExceptionStackItem(Throwable throwable, StackTraceElement[] stackTraceElements) { this.stackTraceElements = stackTraceElements.clone(); this.throwable = throwable; } public StackTraceElement[] getStackTraceElements() { return stackTraceElements.clone(); } public Throwable getThrowable() { return throwable; } @Override public String toString() { return new StringBuilder(). append("throwable: ").append(throwable).append(", "). append("stackTraceElements: ").append(Arrays.toString(stackTraceElements)). toString(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } ExceptionStackItem that = (ExceptionStackItem) o; if (!Arrays.equals(stackTraceElements, that.stackTraceElements)) { return false; } if (!throwable.equals(that.throwable)) { return false; } return true; } @Override public int hashCode() { int result = throwable.hashCode(); result = 31 * result + Arrays.hashCode(stackTraceElements); return result; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/HandlerMethod.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; /** * Metadata interface for an exception handler method. It is the responsibility of the * implementation to support {@link jakarta.enterprise.inject.spi.InjectionPoint}s and to * validate those {@link jakarta.enterprise.inject.spi.InjectionPoint}s. * * @param Exception for which this handler is responsible */ public interface HandlerMethod { /** * Obtains the set of handled event qualifiers. */ Set getQualifiers(); /** * Obtains the handled event type. */ Type getExceptionType(); /** * Flag indicating this handler should be invoked during the before traversal. */ boolean isBeforeHandler(); /** * Calls the handler method, passing the given event object. * * @param event event to pass to the handler. * @param beanManager The BeanManager to use */ void notify(ExceptionEvent event, BeanManager beanManager) throws Exception; /** * Obtains the precedence of the handler, relative to other handlers for the same type. Handler with a higher * ordinal is invoked before a handler with a lower ordinal. */ int getOrdinal(); /** * Basic {@link Object#equals(Object)} but must use all of the get methods from this interface to * maintain compatibility. * * @param o Object being compared to this. * @return true or false based on standard equality. */ @Override boolean equals(Object o); @Override int hashCode(); } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/Handles.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marker annotation for a method to be considered an Exception Handler. * *

* Handlers typically have this form: *

 * public void handle(@Handles @OptionalQualifier ExceptionEvent<TypeOfTheException> evt)
*

* * If a handler method has a return type, it is ignored. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) @Documented public @interface Handles { /** * Precedence relative to handlers for the same type. Handler with a higher ordinal is invoked before a handler with * a lower ordinal. */ int ordinal() default 0; //TODO discuss Precedence } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/event/ExceptionEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control.event; /** * Payload for an exception to be handled. Implementations of this interface should not expose internals and should * remain immutable. * * @param Exception type this event represents */ public interface ExceptionEvent { /** * The exception causing this event. */ T getException(); /** * Instructs the dispatcher to abort further processing of handlers. */ void abort(); /** * Instructs the dispatcher to throw the original exception after handler processing. */ void throwOriginal(); /** * Instructs the dispatcher to terminate additional handler processing and mark the event as handled. */ void handled(); /** * Default instruction to dispatcher, continues handler processing. */ void handledAndContinue(); /** * Similar to {@link ExceptionEvent#handledAndContinue()}, * but instructs the dispatcher to markHandled to the next element * in the cause chain without processing additional handlers for this cause chain element. */ void skipCause(); /** * Instructs the dispatcher to allow this handler to be invoked again. */ void unmute(); /** * Rethrow the exception, but use the given exception instead of the original. * * @param t Exception to be thrown in place of the original. */ void rethrow(Throwable t); /** * Check to see if this exception has been handled. */ boolean isMarkedHandled(); } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/event/ExceptionStackEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control.event; import org.apache.deltaspike.core.api.exception.control.ExceptionStackItem; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayDeque; import java.util.Collection; import java.util.Collections; import java.util.Deque; /** * Information about the current exception and exception cause container. This object is not immutable. */ @SuppressWarnings("CdiManagedBeanInconsistencyInspection") @Vetoed public class ExceptionStackEvent implements Serializable { private static final long serialVersionUID = -6069790756478700680L; private boolean root; private boolean last; private int initialStackSize; private Throwable next; private Collection remaining; private Deque exceptionStackItems; // private Deque origExceptionStackItems; // TODO: Later private Collection causes; private Throwable current; /** * Builds the stack from the given exception. * * @param exception Caught exception */ public ExceptionStackEvent(final Throwable exception) { if (exception == null) { throw new IllegalArgumentException("exception must not be null"); } Throwable e = exception; exceptionStackItems = new ArrayDeque(); do { exceptionStackItems.addFirst(new ExceptionStackItem(e)); if (e instanceof SQLException) { SQLException sqlException = (SQLException) e; while (sqlException.getNextException() != null) { sqlException = sqlException.getNextException(); exceptionStackItems.addFirst(new ExceptionStackItem(sqlException)); } } e = e.getCause(); } while (e != null); initialStackSize = exceptionStackItems.size(); causes = createThrowableCollection(exceptionStackItems); // TODO: Later this.origExceptionStackItems = new ArrayDeque(exceptionStackItems); init(); } private void init() { root = exceptionStackItems.size() == initialStackSize; if (!exceptionStackItems.isEmpty()) { current = exceptionStackItems.removeFirst().getThrowable(); remaining = Collections.unmodifiableCollection(exceptionStackItems); } else { remaining = Collections.emptyList(); current = null; } last = remaining.isEmpty(); next = (last) ? null : exceptionStackItems.peekFirst().getThrowable(); } private Collection createExceptionStackFrom(Collection throwables) { final Deque returningCollection = new ArrayDeque(throwables.size()); for (Throwable t : throwables) { returningCollection.addFirst(new ExceptionStackItem(t)); } return returningCollection; } private Collection createThrowableCollection(final Collection exceptionStackItems) { // allow current final Deque returningCollection = new ArrayDeque(exceptionStackItems.size() + 1); for (ExceptionStackItem item : exceptionStackItems) { returningCollection.addFirst(item.getThrowable()); } return returningCollection; } public Collection getCauseElements() { return Collections.unmodifiableCollection(causes); } /** * Test if iteration is finished * * @return finished with iteration */ public boolean isLast() { return last; } public Throwable getNext() { return next; } public Collection getRemaining() { return Collections.unmodifiableCollection(createThrowableCollection(remaining)); } /** * Tests if the current exception is the root exception * * @return Returns true if iteration is at the root exception (top of the inverted stack) */ public boolean isRoot() { return root; } /** * Current exception in the iteration * * @return current exception */ public Throwable getCurrent() { return current; } /** * Internal only. * * @param elements new stack. */ public void setCauseElements(Collection elements) { exceptionStackItems = new ArrayDeque(createExceptionStackFrom(elements)); init(); } /** * Internal only. */ public void skipCause() { init(); } /** * Done later * The original exception stack if it has been changed. * * @return The original exception stack public Deque getOrigExceptionStackItems() { } */ } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/control/event/ExceptionToCatchEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exception.control.event; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Entry point event into the Exception Control system. This object is nearly immutable, the only mutable portion * is the handled flag. */ @SuppressWarnings("CdiManagedBeanInconsistencyInspection") @Vetoed public class ExceptionToCatchEvent implements Serializable { private static final long serialVersionUID = 2646115104528108266L; private Throwable exception; private boolean handled; private transient Set qualifiers; private boolean optional; /** * Constructor that adds qualifiers for the handler(s) to run. * Typically only integrators will be using this constructor. * * @param exception Exception to handle * @param qualifiers qualifiers to use to narrow the handlers called */ public ExceptionToCatchEvent(Throwable exception, Annotation... qualifiers) { this.exception = exception; this.qualifiers = new HashSet(); Collections.addAll(this.qualifiers, qualifiers); this.optional = false; } /** * Basic constructor without any qualifiers defined. * * @param exception Exception to handle. */ public ExceptionToCatchEvent(Throwable exception) { this.exception = exception; this.qualifiers = Collections.emptySet(); this.optional = false; } public Throwable getException() { return exception; } /** * Internal only. * * @param handled new value */ public void setHandled(boolean handled) { this.handled = handled; } /** * Test to see if the exception has already been processed by an * {@link org.apache.deltaspike.core.api.exception.control.ExceptionHandler}. * * @return true if the exception has already been processed by a handler; false otherwise */ public boolean isHandled() { return handled; } /** * Qualifiers with which the instance was created. * * @return Qualifiers with which the instance was created. */ public Set getQualifiers() { return Collections.unmodifiableSet(qualifiers); } public boolean isOptional() { return optional; } public void setOptional(boolean optional) { this.optional = optional; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/lifecycle/Destroyed.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.lifecycle; 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 static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.inject.Qualifier; /** * Qualifier for events which are fired when servlet objects are destroyed. */ @Qualifier @Target({ TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented public @interface Destroyed { } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/lifecycle/Initialized.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.lifecycle; 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 static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.inject.Qualifier; /** * Qualifier for events which are fired when servlet objects are created. */ @Qualifier @Target({ TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented public @interface Initialized { } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/AlternativeLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link jakarta.enterprise.inject.Alternative}. */ public class AlternativeLiteral extends AnnotationLiteral implements Alternative { private static final long serialVersionUID = -4865048799125718216L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/AnyLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Any; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for the {@link jakarta.enterprise.inject.Any} annotation. */ public class AnyLiteral extends AnnotationLiteral implements Any { private static final long serialVersionUID = -8623640277155878657L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/ApplicationScopedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link ApplicationScoped} */ public class ApplicationScopedLiteral extends AnnotationLiteral implements ApplicationScoped { private static final long serialVersionUID = 6582580975876369665L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/ConversationScopedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link ConversationScoped} */ public class ConversationScopedLiteral extends AnnotationLiteral implements ConversationScoped { private static final long serialVersionUID = -7672396348051568920L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/DefaultLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Default; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link Default} */ public class DefaultLiteral extends AnnotationLiteral implements Default { private static final long serialVersionUID = 3240069236025230401L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/DeltaSpikeLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import org.apache.deltaspike.core.api.common.DeltaSpike; /** * Literal for the {@link org.apache.deltaspike.core.api.common.DeltaSpike} annotation. */ public class DeltaSpikeLiteral extends AnnotationLiteral implements DeltaSpike { public static final DeltaSpike INSTANCE = new DeltaSpikeLiteral(); private static final long serialVersionUID = 1835916508118085812L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/DependentScopeLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link Dependent} */ public class DependentScopeLiteral extends AnnotationLiteral implements Dependent { private static final long serialVersionUID = -7408316864366401212L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/DestroyedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import org.apache.deltaspike.core.api.lifecycle.Destroyed; /** * Annotation literal for {@link Destroyed}. */ public class DestroyedLiteral extends AnnotationLiteral implements Destroyed { public static final Destroyed INSTANCE = new DestroyedLiteral(); private static final long serialVersionUID = 8310730593030223981L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/InitializedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import org.apache.deltaspike.core.api.lifecycle.Initialized; /** * Annotation literal for {@link Initialized}. */ public class InitializedLiteral extends AnnotationLiteral implements Initialized { public static final Initialized INSTANCE = new InitializedLiteral(); private static final long serialVersionUID = 2392444150652655120L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/InjectableResourceLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import org.apache.deltaspike.core.api.resourceloader.InjectableResource; import org.apache.deltaspike.core.api.resourceloader.InjectableResourceProvider; import jakarta.enterprise.util.AnnotationLiteral; public class InjectableResourceLiteral extends AnnotationLiteral implements InjectableResource { private static final long serialVersionUID = 1705986508118055892L; private final Class resourceProvider; private final String location; public InjectableResourceLiteral(Class resourceProvider, String location) { this.resourceProvider = resourceProvider; this.location = location; } @Override public String location() { return this.location; } @Override public Class resourceProvider() { return this.resourceProvider; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/ModelLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Model; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link jakarta.enterprise.inject.Model} annotation. */ public class ModelLiteral extends AnnotationLiteral implements Model { private static final long serialVersionUID = -1828119201454843678L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/NamedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import jakarta.inject.Named; /** * Literal for {@link jakarta.inject.Named} qualifier. */ public class NamedLiteral extends AnnotationLiteral implements Named { private static final long serialVersionUID = -1457223276475846060L; private final String value; public NamedLiteral(String value) { this.value = value; } public NamedLiteral() { value = ""; } @Override public String value() { return value; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/NewLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.New; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link New} */ public class NewLiteral extends AnnotationLiteral implements New { private static final long serialVersionUID = -4134892777333672942L; private final Class value; public NewLiteral() { this(New.class); } public NewLiteral(Class value) { this.value = value; } /** * {@inheritDoc} */ @Override public Class value() { return value; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/RequestScopedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link RequestScoped} */ public class RequestScopedLiteral extends AnnotationLiteral implements RequestScoped { private static final long serialVersionUID = -6365776352042023537L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/SessionScopeLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link SessionScoped} */ public class SessionScopeLiteral extends AnnotationLiteral implements SessionScoped { private static final long serialVersionUID = -1425877068082208121L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/SingletonLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import jakarta.inject.Singleton; /** * Literal for {@link jakarta.inject.Singleton} */ public class SingletonLiteral extends AnnotationLiteral implements Singleton { private static final long serialVersionUID = 2387772903537960411L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/SpecializesLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Specializes; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link Specializes} */ public class SpecializesLiteral extends AnnotationLiteral implements Specializes { private static final long serialVersionUID = 5092179521672196834L; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/literal/TypedLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link jakarta.enterprise.inject.Typed} */ public class TypedLiteral extends AnnotationLiteral implements Typed { private static final long serialVersionUID = 6805980497117269525L; private final Class[] value; public TypedLiteral() { value = new Class[0]; } public TypedLiteral(Class[] value) { this.value = value; } @Override public Class[] value() { return value; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/resourceloader/AbstractResourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.resourceloader; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * An abstract InjectableResourceProvider implementation with some basic utility functionality. */ public abstract class AbstractResourceProvider implements InjectableResourceProvider { private static final Logger logger = Logger.getLogger(AbstractResourceProvider.class.getName()); @Inject @Any private Instance injectionPoint; protected boolean isXml(String fileName) { return fileName.endsWith(".xml"); } protected InjectionPoint getInjectionPoint() { return this.injectionPoint.get(); } protected Set getAnnotations() { return this.getInjectionPoint().getAnnotated().getAnnotations(); } protected void loadInputStreamToProperties(InputStream inputStream, Properties properties, String name) { boolean isXml = this.isXml(name); try { if (isXml) { properties.loadFromXML(inputStream); } else { properties.load(inputStream); } } catch (IOException e) { logger.log(Level.WARNING,"Unable to read resource " + name,e); } } @Override public Properties readProperties(InjectableResource injectableResource) { final Properties properties = new Properties(); final String name = injectableResource.location(); InputStream inputStream = null; try { inputStream = this.readStream(injectableResource); this.loadInputStreamToProperties(inputStream, properties, name); return properties; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Problem closing resource.", e); } } } } } @Override public List readStreams(InjectableResource injectableResource) { return Collections.singletonList(this.readStream(injectableResource)); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/resourceloader/ClasspathResourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.resourceloader; import org.apache.deltaspike.core.util.ClassUtils; import jakarta.enterprise.context.ApplicationScoped; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * A classpath-based resource provider. */ @ApplicationScoped public class ClasspathResourceProvider extends AbstractResourceProvider { private static final Logger logger = Logger.getLogger(ClasspathResourceProvider.class.getName()); @Override public InputStream readStream(final InjectableResource injectableResource) { try { List matchedStreams = this.readClassPath(injectableResource.location(),true); return matchedStreams.get(0); } catch (IOException e) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Problem reading resource.", e); } return null; } } @Override public List readStreams(InjectableResource injectableResource) { try { return readClassPath(injectableResource.location(),false); } catch (IOException e) { throw new IllegalStateException("Error while trying to load resources from classpath ",e); } } /** * Reads all possibly matching classpath entries for the given name. * * If requireUnique is true, then validates that 1 element is present before returning * * @param name * @param requireUnique * @return * @throws IOException * @throws IllegalStateException */ private List readClassPath(final String name, final boolean requireUnique) throws IllegalStateException,IOException { Enumeration urls = ClassUtils.getClassLoader(null).getResources(name); List urlList = new ArrayList(); List results = new ArrayList(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); InputStream is = url.openStream(); if (is != null) { results.add(is); urlList.add(url); } } if (requireUnique && results.size() != 1) { String msg = urlsToString(urlList,name); for (InputStream is : results) { try { is.close(); } catch (IOException e) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE,"Unable to close stream",e); } } } throw new IllegalStateException(msg); } return results; } private String urlsToString(List urls, String name) { if (urls.isEmpty()) { return String.format("No resources found for '%s'",name); } else { StringBuilder sb = new StringBuilder(); sb.append(String.format("multiple resources found for '%s'",name)); for (URL u : urls) { sb.append(" Match : ").append(u.toExternalForm()); } return sb.toString(); } } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/resourceloader/FileResourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.resourceloader; import jakarta.enterprise.context.ApplicationScoped; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.logging.Level; import java.util.logging.Logger; /** * A file-based resource provider, looking for a file based on the name. */ @ApplicationScoped public class FileResourceProvider extends AbstractResourceProvider { private static final Logger logger = Logger.getLogger(FileResourceProvider.class.getName()); InputStream readFile(final String name) { File f = new File(name); if (f.exists() && f.canRead() && f.isFile()) { try { return new FileInputStream(f); } catch (FileNotFoundException e) { logger.log(Level.SEVERE, "Problem reading resource.", e); return null; } } else { return null; } } @Override public InputStream readStream(InjectableResource injectableResource) { return readFile(injectableResource.location()); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/resourceloader/InjectableResource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.resourceloader; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.METHOD; /** * Qualifier which enables simple injection of resources into beans, eliminating the need to deal with their loading. * *

* Example: *

 * @Inject
 * @InjectableResource(location="myfile.properties")
 * private Properties props;
 *
 * @Inject
 * @InjectableResource(location="config.xml")
 * private InputStream inputStream;
 * 
* * This can be used to read files, from classpath or the file system, using two default implementations: * ClasspathResourceProvider and FileResourceProvider. They can be extended as well by implementing the * InjectableResourceProvider interface to allow reading from alternate sources, if needed (e.g. database LOBs, NoSQL * storage areas). *

*/ @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(value = RetentionPolicy.RUNTIME) @Documented @Qualifier public @interface InjectableResource { @Nonbinding Class resourceProvider() default ClasspathResourceProvider.class; @Nonbinding String location() default ""; } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/api/resourceloader/InjectableResourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.resourceloader; import java.io.InputStream; import java.util.List; import java.util.Properties; /** * Provides lookup capability to find a resource. * */ public interface InjectableResourceProvider { InputStream readStream(final InjectableResource injectableResource); List readStreams(final InjectableResource injectableResource); Properties readProperties(final InjectableResource injectableResource); } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/spi/event/IntrospectiveExceptionEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.exception.control.event; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.core.api.exception.control.ExceptionHandlingFlow; /** * Internal view into the ExceptionEvent. Methods on this interface are used by the ExceptionHandlerBroadcaster. */ public interface IntrospectiveExceptionEvent extends ExceptionEvent { /** * Check to see if this event has been unmuted and therefore called again. */ boolean isUnmute(); /** * The next expected step in the exception handling flow (i.e. abort, rethrow, etc) */ ExceptionHandlingFlow getCurrentExceptionHandlingFlow(); boolean isBeforeTraversal(); /** * Returns the exception that should be thrown if the next step in the flow is THROW. */ Throwable getThrowNewException(); } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/AnnotationUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; @Vetoed public abstract class AnnotationUtils { private AnnotationUtils() { // prevent instantiation } public static T extractAnnotationFromMethodOrClass( BeanManager beanManager, Method targetMethod, Class targetClass, Class targetAnnotationType) { T result = extractAnnotationFromMethod(beanManager, targetMethod, targetAnnotationType); if (result == null) { //see DELTASPIKE-517 Class unproxiedTargetClass = ProxyUtils.getUnproxiedClass(targetClass); // and if not found search on the class result = findAnnotation(beanManager, unproxiedTargetClass.getAnnotations(), targetAnnotationType); } return result; } public static T extractAnnotationFromMethod( BeanManager beanManager, Method targetMethod, Class targetAnnotationType) { return findAnnotation(beanManager, targetMethod.getAnnotations(), targetAnnotationType); } public static T findAnnotation( BeanManager beanManager, Annotation[] annotations, Class targetAnnotationType) { for (Annotation annotation : annotations) { if (targetAnnotationType.equals(annotation.annotationType())) { return (T) annotation; } if (beanManager.isStereotype(annotation.annotationType())) { T result = findAnnotation( beanManager, annotation.annotationType().getAnnotations(), targetAnnotationType); if (result != null) { return result; } } } return null; } //based on org.apache.webbeans.container.BeanCacheKey#getQualifierHashCode public static int getQualifierHashCode(Annotation annotation) { Class annotationClass = annotation.annotationType(); int hashCode = getTypeHashCode(annotationClass); for (Method member : annotationClass.getDeclaredMethods()) { if (member.isAnnotationPresent(Nonbinding.class)) { continue; } final Object annotationMemberValue = ReflectionUtils.invokeMethod(annotation, member, Object.class, true); final int arrayValue; if (annotationMemberValue == null /*possible with literals*/) { arrayValue = 0; } else if (annotationMemberValue.getClass().isArray()) { Class annotationMemberType = annotationMemberValue.getClass().getComponentType(); if (annotationMemberType.isPrimitive()) { if (Long.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((long[]) annotationMemberValue); } else if (Integer.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((int[]) annotationMemberValue); } else if (Short.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((short[]) annotationMemberValue); } else if (Double.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((double[]) annotationMemberValue); } else if (Float.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((float[]) annotationMemberValue); } else if (Boolean.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((boolean[]) annotationMemberValue); } else if (Byte.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((byte[]) annotationMemberValue); } else if (Character.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((char[]) annotationMemberValue); } else { arrayValue = 0; } } else { arrayValue = Arrays.hashCode((Object[]) annotationMemberValue); } } else { arrayValue = annotationMemberValue.hashCode(); } hashCode = 29 * hashCode + arrayValue; hashCode = 29 * hashCode + member.getName().hashCode(); } return hashCode; } private static int getTypeHashCode(Type type) { int typeHash = type.hashCode(); if (typeHash == 0 && type instanceof Class) { return ((Class)type).getName().hashCode(); } return typeHash; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/CollectionUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import java.util.Collection; import jakarta.enterprise.inject.Vetoed; /** * A collection of utilities for working with Collections */ @Vetoed public abstract class CollectionUtils { private CollectionUtils() { // prevent instantiation } public static boolean isEmpty(Collection collection) { return collection == null || collection.isEmpty(); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/ParentExtensionStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.spi.Extension; import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; /** * Support for Containers with 'hierarchic BeanManagers' * This is mostly useful for EAR applications. * * Some EE Container scan the common shared EAR lib path and reuse this information * for the webapps in the EAR. This is actually the only approach a container can * do to prevent mem leaks and side effects spreading to different webapps. * Of course this also means that the webapps get their own (different) * instances of an Extension. * * To acknowledge this solution we provide a mechanism to lookup 'parent Extensions' * which is very similar to handling parent ClassLoaders. * * Please note that you need to enable this handling if you are running DeltaSpike * in an EAR on a container which supports parent Extensions. * You can do that by settting {@code "deltaspike.parent.extension.enabled"} to "e;true"e; * * All your Extension has to do is to register itself in * {@link jakarta.enterprise.inject.spi.BeforeBeanDiscovery}. * Later at boot time the Extension can lookup it's parent Extension instance and * e.g. check which classes got scanned in the parent ClassLoader. * * The ExtensionInfo automatically gets removed if the webapp gets undeployed. * * @see org.apache.deltaspike.core.api.config.base.CoreBaseConfig.ParentExtensionCustomization */ public final class ParentExtensionStorage { private static Set extensionStorage = new HashSet(); private ParentExtensionStorage() { // utility class ct } /** * Add info about an Extension to our storage * This method is usually called during boostrap via {@code @Observes BeforeBeanDiscovery}. */ public static synchronized void addExtension(Extension extension) { if (usingParentExtension()) { removeAbandonedExtensions(); ClassLoader classLoader = ClassUtils.getClassLoader(null); extensionStorage.add(new ExtensionStorageInfo(classLoader, extension)); } } /** * When adding a new Extension we also clean up ExtensionInfos * from ClassLoaders which got unloaded. */ private static boolean usingParentExtension() { return CoreBaseConfig.ParentExtensionCustomization.PARENT_EXTENSION_ENABLED; } private static void removeAbandonedExtensions() { Iterator it = extensionStorage.iterator(); while (it.hasNext()) { ExtensionStorageInfo info = it.next(); if (info.isAbandoned()) { it.remove(); } } } /** * @return the Extension from the same type but registered in a hierarchic 'parent' BeanManager */ public static synchronized T getParentExtension(Extension extension) { if (usingParentExtension()) { ClassLoader parentClassLoader = ClassUtils.getClassLoader(null).getParent(); Iterator extIt = extensionStorage.iterator(); while (extIt.hasNext()) { ExtensionStorageInfo extensionInfo = extIt.next(); if (!extensionInfo.isAbandoned() && // weak reference case extension.getClass().equals(extensionInfo.getExtension().getClass()) && extensionInfo.getClassLoader().equals(parentClassLoader)) { return (T) extensionInfo.getExtension(); } } } return null; } /** * Information about an Extension instance and in which classloader it got used */ private static class ExtensionStorageInfo { // we use WeakReferences to allow perfect unloading of any webapp ClassLoader private final WeakReference classLoader; private final WeakReference extension; ExtensionStorageInfo(ClassLoader classLoader, Extension extension) { this.classLoader = new WeakReference(classLoader); this.extension = new WeakReference(extension); } boolean isAbandoned() { return classLoader.get() == null || extension.get() == null; } ClassLoader getClassLoader() { return classLoader.get(); } Extension getExtension() { return extension.get(); } } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/BaseImmutableBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import org.apache.deltaspike.core.api.literal.DefaultLiteral; import org.apache.deltaspike.core.util.ArraysUtils; import org.apache.deltaspike.core.util.metadata.InjectionPointWrapper; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; /** *

* A base class for implementing {@link Bean}. The attributes are immutable, and * collections are defensively copied on instantiation. It uses the defaults * from the specification for properties if not specified. *

*

*

* This class does not provide any bean lifecycle operations *

* * @see ImmutableBeanWrapper */ public abstract class BaseImmutableBean implements Bean { private static final Logger LOG = Logger.getLogger(BaseImmutableBean.class.getName()); private final Class beanClass; private final String name; private final Set qualifiers; private final Class scope; private final Set> stereotypes; private final Set types; private final boolean alternative; private final boolean nullable; private final Set injectionPoints; private final String toString; /** * Create a new, immutable bean. All arguments passed as collections are * defensively copied. * * @param beanClass The Bean class, may not be null * @param name The bean name * @param qualifiers The bean's qualifiers, if null, a singleton set of * {@link jakarta.enterprise.inject.Default} is used * @param scope The bean's scope, if null, the default scope of * {@link Dependent} is used * @param stereotypes The bean's stereotypes, if null, an empty set is used * @param types The bean's types, if null, the beanClass and {@link Object} * will be used * @param alternative True if the bean is an alternative * @param nullable True if the bean is nullable * @param injectionPoints the bean's injection points, if null an empty set is used * @param toString the string which should be returned by #{@link #toString()} * @throws IllegalArgumentException if the beanClass is null */ public BaseImmutableBean(Class beanClass, String name, Set qualifiers, Class scope, Set> stereotypes, Set types, boolean alternative, boolean nullable, Set injectionPoints, String toString) { if (beanClass == null) { throw new IllegalArgumentException("beanClass cannot be null"); } this.beanClass = beanClass; this.name = name; if (qualifiers == null) { this.qualifiers = Collections.singleton(new DefaultLiteral()); LOG.finest("No qualifers provided for bean class " + beanClass + ", using singleton set of @Default"); } else { this.qualifiers = new HashSet(qualifiers); } if (scope == null) { this.scope = Dependent.class; LOG.finest("No scope provided for bean class " + beanClass + ", using @Dependent"); } else { this.scope = scope; } if (stereotypes == null) { this.stereotypes = Collections.emptySet(); } else { this.stereotypes = new HashSet>(stereotypes); } if (types == null) { //noinspection unchecked this.types = ArraysUtils.asSet(Object.class, beanClass); LOG.finest("No types provided for bean class " + beanClass + ", using [java.lang.Object.class, " + beanClass.getName() + ".class]"); } else { this.types = new HashSet(types); } if (injectionPoints == null) { this.injectionPoints = Collections.emptySet(); } else { // Check for null Beans, wrap if there isn't one -- DELTASPIKE-400 final HashSet ips = new HashSet(injectionPoints.size()); for (InjectionPoint ip : injectionPoints) { if (ip.getBean() == null) { ips.add(new InjectionPointWrapper(ip, this)); } else { ips.add(ip); } } this.injectionPoints = ips; } this.alternative = alternative; this.nullable = nullable; if (toString != null) { this.toString = toString; } else { this.toString = "Custom Bean with bean class " + beanClass + " and qualifiers " + qualifiers; } } @Override public Class getBeanClass() { return beanClass; } @Override public Set getInjectionPoints() { return injectionPoints; } @Override public String getName() { return name; } @Override public Set getQualifiers() { return Collections.unmodifiableSet(qualifiers); } @Override public Class getScope() { return scope; } @Override public Set> getStereotypes() { return Collections.unmodifiableSet(stereotypes); } @Override public Set getTypes() { return Collections.unmodifiableSet(types); } @Override public boolean isAlternative() { return alternative; } @Override public boolean isNullable() { return nullable; } @Override public String toString() { return toString; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.api.literal.DefaultLiteral; import org.apache.deltaspike.core.util.Annotateds; import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle; import org.apache.deltaspike.core.util.metadata.builder.DelegatingContextualLifecycle; import org.apache.deltaspike.core.util.metadata.builder.DummyInjectionTarget; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.InjectionTarget; import jakarta.inject.Named; import java.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** *

* A builder class for creating immutable beans. The builder can create * {@link jakarta.enterprise.inject.spi.PassivationCapable} beans. *

*

*

* The builder can read from an {@link AnnotatedType} and have any attribute * modified. This class is not thread-safe, but the bean created by calling * {@link #create()} is. *

*

*

* It is advised that a new bean builder is instantiated for each bean created. *

*/ public class BeanBuilder { protected final BeanManager beanManager; protected Class beanClass; protected String name; protected Set qualifiers; protected Class scope = Dependent.class; protected Set> stereotypes; protected Set types; protected Set injectionPoints; protected boolean alternative; protected boolean nullable; protected ContextualLifecycle beanLifecycle; protected boolean passivationCapable; protected String id; protected String toString; /** * Instantiate a new bean builder. * * @param beanManager the bean manager to use for creating injection targets * and determining if annotations are qualifiers, scopes or * stereotypes. */ public BeanBuilder(BeanManager beanManager) { this.beanManager = beanManager; } /** *

* Read the {@link AnnotatedType}, creating a bean from the class and it's * annotations. *

*

*

* By default the bean lifecycle will wrap the result of calling * {@link BeanManager#createInjectionTarget(AnnotatedType)}. *

*

*

* {@link BeanBuilder} does not support reading members of the class * to create producers or observer methods. *

* * @param type the type to read */ public BeanBuilder readFromType(AnnotatedType type) { this.beanClass = type.getJavaClass(); if (beanLifecycle == null) { setDefaultBeanLifecycle(type); } this.qualifiers = new HashSet(); this.stereotypes = new HashSet>(); this.types = new HashSet(); for (Annotation annotation : type.getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { this.qualifiers.add(annotation); } else if (beanManager.isScope(annotation.annotationType())) { this.scope = annotation.annotationType(); } else if (beanManager.isStereotype(annotation.annotationType())) { this.stereotypes.add(annotation.annotationType()); } if (annotation instanceof Named) { this.name = ((Named) annotation).value(); if (name == null || name.length() == 0) { name = createDefaultBeanName(type); } } if (annotation instanceof Alternative) { this.alternative = true; } } if (type.isAnnotationPresent(Typed.class)) { Typed typed = type.getAnnotation(Typed.class); this.types.addAll(Arrays.asList(typed.value())); } else { for (Class c = type.getJavaClass(); c != Object.class && c != null; c = c.getSuperclass()) { this.types.add(c); } Collections.addAll(this.types, type.getJavaClass().getInterfaces()); this.types.add(Object.class); } if (qualifiers.isEmpty()) { qualifiers.add(new DefaultLiteral()); } qualifiers.add(new AnyLiteral()); this.id = ImmutableBeanWrapper.class.getName() + ":" + Annotateds.createTypeId(type); return this; } private String createDefaultBeanName(AnnotatedType type) { Class javaClass = type.getJavaClass(); return Introspector.decapitalize(javaClass.getSimpleName()); } /** * Set the ContextualLifecycle and the InjectionPoints for the AnnotatedType * @param type */ protected void setDefaultBeanLifecycle(AnnotatedType type) { InjectionTarget injectionTarget; if (!type.getJavaClass().isInterface()) { injectionTarget = beanManager.createInjectionTarget(type); } else { injectionTarget = new DummyInjectionTarget(); } this.beanLifecycle = new DelegatingContextualLifecycle(injectionTarget); this.injectionPoints = injectionTarget.getInjectionPoints(); } /** *

* Use the bean builder's current state to define the bean. *

* * @return the bean */ public Bean create() { if (!passivationCapable) { return new ImmutableBean(beanClass, name, qualifiers, scope, stereotypes, types, alternative, nullable, injectionPoints, toString, beanLifecycle); } else { return new ImmutablePassivationCapableBean(beanClass, name, qualifiers, scope, stereotypes, types, alternative, nullable, injectionPoints, toString, beanLifecycle, id); } } /** * Qualifiers currently defined for bean creation. * * @return the qualifiers current defined */ public Set getQualifiers() { return qualifiers; } /** * Define the qualifiers used for bean creation. * * @param qualifiers the qualifiers to use */ public BeanBuilder qualifiers(Set qualifiers) { this.qualifiers = qualifiers; return this; } /** * Define the qualifiers used for bean creation. * * @param qualifiers the qualifiers to use */ public BeanBuilder qualifiers(Annotation... qualifiers) { this.qualifiers = new HashSet(Arrays.asList(qualifiers)); return this; } /** * Add to the qualifiers used for bean creation. * * @param qualifier the additional qualifier to use */ public BeanBuilder addQualifier(Annotation qualifier) { this.qualifiers.add(qualifier); return this; } /** * Add to the qualifiers used for bean creation. * * @param qualifiers the additional qualifiers to use */ public BeanBuilder addQualifiers(Annotation... qualifiers) { this.qualifiers.addAll(new HashSet(Arrays.asList(qualifiers))); return this; } /** * Add to the qualifiers used for bean creation. * * @param qualifiers the additional qualifiers to use */ public BeanBuilder addQualifiers(Collection qualifiers) { this.qualifiers.addAll(qualifiers); return this; } /** * Scope currently defined for bean creation. * * @return the scope currently defined */ public Class getScope() { return scope; } /** * Define the scope used for bean creation. * * @param scope the scope to use */ public BeanBuilder scope(Class scope) { this.scope = scope; return this; } /** * Stereotypes currently defined for bean creation. * * @return the stereotypes currently defined */ public Set> getStereotypes() { return stereotypes; } /** * Define the stereotypes used for bean creation. * * @param stereotypes the stereotypes to use */ public BeanBuilder stereotypes(Set> stereotypes) { this.stereotypes = stereotypes; return this; } /** * Type closure currently defined for bean creation. * * @return the type closure currently defined */ public Set getTypes() { return types; } /** * Define the type closure used for bean creation. * * @param types the type closure to use */ public BeanBuilder types(Set types) { this.types = types; return this; } /** * Define the type closure used for bean creation. * * @param types the type closure to use */ public BeanBuilder types(Type... types) { this.types = new HashSet(Arrays.asList(types)); return this; } /** * Add to the type closure used for bean creation. * * @param type additional type to use */ public BeanBuilder addType(Type type) { this.types.add(type); return this; } /** * Add to the type closure used for bean creation. * * @param types the additional types to use */ public BeanBuilder addTypes(Type... types) { this.types.addAll(new HashSet(Arrays.asList(types))); return this; } /** * Add to the type closure used for bean creation. * * @param types the additional types to use */ public BeanBuilder addTypes(Collection types) { this.types.addAll(types); return this; } /** * Whether the created bean will be an alternative. * * @return true if the created bean will be an alternative, * otherwise false */ public boolean isAlternative() { return alternative; } /** * Define that the created bean will (or will not) be an alternative. * * @param alternative true if the created bean should be an * alternative, otherwise false */ public BeanBuilder alternative(boolean alternative) { this.alternative = alternative; return this; } /** * Whether the created bean will be nullable. * * @return true if the created bean will be nullable, otherwise * false */ public boolean isNullable() { return nullable; } /** * Define that the created bean will (or will not) be nullable. * * @param nullable true if the created bean should be nullable, * otherwise false */ public BeanBuilder nullable(boolean nullable) { this.nullable = nullable; return this; } /** * The {@link ContextualLifecycle} currently defined for bean creation. * * @return the bean lifecycle currently defined */ public ContextualLifecycle getBeanLifecycle() { return beanLifecycle; } /** * Define the {@link ContextualLifecycle} used for bean creation. * * @param beanLifecycle the {@link ContextualLifecycle} to use for bean * creation. */ public BeanBuilder beanLifecycle(ContextualLifecycle beanLifecycle) { this.beanLifecycle = beanLifecycle; return this; } /** * The bean class currently defined for bean creation. * * @return the bean class currently defined. */ public Class getBeanClass() { return beanClass; } /** * Define the bean class used for bean creation. * * @param beanClass the bean class to use */ public BeanBuilder beanClass(Class beanClass) { this.beanClass = beanClass; return this; } /** * The bean manager in use. This cannot be changed for this * {@link BeanBuilder}. * * @return the bean manager in use */ public BeanManager getBeanManager() { return beanManager; } /** * The name of the bean currently defined for bean creation. * * @return the name of the bean or null if the bean has no name */ public String getName() { return name; } /** * Define the name of the bean used for bean creation. * * @param name the name of the bean to use or null if the bean * should have no name */ public BeanBuilder name(String name) { this.name = name; return this; } /** * Whether the created bean will be passivation capable. * * @return true if the created bean will be passivation capable, * otherwise false */ public boolean isPassivationCapable() { return passivationCapable; } /** * Define that the created bean will (or will not) be passivation capable. * * @param passivationCapable true if the created bean should be * passivation capable, otherwise false */ public BeanBuilder passivationCapable(boolean passivationCapable) { this.passivationCapable = passivationCapable; return this; } /** * The id currently defined for bean creation. * * @return the id currently defined. */ public String getId() { return id; } /** * Define the id used for bean creation. * * @param id the id to use */ public BeanBuilder id(String id) { this.id = id; return this; } /** * The injection points currently defined for bean creation. * * @return the injection points currently defined. */ public Set getInjectionPoints() { return injectionPoints; } /** * Define the injection points used for bean creation. * * @param injectionPoints the injection points to use */ public BeanBuilder injectionPoints(Set injectionPoints) { this.injectionPoints = injectionPoints; return this; } /** * Define the string used when {@link #toString()} is called on the bean. * * @param toString the string to use */ public BeanBuilder toString(String toString) { this.toString = toString; return this; } /** * The string used when {@link #toString()} is called on the bean. * * @return the string currently defined */ public String getToString() { return toString; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/ImmutableBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; /** * */ public class ImmutableBean extends BaseImmutableBean { private final ContextualLifecycle lifecycle; /** * Create a new, immutable bean. All arguments passed as collections are * defensively copied. * * @param beanClass The Bean class, may not be null * @param name The bean name * @param qualifiers The bean's qualifiers, if null, a singleton set of * {@link jakarta.enterprise.inject.Default} is used * @param scope The bean's scope, if null, the default scope of * {@link jakarta.enterprise.context.Dependent} is used * @param stereotypes The bean's stereotypes, if null, an empty set is used * @param types The bean's types, if null, the beanClass and {@link Object} * will be used * @param alternative True if the bean is an alternative * @param nullable True if the bean is nullable * @param injectionPoints the bean's injection points, if null an empty set is used * @param toString the string which should be returned by #{@link #toString()} * @param contextualLifecycle Handler for {@link #create(jakarta.enterprise.context.spi.CreationalContext)} and * {@link #destroy(Object, jakarta.enterprise.context.spi.CreationalContext)} * @throws IllegalArgumentException if the beanClass is null */ // CHECKSTYLE:OFF public ImmutableBean(Class beanClass, String name, Set qualifiers, Class scope, Set> stereotypes, Set types, boolean alternative, boolean nullable, Set injectionPoints, String toString, ContextualLifecycle contextualLifecycle) { // CHECKSTYLE:ON super(beanClass, name, qualifiers, scope, stereotypes, types, alternative, nullable, injectionPoints, toString); this.lifecycle = contextualLifecycle; } @Override public T create(CreationalContext creationalContext) { return lifecycle.create(this, creationalContext); } @Override public void destroy(T instance, CreationalContext creationalContext) { this.lifecycle.destroy(this, instance, creationalContext); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/ImmutableBeanWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; /** *

* This bean-wrapper allows you to build a general purpose bean (likely a * producer method), and register it for a narrowed type (or qualifiers). * You can easily create instances of this class with the * {@link WrappingBeanBuilder}. *

*

*

For example, you could create a producer method which uses an a * String ID tolocated an object (the object can have any class):

*
 * @Produces
 * // Use some synthetic scope to prevent this from interfering with other
 * // resolutions
 * @MyProducer
 * Object produce(InjectionPoint ip)
 * {
 *     String id = ip.getAnnotated().getAnnotation(Id.class).value();
 *     // Lookup and return the object for the id
 * }
 * 
*

The wrapped bean must return an object which can be cast to the * type T, otherwise a {@link ClassCastException} will be thrown at * runtime when the bean is created. *

*

You can then register a narrowing bean for each type you need: *

*
 * event.addBean(new NarrowingBeanBuilder<T>(delegateBean).readFromType(type)
 *         .create());
 * 
*

{@link ImmutableBeanWrapper} will use the annotations on * definingType to discover the qualifiers, types, scope, * stereotypes of the bean, as well as determine it's name (if any) and whether * it is an alternative. *

*

The attributes are immutable, and collections are defensively copied on * instantiation. It uses the defaults from the specification for properties if * not specified. *

* * @see org.apache.deltaspike.core.util.bean.WrappingBeanBuilder */ public class ImmutableBeanWrapper extends BaseImmutableBean { private final Bean wrapped; /** * Instantiate a new {@link ImmutableBeanWrapper}. * * @param bean the bean to wrapped the lifecycle to * @param name the name of the bean * @param qualifiers the qualifiers of the bean * @param scope the scope of the bean * @param stereotypes the bean's stereotypes * @param types the types of the bean * @param alternative whether the bean is an alternative * @param nullable true if the bean is nullable * @param toString the string which should be returned by #{@link #toString()} */ public ImmutableBeanWrapper(Bean bean, String name, Set qualifiers, Class scope, Set> stereotypes, Set types, boolean alternative, boolean nullable, String toString) { super(bean.getBeanClass(), name, qualifiers, scope, stereotypes, types, alternative, nullable, bean.getInjectionPoints(), toString); wrapped = bean; } @Override public T create(CreationalContext creationalContext) { return wrapped.create(creationalContext); } @Override public void destroy(T instance, CreationalContext creationalContext) { wrapped.destroy(instance, creationalContext); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/ImmutablePassivationCapableBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import org.apache.deltaspike.core.util.metadata.builder.ContextualLifecycle; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.PassivationCapable; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; /** * */ public class ImmutablePassivationCapableBean extends ImmutableBean implements PassivationCapable { private final String id; /** * Create a new, immutable bean. All arguments passed as collections are * defensively copied. * * @param beanClass The Bean class, may not be null * @param name The bean name * @param qualifiers The bean's qualifiers, if null, a singleton set of * {@link jakarta.enterprise.inject.Default} is used * @param scope The bean's scope, if null, the default scope of * {@link jakarta.enterprise.context.Dependent} is used * @param stereotypes The bean's stereotypes, if null, an empty set is used * @param types The bean's types, if null, the beanClass and {@link Object} * will be used * @param alternative True if the bean is an alternative * @param nullable True if the bean is nullable * @param injectionPoints the bean's injection points, if null an empty set is used * @param toString the string which should be returned by #{@link #toString()} * @param lifecycle Handler for {@link #create(jakarta.enterprise.context.spi.CreationalContext)} and * {@link #destroy(Object, jakarta.enterprise.context.spi.CreationalContext)} * @param passivationId Passivation bean Id. * @throws IllegalArgumentException if the beanClass is null */ // CHECKSTYLE:OFF public ImmutablePassivationCapableBean(Class beanClass, String name, Set qualifiers, Class scope, Set> stereotypes, Set types, boolean alternative, boolean nullable, Set injectionPoints, String toString, ContextualLifecycle lifecycle, String passivationId) { // CHECKSTYLE:ON super(beanClass, name, qualifiers, scope, stereotypes, types, alternative, nullable, injectionPoints, toString, lifecycle); this.id = passivationId; } @Override public String getId() { return this.id; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/ImmutablePassivationCapableBeanWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.PassivationCapable; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Set; /** *

PassivationCapable version of an ImmutableBeanWrapper. * You can easily create instances of this class with the * {@link WrappingBeanBuilder}.

* * @see ImmutableBeanWrapper * @see WrappingBeanBuilder */ public class ImmutablePassivationCapableBeanWrapper extends ImmutableBeanWrapper implements PassivationCapable { private final String id; /** * Instantiate a new {@link ImmutableBeanWrapper} for a {@link PassivationCapable} Bean. * * @param bean the bean to wrapped the lifecycle to * @param name the name of the bean * @param qualifiers the qualifiers of the bean * @param scope the scope of the bean * @param stereotypes the bean's stereotypes * @param types the types of the bean * @param alternative whether the bean is an alternative * @param nullable true if the bean is nullable * @param toString the string which should be returned by #{@link #toString()} * @param id the passivationId which gets returned by {@link #getId()} */ public ImmutablePassivationCapableBeanWrapper(Bean bean, String name, Set qualifiers, Class scope, Set> stereotypes, Set types, boolean alternative, boolean nullable, String toString, String id) { super(bean, name, qualifiers, scope, stereotypes, types, alternative, nullable, toString); this.id = id; } @Override public String getId() { return id; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/bean/WrappingBeanBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.bean; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; /** *

A WrappingBeanBuilder helps creating Beans which internally * just wrap another existing Bean. The Types, Qualifiers * and other attributes of the resulting Bean can be modified.

*

*

The {@link Bean#create(jakarta.enterprise.context.spi.CreationalContext)} * and {@link Bean#destroy(Object, jakarta.enterprise.context.spi.CreationalContext)} * methods will get delegated to the underlying wrapped Bean.

* * @param the type of the Bean */ public class WrappingBeanBuilder extends BeanBuilder { private final Bean delegate; /** * Instantiate a new {@link WrappingBeanBuilder}. * * @param delegate the delegate bean * @param beanManager current bean-manager */ public WrappingBeanBuilder(Bean delegate, BeanManager beanManager) { super(beanManager); this.delegate = (Bean) delegate; } protected void setDefaultBeanLifecycle(AnnotatedType type) { // do nothing. We don't need that as we delegate this information } /** *

* Use the bean builder's current state to define the bean. *

* * @return the bean */ public Bean create() { if (isPassivationCapable()) { return new ImmutablePassivationCapableBeanWrapper(delegate, name, qualifiers, scope, stereotypes, types, alternative, nullable, toString, id); } else { return new ImmutableBeanWrapper(delegate, name, qualifiers, scope, stereotypes, types, alternative, nullable, toString); } } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/InjectionPointWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Member; import java.lang.reflect.Type; import java.util.Set; /** * Simple wrapper for injection points. Some metadata (as of 2014-12-15 just Bean) can be overridden, all else * delegates to the wrapped InjectionPoint. */ public class InjectionPointWrapper implements InjectionPoint { private final InjectionPoint wrapped; private final Bean newBean; public InjectionPointWrapper(InjectionPoint wrapped, Bean newBean) { this.wrapped = wrapped; this.newBean = newBean; } @Override public Type getType() { return wrapped.getType(); } @Override public Set getQualifiers() { return wrapped.getQualifiers(); } @Override public Bean getBean() { return newBean; } @Override public Member getMember() { return wrapped.getMember(); } @Override public Annotated getAnnotated() { return wrapped.getAnnotated(); } @Override public boolean isDelegate() { return wrapped.isDelegate(); } @Override public boolean isTransient() { return wrapped.isTransient(); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedCallableImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedCallable; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.reflect.Member; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; /** * Implementation of {@link AnnotatedCallable} */ abstract class AnnotatedCallableImpl extends AnnotatedMemberImpl implements AnnotatedCallable { private final List> parameters; protected AnnotatedCallableImpl(AnnotatedType declaringType, Y member, Class memberType, Class[] parameterTypes, Type[] genericTypes, AnnotationStore annotations, Map parameterAnnotations, Type genericType, Map parameterTypeOverrides) { super(declaringType, member, memberType, annotations, genericType, null); parameters = getAnnotatedParameters(this, parameterTypes, genericTypes, parameterAnnotations, parameterTypeOverrides); } /** * {@inheritDoc} */ @Override public List> getParameters() { return Collections.unmodifiableList(parameters); } public AnnotatedParameter getParameter(int index) { return parameters.get(index); } private static List> getAnnotatedParameters( AnnotatedCallableImpl callable, Class[] parameterTypes, Type[] genericTypes, Map parameterAnnotations, Map parameterTypeOverrides) { List> parameters = new ArrayList>(); int len = parameterTypes.length; for (int i = 0; i < len; ++i) { AnnotationBuilder builder = new AnnotationBuilder(); if (parameterAnnotations != null && parameterAnnotations.containsKey(i)) { builder.addAll(parameterAnnotations.get(i)); } Type over = null; if (parameterTypeOverrides != null) { over = parameterTypeOverrides.get(i); } AnnotatedParameterImpl p = new AnnotatedParameterImpl( callable, parameterTypes[i], i, builder.create(), genericTypes[i], over); parameters.add(p); } return parameters; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedConstructorImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedConstructor; import java.lang.reflect.Constructor; import java.lang.reflect.Type; import java.util.Map; /** * Implementation of {@link AnnotatedConstructor} to be used in * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder} * and other CDI life cycle events. */ class AnnotatedConstructorImpl extends AnnotatedCallableImpl> implements AnnotatedConstructor { /** * Constructor */ AnnotatedConstructorImpl(AnnotatedTypeImpl type, Constructor constructor, AnnotationStore annotations, Map parameterAnnotations, Map typeOverrides) { super(type, (Constructor) constructor, constructor.getDeclaringClass(), constructor.getParameterTypes(), getGenericArray(constructor), annotations, parameterAnnotations, null, typeOverrides); } private static Type[] getGenericArray(Constructor constructor) { Type[] genericTypes = constructor.getGenericParameterTypes(); // for inner classes genericTypes and parameterTypes can be different // length, this is a hack to fix this. // TODO: investigate this behavior further, on different JVM's and // compilers if (genericTypes.length < constructor.getParameterTypes().length) { genericTypes = new Type[constructor.getParameterTypes().length]; genericTypes[0] = constructor.getParameterTypes()[0]; for (int i = 0; i < constructor.getGenericParameterTypes().length; ++i) { genericTypes[i + 1] = constructor.getGenericParameterTypes()[i]; } } return genericTypes; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedFieldImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.reflect.Field; import java.lang.reflect.Type; /** * Implementation of {@link AnnotatedField} to be used in CDI life cycle events and * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}. */ class AnnotatedFieldImpl extends AnnotatedMemberImpl implements AnnotatedField { /** * Constructor. */ AnnotatedFieldImpl(AnnotatedType declaringType, Field field, AnnotationStore annotations, Type overriddenType) { super(declaringType, field, field.getType(), annotations, field.getGenericType(), overriddenType); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import org.apache.deltaspike.core.util.HierarchyDiscovery; import jakarta.enterprise.inject.spi.Annotated; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * The base class for all New Annotated types. */ abstract class AnnotatedImpl implements Annotated { private final Type type; private final Set typeClosure; private final AnnotationStore annotations; protected AnnotatedImpl(Class type, AnnotationStore annotations, Type genericType, Type overriddenType) { if (overriddenType == null) { if (genericType != null) { typeClosure = new HierarchyDiscovery(genericType).getTypeClosure(); this.type = genericType; } else { typeClosure = new HierarchyDiscovery(type).getTypeClosure(); this.type = type; } } else { this.type = overriddenType; typeClosure = Collections.singleton(overriddenType); } if (annotations == null) { this.annotations = new AnnotationStore(); } else { this.annotations = annotations; } } /** * {@inheritDoc} */ @Override public T getAnnotation(Class annotationType) { return annotations.getAnnotation(annotationType); } /** * {@inheritDoc} */ @Override public Set getAnnotations() { return annotations.getAnnotations(); } /** * {@inheritDoc} */ @Override public boolean isAnnotationPresent(Class annotationType) { return annotations.isAnnotationPresent(annotationType); } /** * {@inheritDoc} */ @Override public Set getTypeClosure() { return new HashSet(typeClosure); } /** * {@inheritDoc} */ @Override public Type getBaseType() { return type; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMemberImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedMember; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.reflect.Member; import java.lang.reflect.Modifier; import java.lang.reflect.Type; /** * An implementation of {@link AnnotatedMember} to be used in CDI life cycle events and * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}. */ abstract class AnnotatedMemberImpl extends AnnotatedImpl implements AnnotatedMember { private final AnnotatedType declaringType; private final M javaMember; protected AnnotatedMemberImpl(AnnotatedType declaringType, M member, Class memberType, AnnotationStore annotations, Type genericType, Type overriddenType) { super(memberType, annotations, genericType, overriddenType); this.declaringType = declaringType; javaMember = member; } /** * {@inheritDoc} */ @Override public AnnotatedType getDeclaringType() { return declaringType; } /** * {@inheritDoc} */ @Override public M getJavaMember() { return javaMember; } /** * {@inheritDoc} */ @Override public boolean isStatic() { return Modifier.isStatic(javaMember.getModifiers()); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedMethodImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Map; /** * Implementation of {@link AnnotatedMethod} to be used in CDI life cycle events and * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}. */ class AnnotatedMethodImpl extends AnnotatedCallableImpl implements AnnotatedMethod { /** * Constructor. */ AnnotatedMethodImpl(AnnotatedType type, Method method, AnnotationStore annotations, Map parameterAnnotations, Map parameterTypeOverrides) { super(type, method, method.getReturnType(), method.getParameterTypes(), method.getGenericParameterTypes(), annotations, parameterAnnotations, method.getGenericReturnType(), parameterTypeOverrides); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedParameterImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedCallable; import jakarta.enterprise.inject.spi.AnnotatedParameter; import java.lang.reflect.Type; /** * Implementation of {@link AnnotatedParameter}. */ class AnnotatedParameterImpl extends AnnotatedImpl implements AnnotatedParameter { private final int position; private final AnnotatedCallable declaringCallable; /** * Constructor */ AnnotatedParameterImpl(AnnotatedCallable declaringCallable, Class type, int position, AnnotationStore annotations, Type genericType, Type typeOverride) { super(type, annotations, genericType, typeOverride); this.declaringCallable = declaringCallable; this.position = position; } /** * {@inheritDoc} */ @Override public AnnotatedCallable getDeclaringCallable() { return declaringCallable; } /** * {@inheritDoc} */ @Override public int getPosition() { return position; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import org.apache.deltaspike.core.util.ReflectionUtils; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedConstructor; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.security.AccessController; import java.util.HashMap; import java.util.Map; /** * Builder to aid in creation of a new {@link AnnotatedType} for use in CDI life cycle events. * Using the builder is typically done by reading the annotations from a {@link Class} or an * {@link AnnotatedType}. Once the starting class or type has been added all of annotations * can be modified: constructor, parameter, class, method and fields. *

* The AnnotatedTypeBuilder is not thread safe and shall not be used concurrently! */ public class AnnotatedTypeBuilder { private Class javaClass; private final AnnotationBuilder typeAnnotations; private final Map, AnnotationBuilder> constructors; private final Map, Map> constructorParameters; private final Map, Map> constructorParameterTypes; private final Map fields; private final Map fieldTypes; private final Map methods; private final Map> methodParameters; private final Map> methodParameterTypes; /** * Create a new builder. A new builder has no annotations and no members. * * @see #readFromType(AnnotatedType) * @see #readFromType(Class) * @see #readFromType(AnnotatedType, boolean) * @see #readFromType(Class, boolean) */ public AnnotatedTypeBuilder() { typeAnnotations = new AnnotationBuilder(); constructors = new HashMap, AnnotationBuilder>(); constructorParameters = new HashMap, Map>(); constructorParameterTypes = new HashMap, Map>(); fields = new HashMap(); fieldTypes = new HashMap(); methods = new HashMap(); methodParameters = new HashMap>(); methodParameterTypes = new HashMap>(); } /** * Add an annotation to the type declaration. * * @param annotation the annotation instance to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToClass(Annotation annotation) { typeAnnotations.add(annotation); return this; } /** * Remove an annotation from the type * * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType */ public AnnotatedTypeBuilder removeFromClass(Class annotationType) { typeAnnotations.remove(annotationType); return this; } /** * Add an annotation to the specified field. If the field is not already * present, it will be added. * * @param field the field to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToField(Field field, Annotation annotation) { if (fields.get(field) == null) { fields.put(field, new AnnotationBuilder()); } fields.get(field).add(annotation); return this; } /** * Add an annotation to the specified field. If the field is not already * present, it will be added. * * @param field the field to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToField(AnnotatedField field, Annotation annotation) { return addToField(field.getJavaMember(), annotation); } /** * Remove an annotation from the specified field. * * @param field the field to remove the annotation from * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null or if the * field is not currently declared on the type */ public AnnotatedTypeBuilder removeFromField(Field field, Class annotationType) { if (fields.get(field) == null) { throw new IllegalArgumentException("field " + field + " not present on class " + getJavaClass()); } else { fields.get(field).remove(annotationType); } return this; } /** * Remove an annotation from the specified field. * * @param field the field to remove the annotation from * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null or if the * field is not currently declared on the type */ public AnnotatedTypeBuilder removeFromField(AnnotatedField field, Class annotationType) { return removeFromField(field.getJavaMember(), annotationType); } /** * Add an annotation to the specified method. If the method is not already * present, it will be added. * * @param method the method to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToMethod(Method method, Annotation annotation) { if (methods.get(method) == null) { methods.put(method, new AnnotationBuilder()); } methods.get(method).add(annotation); return this; } /** * Add an annotation to the specified method. If the method is not already * present, it will be added. * * @param method the method to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToMethod(AnnotatedMethod method, Annotation annotation) { return addToMethod(method.getJavaMember(), annotation); } /** * Remove an annotation from the specified method. * * @param method the method to remove the annotation from * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null or if the * method is not currently declared on the type */ public AnnotatedTypeBuilder removeFromMethod(Method method, Class annotationType) { if (methods.get(method) == null) { throw new IllegalArgumentException("Method " + method + " not present on class" + getJavaClass()); } else { methods.get(method).remove(annotationType); } return this; } /** * Remove an annotation from the specified method. * * @param method the method to remove the annotation from * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null or if the * method is not currently declared on the type */ public AnnotatedTypeBuilder removeFromMethod(AnnotatedMethod method, Class annotationType) { return removeFromMethod(method.getJavaMember(), annotationType); } /** * Add an annotation to the specified method parameter. If the method is not * already present, it will be added. If the method parameter is not already * present, it will be added. * * @param method the method to add the annotation to * @param position the position of the parameter to add * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToMethodParameter(Method method, int position, Annotation annotation) { if (!methods.containsKey(method)) { methods.put(method, new AnnotationBuilder()); } if (methodParameters.get(method) == null) { methodParameters.put(method, new HashMap()); } if (methodParameters.get(method).get(position) == null) { methodParameters.get(method).put(position, new AnnotationBuilder()); } methodParameters.get(method).get(position).add(annotation); return this; } /** * Remove an annotation from the specified method parameter. * * @param method the method to remove the annotation from * @param position the position of the parameter to remove * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null, if the * method is not currently declared on the type or if the * parameter is not declared on the method */ public AnnotatedTypeBuilder removeFromMethodParameter(Method method, int position, Class annotationType) { if (methods.get(method) == null) { throw new IllegalArgumentException("Method " + method + " not present on class " + getJavaClass()); } else { if (methodParameters.get(method).get(position) == null) { throw new IllegalArgumentException( String.format("parameter %s not present on method %s declared on class %s", method, position, getJavaClass())); } else { methodParameters.get(method).get(position).remove(annotationType); } } return this; } /** * Add an annotation to the specified constructor. If the constructor is not * already present, it will be added. * * @param constructor the constructor to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToConstructor(Constructor constructor, Annotation annotation) { if (constructors.get(constructor) == null) { constructors.put(constructor, new AnnotationBuilder()); } constructors.get(constructor).add(annotation); return this; } /** * Add an annotation to the specified constructor. If the constructor is not * already present, it will be added. * * @param constructor the constructor to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToConstructor(AnnotatedConstructor constructor, Annotation annotation) { return addToConstructor(constructor.getJavaMember(), annotation); } /** * Remove an annotation from the specified constructor. * * @param constructor the constructor to add the annotation to * @param annotationType the annotation to add * @throws IllegalArgumentException if the annotationType is null or if the * constructor is not currently declared on the type */ public AnnotatedTypeBuilder removeFromConstructor(Constructor constructor, Class annotationType) { if (constructors.get(constructor) != null) { constructors.get(constructor).remove(annotationType); } return this; } /** * Remove an annotation from the specified constructor. * * @param constructor the constructor to add the annotation to * @param annotationType the annotation to add * @throws IllegalArgumentException if the annotationType is null, if the * annotation does not exist on the type or if the constructor is * not currently declared on the type */ public AnnotatedTypeBuilder removeFromConstructor(AnnotatedConstructor constructor, Class annotationType) { return removeFromConstructor(constructor.getJavaMember(), annotationType); } /** * Add an annotation to the specified constructor parameter. If the * constructor is not already present, it will be added. If the constructor * parameter is not already present, it will be added. * * @param constructor the constructor to add the annotation to * @param position the position of the parameter to add * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null */ public AnnotatedTypeBuilder addToConstructorParameter(Constructor constructor, int position, Annotation annotation) { if (!constructors.containsKey(constructor)) { constructors.put(constructor, new AnnotationBuilder()); } if (constructorParameters.get(constructor) == null) { constructorParameters.put(constructor, new HashMap()); } if (constructorParameters.get(constructor).get(position) == null) { constructorParameters.get(constructor).put(position, new AnnotationBuilder()); } constructorParameters.get(constructor).get(position).add(annotation); return this; } /** * Remove an annotation from the specified constructor parameter. * * @param constructor the constructor to remove the annotation from * @param position the position of the parameter to remove * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null, if the * constructor is not currently declared on the type or if the * parameter is not declared on the constructor */ public AnnotatedTypeBuilder removeFromConstructorParameter(Constructor constructor, int position, Class annotationType) { if (constructorParameters.get(constructor) != null && constructorParameters.get(constructor).get(position) != null) { constructorParameters.get(constructor).get(position).remove(annotationType); } return this; } /** * Remove an annotation from the specified parameter. * * @param parameter the parameter to remove the annotation from * @param annotationType the annotation type to remove * @throws IllegalArgumentException if the annotationType is null, if the * callable which declares the parameter is not currently declared * on the type or if the parameter is not declared on either a * constructor or a method */ public AnnotatedTypeBuilder removeFromParameter(AnnotatedParameter parameter, Class annotationType) { if (parameter.getDeclaringCallable().getJavaMember() instanceof Method) { Method method = (Method) parameter.getDeclaringCallable().getJavaMember(); return removeFromMethodParameter(method, parameter.getPosition(), annotationType); } if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor) { @SuppressWarnings("unchecked") Constructor constructor = (Constructor) parameter.getDeclaringCallable().getJavaMember(); return removeFromConstructorParameter(constructor, parameter.getPosition(), annotationType); } else { throw new IllegalArgumentException("Cannot remove from parameter " + parameter + " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember()); } } /** * Add an annotation to the specified parameter. If the callable which * declares the parameter is not already present, it will be added. If the * parameter is not already present on the callable, it will be added. * * @param parameter the parameter to add the annotation to * @param annotation the annotation to add * @throws IllegalArgumentException if the annotation is null or if the * parameter is not declared on either a constructor or a method */ public AnnotatedTypeBuilder addToParameter(AnnotatedParameter parameter, Annotation annotation) { if (parameter.getDeclaringCallable().getJavaMember() instanceof Method) { Method method = (Method) parameter.getDeclaringCallable().getJavaMember(); return addToMethodParameter(method, parameter.getPosition(), annotation); } if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor) { @SuppressWarnings("unchecked") Constructor constructor = (Constructor) parameter.getDeclaringCallable().getJavaMember(); return addToConstructorParameter(constructor, parameter.getPosition(), annotation); } else { throw new IllegalArgumentException("Cannot remove from parameter " + parameter + " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember()); } } /** * Remove annotations from the type, and all of it's members. If an * annotation of the specified type appears on the type declaration, or any * of it's members it will be removed. * * @param annotationType the type of annotation to remove * @throws IllegalArgumentException if the annotationType is null */ public AnnotatedTypeBuilder removeFromAll(Class annotationType) { if (annotationType == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "annotationType")); } removeFromClass(annotationType); for (Map.Entry field : fields.entrySet()) { field.getValue().remove(annotationType); } for (Map.Entry method : methods.entrySet()) { method.getValue().remove(annotationType); if (methodParameters.get(method.getKey()) != null) { for (Map.Entry parameter : methodParameters.get(method.getKey()).entrySet()) { parameter.getValue().remove(annotationType); } } } for (Map.Entry, AnnotationBuilder> constructor : constructors.entrySet()) { constructor.getValue().remove(annotationType); if (constructorParameters.get(constructor.getKey()) != null) { for (Map.Entry parameter : constructorParameters.get(constructor.getKey()).entrySet()) { parameter.getValue().remove(annotationType); } } } return this; } /** * Reads in from an existing AnnotatedType. Any elements not present are * added. The javaClass will be read in. If the annotation already exists on * that element in the builder the read annotation will be used. * * @param type the type to read from * @throws IllegalArgumentException if type is null */ public AnnotatedTypeBuilder readFromType(AnnotatedType type) { return readFromType(type, true); } /** * Reads in from an existing AnnotatedType. Any elements not present are * added. The javaClass will be read in if overwrite is true. If the * annotation already exists on that element in the builder, overwrite * determines whether the original or read annotation will be used. * * @param type the type to read from * @param overwrite if true, the read annotation will replace any existing * annotation * @throws IllegalArgumentException if type is null */ public AnnotatedTypeBuilder readFromType(AnnotatedType type, boolean overwrite) { if (type == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "type")); } if (javaClass == null || overwrite) { javaClass = type.getJavaClass(); } mergeAnnotationsOnElement(type, overwrite, typeAnnotations); for (AnnotatedField field : type.getFields()) { if (fields.get(field.getJavaMember()) == null) { fields.put(field.getJavaMember(), new AnnotationBuilder()); } mergeAnnotationsOnElement(field, overwrite, fields.get(field.getJavaMember())); } for (AnnotatedMethod method : type.getMethods()) { if (methods.get(method.getJavaMember()) == null) { methods.put(method.getJavaMember(), new AnnotationBuilder()); } mergeAnnotationsOnElement(method, overwrite, methods.get(method.getJavaMember())); for (AnnotatedParameter p : method.getParameters()) { if (methodParameters.get(method.getJavaMember()) == null) { methodParameters.put(method.getJavaMember(), new HashMap()); } if (methodParameters.get(method.getJavaMember()).get(p.getPosition()) == null) { methodParameters.get(method.getJavaMember()).put(p.getPosition(), new AnnotationBuilder()); } mergeAnnotationsOnElement( p, overwrite, methodParameters.get(method.getJavaMember()).get(p.getPosition())); } } for (AnnotatedConstructor constructor : type.getConstructors()) { if (constructors.get(constructor.getJavaMember()) == null) { constructors.put(constructor.getJavaMember(), new AnnotationBuilder()); } mergeAnnotationsOnElement(constructor, overwrite, constructors.get(constructor.getJavaMember())); for (AnnotatedParameter p : constructor.getParameters()) { if (constructorParameters.get( constructor.getJavaMember()) == null) { constructorParameters.put( constructor.getJavaMember(), new HashMap()); } if (constructorParameters.get( constructor.getJavaMember()).get(p.getPosition()) == null) { constructorParameters.get( constructor.getJavaMember()).put(p.getPosition(), new AnnotationBuilder()); } mergeAnnotationsOnElement( p, overwrite, constructorParameters.get(constructor.getJavaMember()).get(p.getPosition())); } } return this; } /** * Reads the annotations from an existing java type. Annotations already * present will be overwritten * * @param type the type to read from * @throws IllegalArgumentException if type is null */ public AnnotatedTypeBuilder readFromType(Class type) { return readFromType(type, true); } /** * Reads the annotations from an existing java type. If overwrite is true * then existing annotations will be overwritten * * @param type the type to read from * @param overwrite if true, the read annotation will replace any existing * annotation */ public AnnotatedTypeBuilder readFromType(Class type, boolean overwrite) { if (type == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "type")); } if (javaClass == null || overwrite) { javaClass = type; } for (Annotation annotation : type.getAnnotations()) { if (overwrite || !typeAnnotations.isAnnotationPresent(annotation.annotationType())) { typeAnnotations.add(annotation); } } for (Field field : ReflectionUtils.getAllDeclaredFields(type)) { AnnotationBuilder annotationBuilder = fields.get(field); if (annotationBuilder == null) { annotationBuilder = new AnnotationBuilder(); fields.put(field, annotationBuilder); } if (System.getSecurityManager() != null) { AccessController.doPrivileged(new SetAccessiblePrivilegedAction(field)); } else { field.setAccessible(true); } for (Annotation annotation : field.getAnnotations()) { if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType())) { annotationBuilder.add(annotation); } } } for (Method method : ReflectionUtils.getAllDeclaredMethods(type)) { AnnotationBuilder annotationBuilder = methods.get(method); if (annotationBuilder == null) { annotationBuilder = new AnnotationBuilder(); methods.put(method, annotationBuilder); } if (System.getSecurityManager() != null) { AccessController.doPrivileged(new SetAccessiblePrivilegedAction(method)); } else { method.setAccessible(true); } for (Annotation annotation : method.getAnnotations()) { if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType())) { annotationBuilder.add(annotation); } } Map parameters = methodParameters.get(method); if (parameters == null) { parameters = new HashMap(); methodParameters.put(method, parameters); } for (int i = 0; i < method.getParameterTypes().length; ++i) { AnnotationBuilder parameterAnnotationBuilder = parameters.get(i); if (parameterAnnotationBuilder == null) { parameterAnnotationBuilder = new AnnotationBuilder(); parameters.put(i, parameterAnnotationBuilder); } for (Annotation annotation : method.getParameterAnnotations()[i]) { if (overwrite || !parameterAnnotationBuilder.isAnnotationPresent(annotation.annotationType())) { parameterAnnotationBuilder.add(annotation); } } } } for (Constructor constructor : type.getDeclaredConstructors()) { AnnotationBuilder annotationBuilder = constructors.get(constructor); if (annotationBuilder == null) { annotationBuilder = new AnnotationBuilder(); constructors.put(constructor, annotationBuilder); } constructor.setAccessible(true); for (Annotation annotation : constructor.getAnnotations()) { if (overwrite || !annotationBuilder.isAnnotationPresent(annotation.annotationType())) { annotationBuilder.add(annotation); } } Map mparams = constructorParameters.get(constructor); if (mparams == null) { mparams = new HashMap(); constructorParameters.put(constructor, mparams); } for (int i = 0; i < constructor.getParameterTypes().length; ++i) { AnnotationBuilder parameterAnnotationBuilder = mparams.get(i); if (parameterAnnotationBuilder == null) { parameterAnnotationBuilder = new AnnotationBuilder(); mparams.put(i, parameterAnnotationBuilder); } for (Annotation annotation : constructor.getParameterAnnotations()[i]) { if (overwrite || !parameterAnnotationBuilder.isAnnotationPresent(annotation.annotationType())) { annotationBuilder.add(annotation); } } } } return this; } protected void mergeAnnotationsOnElement(Annotated annotated, boolean overwriteExisting, AnnotationBuilder typeAnnotations) { for (Annotation annotation : annotated.getAnnotations()) { if (typeAnnotations.getAnnotation(annotation.annotationType()) != null) { if (overwriteExisting) { typeAnnotations.remove(annotation.annotationType()); typeAnnotations.add(annotation); } } else { typeAnnotations.add(annotation); } } } /** * Create an {@link AnnotatedType}. Any public members present on the * underlying class and not overridden by the builder will be automatically * added. */ public AnnotatedType create() { Map, Map> constructorParameterAnnotations = new HashMap, Map>(); Map, AnnotationStore> constructorAnnotations = new HashMap, AnnotationStore>(); Map> methodParameterAnnotations = new HashMap>(); Map methodAnnotations = new HashMap(); Map fieldAnnotations = new HashMap(); for (Map.Entry field : fields.entrySet()) { fieldAnnotations.put(field.getKey(), field.getValue().create()); } for (Map.Entry method : methods.entrySet()) { methodAnnotations.put(method.getKey(), method.getValue().create()); } for (Map.Entry> parameters : methodParameters.entrySet()) { Map parameterAnnotations = new HashMap(); methodParameterAnnotations.put(parameters.getKey(), parameterAnnotations); for (Map.Entry parameter : parameters.getValue().entrySet()) { parameterAnnotations.put(parameter.getKey(), parameter.getValue().create()); } } for (Map.Entry, AnnotationBuilder> constructor : constructors.entrySet()) { constructorAnnotations.put(constructor.getKey(), constructor.getValue().create()); } for (Map.Entry, Map> parameters : constructorParameters.entrySet()) { Map parameterAnnotations = new HashMap(); constructorParameterAnnotations.put(parameters.getKey(), parameterAnnotations); for (Map.Entry parameter : parameters.getValue().entrySet()) { parameterAnnotations.put(parameter.getKey(), parameter.getValue().create()); } } return new AnnotatedTypeImpl(javaClass, typeAnnotations.create(), fieldAnnotations, methodAnnotations, methodParameterAnnotations, constructorAnnotations, constructorParameterAnnotations, fieldTypes, methodParameterTypes, constructorParameterTypes); } /** * Override the declared type of a field * * @param field the field to override the type on * @param type the new type of the field * @throws IllegalArgumentException if field or type is null */ public void overrideFieldType(Field field, Type type) { if (field == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "field")); } if (type == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "type")); } fieldTypes.put(field, type); } /** * Override the declared type of a field * * @param field the field to override the type on * @param type the new type of the field * @throws IllegalArgumentException if field or type is null */ public void overrideFieldType(AnnotatedField field, Type type) { overrideFieldType(field.getJavaMember(), type); } /** * Override the declared type of a method parameter * * @param method the method to override the parameter type on * @param position the position of the parameter to override the type on * @param type the new type of the parameter * @throws IllegalArgumentException if parameter or type is null */ public AnnotatedTypeBuilder overrideMethodParameterType(Method method, int position, Type type) { if (method == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "method")); } if (type == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "type")); } if (methodParameterTypes.get(method) == null) { methodParameterTypes.put(method, new HashMap()); } methodParameterTypes.get(method).put(position, type); return this; } /** * Override the declared type of a constructor parameter * * @param constructor the constructor to override the parameter type on * @param position the position of the parameter to override the type on * @param type the new type of the parameter * @throws IllegalArgumentException if parameter or type is null */ public AnnotatedTypeBuilder overrideConstructorParameterType(Constructor constructor, int position, Type type) { if (constructor == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "constructor")); } if (type == null) { throw new IllegalArgumentException(String.format("%s parameter must not be null", "type")); } if (constructorParameterTypes.get(constructor) == null) { constructorParameterTypes.put(constructor, new HashMap()); } constructorParameterTypes.get(constructor).put(position, type); return this; } /** * Override the declared type of a parameter. * * @param parameter the parameter to override the type on * @param type the new type of the parameter * @throws IllegalArgumentException if parameter or type is null */ public AnnotatedTypeBuilder overrideParameterType(AnnotatedParameter parameter, Type type) { if (parameter.getDeclaringCallable().getJavaMember() instanceof Method) { Method method = (Method) parameter.getDeclaringCallable().getJavaMember(); return overrideMethodParameterType(method, parameter.getPosition(), type); } if (parameter.getDeclaringCallable().getJavaMember() instanceof Constructor) { @SuppressWarnings("unchecked") Constructor constructor = (Constructor) parameter.getDeclaringCallable().getJavaMember(); return overrideConstructorParameterType(constructor, parameter.getPosition(), type); } else { throw new IllegalArgumentException("Cannot remove from parameter " + parameter + " - cannot operate on member " + parameter.getDeclaringCallable().getJavaMember()); } } /** * getter for the class */ public Class getJavaClass() { return javaClass; } /** * setter for the class */ public AnnotatedTypeBuilder setJavaClass(Class javaClass) { this.javaClass = javaClass; return this; } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotatedTypeImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.inject.spi.AnnotatedConstructor; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * An implementation of {@link AnnotatedType} to be used in CDI life cycle events and * {@link org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder}. */ class AnnotatedTypeImpl extends AnnotatedImpl implements AnnotatedType { private final Set> constructors; private final Set> fields; private final Set> methods; private final Class javaClass; /** * We make sure that there is a NewAnnotatedMember for every public * method/field/constructor *

* If annotation have been added to other methods as well we add them to */ AnnotatedTypeImpl(Class clazz, AnnotationStore typeAnnotations, Map fieldAnnotations, Map methodAnnotations, Map> methodParameterAnnotations, Map, AnnotationStore> constructorAnnotations, Map, Map> constructorParameterAnnotations, Map fieldTypes, Map> methodParameterTypes, Map, Map> constructorParameterTypes) { super(clazz, typeAnnotations, null, null); javaClass = clazz; constructors = new HashSet>(); Set> cset = new HashSet>(); Set mset = new HashSet(); Set fset = new HashSet(); for (Constructor c : clazz.getConstructors()) { AnnotatedConstructor nc = new AnnotatedConstructorImpl( this, c, constructorAnnotations.get(c), constructorParameterAnnotations.get(c), constructorParameterTypes.get(c)); constructors.add(nc); cset.add(c); } for (Map.Entry, AnnotationStore> c : constructorAnnotations.entrySet()) { if (!cset.contains(c.getKey())) { AnnotatedConstructor nc = new AnnotatedConstructorImpl( this, c.getKey(), c.getValue(), constructorParameterAnnotations.get(c.getKey()), constructorParameterTypes.get(c.getKey())); constructors.add(nc); } } methods = new HashSet>(); for (Method m : clazz.getMethods()) { if (!m.getDeclaringClass().equals(Object.class) && !m.getDeclaringClass().equals(Annotation.class)) { AnnotatedMethodImpl met = new AnnotatedMethodImpl(this, m, methodAnnotations.get(m), methodParameterAnnotations.get(m), methodParameterTypes.get(m)); methods.add(met); mset.add(m); } } for (Map.Entry c : methodAnnotations.entrySet()) { if (!c.getKey().getDeclaringClass().equals(Object.class) && !mset.contains(c.getKey())) { AnnotatedMethodImpl nc = new AnnotatedMethodImpl( this, c.getKey(), c.getValue(), methodParameterAnnotations.get(c.getKey()), methodParameterTypes.get(c.getKey())); methods.add(nc); } } fields = new HashSet>(); for (Field f : clazz.getFields()) { AnnotatedField b = new AnnotatedFieldImpl(this, f, fieldAnnotations.get(f), fieldTypes.get(f)); fields.add(b); fset.add(f); } for (Map.Entry e : fieldAnnotations.entrySet()) { if (!fset.contains(e.getKey())) { fields.add(new AnnotatedFieldImpl(this, e.getKey(), e.getValue(), fieldTypes.get(e.getKey()))); } } } /** * {@inheritDoc} */ @Override public Set> getConstructors() { return Collections.unmodifiableSet(constructors); } /** * {@inheritDoc} */ @Override public Set> getFields() { return Collections.unmodifiableSet(fields); } /** * {@inheritDoc} */ @Override public Class getJavaClass() { return javaClass; } /** * {@inheritDoc} */ @Override public Set> getMethods() { return Collections.unmodifiableSet(methods); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotationBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * A store of annotations to be used {@link AnnotatedTypeBuilder} and other places * where a collection of annotations needs manipulation. */ // this class is intentionally made package scope class AnnotationBuilder { private final Map, Annotation> annotationMap; private final Set annotationSet; /** * Default constructor. */ AnnotationBuilder() { annotationMap = new HashMap, Annotation>(); annotationSet = new HashSet(); } /** * Adds the annotation to the collections. * * @param annotation annotation to be added * @return this */ public AnnotationBuilder add(Annotation annotation) { if (annotation == null) { throw new IllegalArgumentException("annotation parameter must not be null"); } annotationSet.add(annotation); annotationMap.put(annotation.annotationType(), annotation); return this; } /** * Removes the given annotation from the collections. * * @param annotationType to be removed * @return this */ public AnnotationBuilder remove(Class annotationType) { if (annotationType == null) { throw new IllegalArgumentException("annotationType parameter must not be null"); } Iterator it = annotationSet.iterator(); while (it.hasNext()) { Annotation an = it.next(); if (annotationType.isAssignableFrom(an.annotationType())) { it.remove(); } } annotationMap.remove(annotationType); return this; } /** * Creates an {@link AnnotationStore} using the annotations from this instance. * * @return new AnnotationStore */ public AnnotationStore create() { return new AnnotationStore(annotationMap, annotationSet); } /** * Adds all annotations from the given collection * * @param annotations collection of annotations to be added * @return this */ public AnnotationBuilder addAll(Collection annotations) { for (Annotation annotation : annotations) { add(annotation); } return this; } /** * Adds all annotations from an {@link AnnotationStore}. * * @param annotations annotations to be added * @return this */ public AnnotationBuilder addAll(AnnotationStore annotations) { for (Annotation annotation : annotations.getAnnotations()) { add(annotation); } return this; } /** * Adds all annotations from the given {@link AnnotatedElement}. * * @param element element containing annotations to be added * @return this */ public AnnotationBuilder addAll(AnnotatedElement element) { for (Annotation a : element.getAnnotations()) { add(a); } return this; } /** * Getter. */ public T getAnnotation(Class anType) { return (T) annotationMap.get(anType); } /** * Simple check for an annotation. */ public boolean isAnnotationPresent(Class annotationType) { return annotationMap.containsKey(annotationType); } /** * {@inheritDoc} */ @Override public String toString() { return annotationSet.toString(); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/AnnotationStore.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import java.lang.annotation.Annotation; import java.util.Map; import java.util.Set; import static java.util.Collections.emptyMap; import static java.util.Collections.emptySet; import static java.util.Collections.unmodifiableSet; /** * A helper class used to hold annotations on a type or member. */ class AnnotationStore { private final Map, Annotation> annotationMap; private final Set annotationSet; AnnotationStore(Map, Annotation> annotationMap, Set annotationSet) { this.annotationMap = annotationMap; this.annotationSet = unmodifiableSet(annotationSet); } AnnotationStore() { annotationMap = emptyMap(); annotationSet = emptySet(); } T getAnnotation(Class annotationType) { return annotationType.cast(annotationMap.get(annotationType)); } Set getAnnotations() { return annotationSet; } boolean isAnnotationPresent(Class annotationType) { return annotationMap.containsKey(annotationType); } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/ContextualLifecycle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; /** * Callbacks used by {@link org.apache.deltaspike.core.util.bean.BeanBuilder} * and {@link org.apache.deltaspike.core.util.bean.ImmutableBeanWrapper} to allow control * of the creation and destruction of a custom bean. * * @param the class of the bean instance */ public interface ContextualLifecycle { /** * Callback invoked by a Solder created bean when * {@link Bean#create(CreationalContext)} is called. * * @param bean the bean initiating the callback * @param creationalContext the context in which this instance was created */ T create(Bean bean, CreationalContext creationalContext); /** * Callback invoked by a Solder created bean when * {@link Bean#destroy(Object, CreationalContext)} is called. * * @param bean the bean initiating the callback * @param instance the contextual instance to destroy * @param creationalContext the context in which this instance was created */ void destroy(Bean bean, T instance, CreationalContext creationalContext); } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/DelegatingContextualLifecycle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.InjectionTarget; /** * An implementation of {@link ContextualLifecycle} that is backed by an * {@link InjectionTarget}. * * @param */ public class DelegatingContextualLifecycle implements ContextualLifecycle { private final InjectionTarget injectionTarget; /** * Instantiate a new {@link ContextualLifecycle} backed by an * {@link InjectionTarget}. * * @param injectionTarget the {@link InjectionTarget} used to create and * destroy instances */ public DelegatingContextualLifecycle(InjectionTarget injectionTarget) { this.injectionTarget = injectionTarget; } public T create(Bean bean, CreationalContext creationalContext) { T instance = injectionTarget.produce(creationalContext); injectionTarget.inject(instance, creationalContext); injectionTarget.postConstruct(instance); return instance; } public void destroy(Bean bean, T instance, CreationalContext creationalContext) { try { injectionTarget.preDestroy(instance); creationalContext.release(); } catch (Exception e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/core/api/obsolete/src/main/java/org/apache/deltaspike/core/util/metadata/builder/DummyInjectionTarget.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.InjectionTarget; import java.util.Set; import static java.util.Collections.emptySet; /** * Injection target implementation that does nothing */ public class DummyInjectionTarget implements InjectionTarget { public void inject(T instance, CreationalContext ctx) { } public void postConstruct(T instance) { } public void preDestroy(T instance) { } public void dispose(T instance) { } public Set getInjectionPoints() { return emptySet(); } public T produce(CreationalContext ctx) { return null; } } ================================================ FILE: deltaspike/core/api/obsolete/src/test/java/org/apache/deltaspike/test/api/metadata/AnnotatedTypeBuilderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.metadata; import org.apache.deltaspike.core.api.literal.AlternativeLiteral; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.api.literal.ApplicationScopedLiteral; import org.apache.deltaspike.core.api.literal.NamedLiteral; import org.apache.deltaspike.core.api.literal.TypedLiteral; import org.apache.deltaspike.core.util.metadata.builder.AnnotatedTypeBuilder; import org.junit.Test; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AnnotatedConstructor; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.util.AnnotationLiteral; import jakarta.inject.Named; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertNotNull; public class AnnotatedTypeBuilderTest { @Test public void testTypeLevelAnnotationRedefinition() { AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(Cat.class); AnnotatedType cat = builder.create(); assertNotNull(cat); assertNotNull(cat.getAnnotation(Named.class)); assertEquals("cat", cat.getAnnotation(Named.class).value()); builder.addToClass(new AlternativeLiteral()) .addToClass(new ApplicationScopedLiteral()) .removeFromClass(Named.class) .addToClass(new NamedLiteral("tomcat")); cat = builder.create(); assertNotNull(cat); assertEquals(3, cat.getAnnotations().size()); assertTrue(cat.isAnnotationPresent(Named.class)); assertTrue(cat.isAnnotationPresent(Alternative.class)); assertTrue(cat.isAnnotationPresent(ApplicationScoped.class)); assertEquals("tomcat", cat.getAnnotation(Named.class).value()); AnnotatedMethod observerMethod = null; for (AnnotatedMethod m : cat.getMethods()) { if ("doSomeObservation".equals(m.getJavaMember().getName())) { observerMethod = m; break; } } assertNotNull(observerMethod); observerMethod.isAnnotationPresent(Observes.class); { // test reading from an AnnotatedType AnnotatedTypeBuilder builder2 = new AnnotatedTypeBuilder(); builder2.readFromType(cat); builder2.removeFromAll(Named.class); final AnnotatedType noNameCat = builder2.create(); assertFalse(noNameCat.isAnnotationPresent(Named.class)); assertEquals(2, noNameCat.getAnnotations().size()); } { // test reading from an AnnotatedType in non-overwrite mode AnnotatedTypeBuilder builder3 = new AnnotatedTypeBuilder(); builder3.readFromType(cat, true); builder3.removeFromAll(Named.class); builder3.readFromType(cat, false); final AnnotatedType namedCat = builder3.create(); assertTrue(namedCat.isAnnotationPresent(Named.class)); assertEquals(3, namedCat.getAnnotations().size()); } } @Test public void testAdditionOfAnnotation() { final AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(Cat.class, true); builder.addToClass(new TypedLiteral()); final AnnotatedType catAnnotatedType = builder.create(); assertThat(catAnnotatedType.isAnnotationPresent(Typed.class), is(true)); } @Test public void modifyAnnotationsOnConstructorParameter() throws NoSuchMethodException { final AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(Cat.class, true); builder.removeFromConstructorParameter(Cat.class.getConstructor(String.class, String.class), 1, Default.class); builder.addToConstructorParameter(Cat.class.getConstructor(String.class, String.class), 1, new AnyLiteral()); final AnnotatedType catAnnotatedType = builder.create(); Set> catCtors = catAnnotatedType.getConstructors(); assertThat(catCtors.size(), is(2)); for (AnnotatedConstructor ctor : catCtors) { if (ctor.getParameters().size() == 2) { List> ctorParams = ctor.getParameters(); assertThat(ctorParams.get(1).getAnnotations().size(), is(1)); assertThat((AnyLiteral) ctorParams.get(1).getAnnotations().toArray()[0], is(new AnyLiteral())); } } } @Test public void buildValidAnnotationAnnotatedType() { final AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(Small.class); final AnnotatedType smallAnnotatedType = builder.create(); assertThat(smallAnnotatedType.getMethods().size(), is(1)); assertThat(smallAnnotatedType.getConstructors().size(), is(0)); assertThat(smallAnnotatedType.getFields().size(), is(0)); } @Test public void testCtWithMultipleParams() { final AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(TypeWithParamsInCt.class); builder.addToClass(new AnnotationLiteral() {}); AnnotatedType newAt = builder.create(); assertNotNull(newAt); } @Test public void testEnumWithParam() { final AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); builder.readFromType(EnumWithParams.class); builder.addToClass(new AnnotationLiteral() {}); AnnotatedType newAt = builder.create(); assertNotNull(newAt); } public static class TypeWithParamsInCt { public TypeWithParamsInCt(String a, int b, String c) { // all fine } } public enum EnumWithParams { VALUE("A"); EnumWithParams(String val) { // all fine } } @Test public void testExceptionPerformance() { long start = System.nanoTime(); long val = -230349823423L; Exception e = new Exception("static"); for (int i=0; i < 10_000_000; i++) { try { val += 19; throw e; } catch (Exception e2) { // do nothing } } long end = System.nanoTime(); System.out.println("Exeptions took ms " + TimeUnit.NANOSECONDS.toMillis(end - start)); } } ================================================ FILE: deltaspike/core/api/obsolete/src/test/java/org/apache/deltaspike/test/api/metadata/Cat.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.metadata; import jakarta.annotation.PostConstruct; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.inject.Named; @Named("cat") public class Cat { private String color; private String gender; public Cat() { } @Inject public Cat(String color, String gender) { this.color = color; this.gender = gender; } @PostConstruct public void setup() { } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } protected void doSomeObservation(@Observes Cat cat, BeanManager beanManager) { // whoah, someone fires cats around ^^ // at least it tests parameter scanning ;) color = cat.color; } } ================================================ FILE: deltaspike/core/api/obsolete/src/test/java/org/apache/deltaspike/test/api/metadata/Small.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.metadata; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Qualifier @Documented @Retention(value = RetentionPolicy.RUNTIME) public @interface Small { String value() default ""; } ================================================ FILE: deltaspike/core/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.core core-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.core deltaspike-core-api jar Apache DeltaSpike Core-API org.apache.deltaspike.core.* !org.apache.deltaspike.core.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.ops4j.pax.cdi.extension; extension=deltaspike-core-api ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Config.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import org.apache.deltaspike.core.spi.config.ConfigFilter; import org.apache.deltaspike.core.spi.config.ConfigSource; import java.util.List; /** * The Configuration for an application/ClassLoader. */ public interface Config { /** * The entry point to the builder-based optionally typed configuration resolution mechanism. * * String is the default type for configuration entries and is not considered a 'type' by this resolver. Therefore * an UntypedResolver is returned by this method. To convert the configuration value to another type, call * {@link ConfigResolver.UntypedResolver#as(Class)}. * * @param name The property key to resolve * @return A builder for configuration resolution. */ ConfigResolver.UntypedResolver resolve(String name); /** *

This method can be used to access multiple * {@link ConfigResolver.TypedResolver} which must be consistent. * The returned {@link ConfigSnapshot} is an immutable object which contains all the * resolved values at the time of calling this method. * *

An example would be to access some {@code 'myapp.host'} and {@code 'myapp.port'}: * The underlying values are {@code 'oldserver'} and {@code '8080'}. * *

     *     // get the current host value
     *     TypedResolver<String> hostCfg config.resolve("myapp.host")
     *              .cacheFor(TimeUnit.MINUTES, 60);
     *
     *     // and right inbetween the underlying values get changed to 'newserver' and port 8082
     *
     *     // get the current port for the host
     *     TypedResolver<Integer> portCfg config.resolve("myapp.port")
     *              .cacheFor(TimeUnit.MINUTES, 60);
     * 
* * In ths above code we would get the combination of {@code 'oldserver'} but with the new port {@code 8081}. * And this will obviously blow up because that host+port combination doesn't exist. * * To consistently access n different config values we can start a {@link ConfigSnapshot} for those values. * *
     *     ConfigSnapshot cfgSnap = config.createSnapshot(hostCfg, portCfg);
     *
     *     String host = cfgSnap.getValue(hostCfg);
     *     Integer port = cfgSnap.getValue(portCfg);
     * 
* * Note that there is no close on the snapshot. * They should be used as local variables inside a method. * Values will not be reloaded for an open {@link ConfigSnapshot}. * * @param typedResolvers the list of {@link ConfigResolver.TypedResolver} to be accessed in an atomic way * * @return a new {@link ConfigSnapshot} which holds the resolved values of all the {@param typedResolvers}. */ ConfigSnapshot snapshotFor(ConfigResolver.TypedResolver... typedResolvers); /** * @return all the current ConfigSources for this Config */ ConfigSource[] getConfigSources(); /** * This method can be used for programmatically adding {@link ConfigSource}s. * It is not needed for normal 'usage' by end users, but only for Extension Developers! * * @param configSourcesToAdd the ConfigSources to add */ void addConfigSources(List configSourcesToAdd); /** * @return the {@link ConfigFilter}s for the current application. */ List getConfigFilters(); /** * Add a {@link ConfigFilter} to the ConfigResolver. This will only affect the current WebApp (or more precisely the * current ClassLoader and it's children). * * @param configFilter */ void addConfigFilter(ConfigFilter configFilter); /** * Filter the configured value. * This can e.g. be used for decryption. * @param key the key of the config property * @param value to be filtered * @param forLog whether the value is intended to be presented to some humans somehow. * If filtered for logging, then secrets might get starred out '*****'. * @return the filtered value */ String filterConfigValue(String key, String value, boolean forLog); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigProperty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; import static java.lang.annotation.ElementType.CONSTRUCTOR; 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.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.util.concurrent.TimeUnit.SECONDS; /** * This Qualifier allows simple injection of configuration properties through the DeltaSpike configuration * mechanism. *

* A default implementation is provided in DeltaSpike for basic String injection points: *

 *   @Inject @ConfigProperty(name="locationId")
 *   private String locationId;
 * 
*

*

* It's possible to use config properties in a type-safe manner, which requires a custom producer: * *

 *   @Target({FIELD, METHOD})
 *   @Retention(RUNTIME)
 *   @ConfigProperty(name = "locationId")
 *   @Qualifier
 *   public @interface Location {
 *   }
 * 
* *
 *   @Location
 *   private String locationId;
 * 
* *
 *   @ApplicationScoped
 *   public class CustomConfigPropertyProducer extends BaseConfigPropertyProducer {
 *     @Produces
 *     @Dependent
 *     @Location
 *     public String produceLocationId(InjectionPoint injectionPoint) {
 *       String configuredValue = getStringPropertyValue(injectionPoint);
 *       if (configuredValue == null) {
 *         return null;
 *       }
 *       return configuredValue;
 *     }
 *   }
 * 
*

*

* Producers can be implemented to support other types of injection points: *

 *   @Inject
 *   @Location
 *   private LocationId locationId;
 * 
* *
 *   @ApplicationScoped
 *   public class CustomConfigPropertyProducer extends BaseConfigPropertyProducer {
 *     @Produces
 *     @Dependent
 *     @Location
 *     public LocationId produceLocationId(InjectionPoint injectionPoint) {
 *       String configuredValue = getStringPropertyValue(injectionPoint);
 *       if (configuredValue == null) {
 *         return null;
 *       }
 *       return LocationId.valueOf(configuredValue.trim().toUpperCase());
 *     }
 *   }
 * 
*

* For custom producer implementations, {@link org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer} can * be used as the base class. * * @see org.apache.deltaspike.core.api.config.ConfigResolver * @see org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer */ @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @Qualifier public @interface ConfigProperty { /** * This constant is a workaround for the java restriction that Annotation values cannot be set to null. Do not use * this String in your configuration. */ String NULL = "org.apache.deltaspike.NullValueMarker"; /** * Name/key of the property. * @return name of the property */ @Nonbinding String name(); /** * Optional default value. * * @return the default value which should be used if no config value could be found */ @Nonbinding String defaultValue() default NULL; @Nonbinding boolean projectStageAware() default true; @Nonbinding String parameterizedBy() default NULL; /** * Whether to resolve 'variables' in configured values. * * @see org.apache.deltaspike.core.api.config.ConfigResolver.TypedResolver#evaluateVariables(boolean) */ @Nonbinding boolean evaluateVariables() default true; /** * Converter for this property. * @return the converter to use to read this property in the expected type. */ @Nonbinding Class converter() default ConfigResolver.Converter.class; /** * This only applies when used with injecting a {@link java.util.function.Supplier} for the requested configuration. * @return the duration while the value is not reloaded. */ @Nonbinding long cacheFor() default -1; /** * This only applies when used with injecting a {@link java.util.function.Supplier} for the requested configuration. * @return the duration unit for {@see cacheFor()}. */ @Nonbinding TimeUnit cacheUnit() default SECONDS; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import jakarta.enterprise.inject.Vetoed; import org.apache.deltaspike.core.spi.config.ConfigFilter; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassUtils; /** * The main entry point to the DeltaSpike configuration mechanism. * *

* Resolves configured values of properties by going through the list of configured {@link ConfigSource}s and using the * one with the highest ordinal. If multiple {@link ConfigSource}s have the same ordinal, their order is undefined.

* *

* You can provide your own lookup paths by implementing and registering additional {@link PropertyFileConfig} or * {@link ConfigSource} or {@link org.apache.deltaspike.core.spi.config.ConfigSourceProvider} implementations.

* *

* The resolved configuration is also accessible by simple injection using the {@link ConfigProperty} qualifier.

* * @see DeltaSpike Configuration Mechanism */ @Vetoed public final class ConfigResolver { /** * Can be used to tweak the application name. * This will e.g. used in the JMX MBean to differentiate between applications. */ public static final String DELTASPIKE_APP_NAME_CONFIG = "deltaspike.application.name"; /** * Set this to true if your application should log the whole ConfigSources and Configuration * at startup. */ public static final String DELTASPIKE_LOG_CONFIG = "deltaspike.config.log"; private static ConfigProvider configProvider; private ConfigResolver() { // this is a utility class which doesn't get instantiated. } public static Config getConfig() { ClassLoader cl = ClassUtils.getClassLoader(null); return getConfig(cl); } public static Config getConfig(ClassLoader cl) { return getConfigProvider().getConfig(cl); } /** * This method can be used for programmatically adding {@link ConfigSource}s. * It is not needed for normal 'usage' by end users, but only for Extension Developers! * * @param configSourcesToAdd the ConfigSources to add */ public static synchronized void addConfigSources(List configSourcesToAdd) { getConfigProvider().getConfig().addConfigSources(configSourcesToAdd); } /** * Clear all ConfigSources for the current ClassLoader. * This will also clean up all ConfigFilters. */ public static synchronized void freeConfigSources() { if (configProvider != null) { ClassLoader cl = ClassUtils.getClassLoader(null); configProvider.releaseConfig(cl); } } /** * Add a {@link ConfigFilter} to the ConfigResolver. This will only affect the current WebApp (or more precisely the * current ClassLoader and it's children). * * @param configFilter */ public static void addConfigFilter(ConfigFilter configFilter) { getConfigProvider().getConfig().addConfigFilter(configFilter); } /** * @return the {@link ConfigFilter}s for the current application. */ public static List getConfigFilters() { return getConfigProvider().getConfig().getConfigFilters(); } /** * {@link #getPropertyValue(java.lang.String)} which returns the provided default value if no configured value can * be found (null or empty). * * @param key the property key * @param defaultValue fallback value * * @return the configured property value from the {@link ConfigSource} with the highest ordinal or the defaultValue * if there is no value explicitly configured */ public static String getPropertyValue(String key, String defaultValue) { return getPropertyValue(key, defaultValue, true); } public static String getPropertyValue(String key, String defaultValue, boolean evaluateVariables) { return getConfigProvider().getConfig().resolve(key) .withDefault(defaultValue) .evaluateVariables(evaluateVariables) .withCurrentProjectStage(false) .getValue(); } /** * Resolves the value configured for the given key. * * @param key the property key * * @return the configured property value from the {@link ConfigSource} with the highest ordinal or null if there is * no configured value for it */ public static String getPropertyValue(String key) { return getConfigProvider().getConfig().resolve(key) .evaluateVariables(true) .withCurrentProjectStage(false) .getValue(); } /** * Resolves the value configured for the given key. * * @param key the property key * @param evaluateVariables whether to evaluate any '${variablename}' variable expressions * * @return the configured property value from the {@link ConfigSource} with the highest ordinal or null if there is * no configured value for it */ public static String getPropertyValue(String key, boolean evaluateVariables) { return getConfigProvider().getConfig().resolve(key) .evaluateVariables(evaluateVariables) .withCurrentProjectStage(false) .getValue(); } /** * Resolves the value configured for the given key in the current * {@link org.apache.deltaspike.core.api.projectstage.ProjectStage}. * *

* First, it will search for a value configured for the given key suffixed with the current ProjectStage (e.g. * 'myproject.myconfig.Production'), and in case this value is not found (null or empty), it will look up the given * key without any suffix.

* *

* Attention This method must only be used after all ConfigSources got registered and it also must not be * used to determine the ProjectStage itself.

* * @param key * * @return the value configured for {@code .}, or just the configured value of * {@code } if the project-stage-specific value is not found (null or empty) * */ public static String getProjectStageAwarePropertyValue(String key) { return getConfigProvider().getConfig().resolve(key) .withCurrentProjectStage(true) .evaluateVariables(true) .getValue(); } /** * {@link #getProjectStageAwarePropertyValue(String)} which returns the provided default value if no configured * value can be found (null or empty). * * @param key * @param defaultValue fallback value * * @return the configured value or if non found the defaultValue * */ public static String getProjectStageAwarePropertyValue(String key, String defaultValue) { return getConfigProvider().getConfig().resolve(key) .withCurrentProjectStage(true) .withDefault(defaultValue) .evaluateVariables(true) .getValue(); } /** * Resolves the value configured for the given key, parameterized by the current * {@link org.apache.deltaspike.core.api.projectstage.ProjectStage} and by the value of a second property. * *

* Example:
* Suppose the current ProjectStage is {@code UnitTest} and we are looking for the value of {@code datasource} * parameterized by the configured {@code dbvendor}. *

*

* The first step is to resolve the value of the second property, {@code dbvendor}. This will also take the current * ProjectStage into account. The following lookup is performed: *

  • dbvendor.UnitTest
* and if this value is not found then we will do a 2nd lookup for *
  • dbvendor

* *

* If a value was found for the second property (e.g. dbvendor = 'mysql') then we will use its value for the main * lookup. If no value is found for the parameterized key {@code ..}, we * will do the {@code .}, then {@code .} and finally a {@code } * lookup: *

    *
  • datasource.mysql.UnitTest
  • *
  • datasource.mysql
  • *
  • datasource.UnitTest
  • *
  • datasource
  • *
*

* *

* Attention This method must only be used after all ConfigSources got registered and it also must not be * used to determine the ProjectStage itself.

* * @param key * @param property the property to look up first and use as the parameter for the main lookup * * @return the configured value or null if no value is found for any of the key variants * */ public static String getPropertyAwarePropertyValue(String key, String property) { return getConfigProvider().getConfig().resolve(key) .withCurrentProjectStage(true) .parameterizedBy(property) .evaluateVariables(true) .getValue(); } /** * {@link #getPropertyAwarePropertyValue(java.lang.String, java.lang.String)} which returns the provided default * value if no configured value can be found (null or empty). * *

* Attention This method must only be used after all ConfigSources got registered and it also must not be * used to determine the ProjectStage itself.

* * @param key * @param property the property to look up first and use as the parameter for the main lookup * @param defaultValue fallback value * * @return the configured value or if non found the defaultValue * */ public static String getPropertyAwarePropertyValue(String key, String property, String defaultValue) { return getConfigProvider().getConfig().resolve(key) .withCurrentProjectStage(true) .parameterizedBy(property) .withDefault(defaultValue) .evaluateVariables(true) .getValue(); } /** * Resolve all values for the given key. * * @param key * * @return a List of all found property values, sorted by their ordinal in ascending order * * @see org.apache.deltaspike.core.spi.config.ConfigSource#getOrdinal() */ public static List getAllPropertyValues(String key) { ConfigSource[] configSources = getConfigProvider().getConfig().getConfigSources(); List result = new ArrayList(); for (int i = configSources.length; i > 0; i--) { String value = configSources[i - 1].getPropertyValue(key); if (value != null) { value = filterConfigValue(key, value); if (!result.contains(value)) { result.add(value); } } } return result; } /** * Returns a Map of all properties from all scannable config sources. The values of the properties reflect the * values that would be obtained by a call to {@link #getPropertyValue(java.lang.String)}, that is, the value of the * property from the ConfigSource with the highest ordinal. * * @see ConfigSource#isScannable() */ public static Map getAllProperties() { ConfigSource[] configSources = getConfigProvider().getConfig().getConfigSources(); Map result = new HashMap(); for (int i = configSources.length; i > 0; i--) { ConfigSource configSource = configSources[i - 1]; if (configSource.isScannable()) { result.putAll(configSource.getProperties()); } } return Collections.unmodifiableMap(result); } public static ConfigSource[] getConfigSources() { return getConfigProvider().getConfig().getConfigSources(); } /** * Filter the configured value. * This can e.g. be used for decryption. * @return the filtered value */ public static String filterConfigValue(String key, String value) { return getConfigProvider().getConfig().filterConfigValue(key, value, false); } /** * Filter the configured value for logging. * This can e.g. be used for displaying ***** instead of a real password. * @return the filtered value */ public static String filterConfigValueForLog(String key, String value) { return getConfigProvider().getConfig().filterConfigValue(key, value, true); } /** * A very simple interface for conversion of configuration values from String to any Java type. * *

If a Converter implements the {@link java.lang.AutoCloseable} interface it will automatically * be released when the Config is shut down.

* @param The target type of the configuration entry */ public interface Converter { /** * Returns the converted value of the configuration entry. * @param value The String property value to convert * @return Converted value */ T convert(String value); } /** * A builder-based typed resolution mechanism for configuration values. * @param The target type of the configuration entry. */ public interface TypedResolver { /** * Declare the Resolver to return a List of the given Type. * When getting value it will be split on each comma (',') character. * If a comma is contained in the values it must get escaped with a preceding backslash ("\,"). * Any backslash needs to get escaped via double-backslash ("\\"). * Note that in property files this leads to "\\\\" as properties escape themselves. * * @return a TypedResolver for a list of configured comma separated values * * @since 1.8.0 */ TypedResolver> asList(); /** * Appends the resolved value of the given property to the key of this builder. This is described in more detail * in {@link ConfigResolver#getPropertyAwarePropertyValue(String, String)}. * @param propertyName The name of the parameter property * @return This builder */ TypedResolver parameterizedBy(String propertyName); /** * Indicates whether to append the name of the current project stage to the key of this builder. This * is described in more detail in {@link ConfigResolver#getProjectStageAwarePropertyValue(String)}. True by * default. * @param with * @return This builder */ TypedResolver withCurrentProjectStage(boolean with); /** * Indicates whether the fallback resolution sequence should be performed, as described in * {@link ConfigResolver#getPropertyAwarePropertyValue(String, String)}. This applies only when * {@link #parameterizedBy(String)} or {@link #withCurrentProjectStage(boolean)} is used. * @param strictly * @return This builder */ TypedResolver strictly(boolean strictly); /** * Sets the default value to use in case the resolution returns null. * @param value the default value * @return This builder */ TypedResolver withDefault(T value); /** * Sets the default value to use in case the resolution returns null. Converts the given String to the type of * this resolver using the same method as used for the configuration entries. * @param value string value to be converted and used as default * @return This builder */ TypedResolver withStringDefault(String value); /** * Specify that a resolved value will get cached for a certain amount of time. * After the time expires the next {@link #getValue()} will again resolve the value * from the underlying {@link ConfigResolver}. * * @param timeUnit the TimeUnit for the value * @param value the amount of the TimeUnit to wait * @return This builder */ TypedResolver cacheFor(TimeUnit timeUnit, long value); /** * Whether to evaluate variables in configured values. * A variable starts with '${' and ends with '}', e.g. *
         * mycompany.some.url=${myserver.host}/some/path
         * myserver.host=http://localhost:8081
         * 
* If 'evaluateVariables' is enabled, the result for the above key * {@code "mycompany.some.url"} would be: * {@code "http://localhost:8081/some/path"} * @param evaluateVariables whether to evaluate variables in values or not * @return This builder */ TypedResolver evaluateVariables(boolean evaluateVariables); /** * Whether to log picking up any value changes as INFO. * * @return This builder */ TypedResolver logChanges(boolean logChanges); /** * A user can register a Callback which gets notified whenever * a config change got detected. * The check is performed on every call to {@link #getValue()} * and also inside {@link Config#snapshotFor(TypedResolver...)}. * * If a change got detected the {@param valueChangedCallback} will * get invoked in a synchronous way before the {@link #getValue()} * or {@link Config#snapshotFor(TypedResolver...)} returns. * * There can only be a single valueChangedCallback. * Using this method multiple times will replace the previously set callback. * * @param valueChangedCallback a lambda or implementation which will get invoked * whenever a value change is being detected. * @return This builder */ TypedResolver onChange(ConfigChanged valueChangedCallback); /** * Returns the converted resolved filtered value. * @return the resolved value */ T getValue(); /** * Returns the value from a previously taken {@link ConfigSnapshot}. * * @return the resolved Value * @see Config#snapshotFor(TypedResolver[]) * @throws IllegalArgumentException if the {@link ConfigSnapshot} hasn't been resolved * for this {@link TypedResolver} */ T getValue(ConfigSnapshot configSnapshot); /** * Returns the key given in {@link #resolve(String)}. * @return the original key */ String getKey(); /** * Returns the actual key which led to successful resolution and corresponds to the resolved value. This applies * only when {@link #parameterizedBy(String)} or {@link #withCurrentProjectStage(boolean)} is used and * {@link #strictly(boolean)} is not used, otherwise the resolved key should always be equal to the original * key. This method is provided for cases, when projectStage-aware and/or parameterized resolution is * requested but the value for such appended key is not found and some of the fallback keys is used, as * described in {@link ConfigResolver#getPropertyAwarePropertyValue(String, String)}. * This should be called only after calling {@link #getValue()} otherwise the value is undefined (but likely * null). * @return */ String getResolvedKey(); /** * Returns the default value provided by {@link #withDefault(Object)} or {@link #withStringDefault(String)}. * Returns null if no default was provided. * @return the default value or null */ T getDefaultValue(); } /** * A builder-based optionally typed resolution mechanism for configuration values. * @param This type variable should always be String for UntypedResolver. */ public interface UntypedResolver extends TypedResolver { /** * Sets the type of the configuration entry to the given class and returns this builder as a TypedResolver. * Only one of the supported types should be used which includes: Boolean, Class, Integer, Long, Float, Double. * For custom types, see {@link #as(Class, Converter)}. * @param clazz The target type * @param The target type * @return This builder as a TypedResolver */ TypedResolver as(Class clazz); /** * @param type target type, includes List and Map using a Converter * @param converter The converter for the target type * @param target type * @return this builder typed. */ TypedResolver as(Type type, Converter converter); /** * Sets the type of the configuration entry to the given class, sets the converter to the one given and * returns this builder as a TypedResolver. If a converter is provided for one of the types supported by * default (see {@link #as(Class)} then the provided converter is used instead of the built-in one. * @param clazz The target type * @param converter The converter for the target type * @param The target type * @return This builder as a TypedResolver */ TypedResolver as(Class clazz, Converter converter); /** * Use this method if the target type consists of information taken from multiple config keys. * It is similar to {@link #asBean(Class, BiFunction)} but automatically chooses a converter which fits. * The following Beans are supported: *
    *
  • POJO with Constructor parameters. In this case this constructor will be used
  • *
  • Java14 Records
  • *
  • POJO with default ct and fields. * Those fields can use the {@link ConfigProperty} annotation on the fields for more control
  • *
* @param clazz * @param * @return */ TypedResolver asBean(Class clazz); /** * Set the required Target type and use a converter function which has access to multiple attributes in the configuration. * Use this method if the target type consists of information taken from multiple config keys. * If you consider the following type: *
         *  public record ServerEndpoint(String host, Integer port, String path)
         *
         *  config.properties:
         *  myapp.some.server.host=myserver
         *  myapp.some.server.port=80
         *  myapp.some.server.path=/myapp/endpoint1
         *  myapp.other.server.host=otherserver
         *  myapp.other.server.port=443
         *  myapp.other.server.path=/otherapp/endpoint2
         * 
* * This function will have access to all the underlying properties by using the given Config. * When resolving the target type the system makes sure that access to all requested properties is atomic. * * @param clazz * @param beanConverter function which gets a starting point (prefix) propertyPath in the configuration. * In the examples above it is e.g. "myapp.some.server." and "myapp.other.server." * @return This builder as a TypedResolver */ TypedResolver asBean(Class clazz, BiFunction beanConverter); } /** * The entry point to the builder-based optionally typed configuration resolution mechanism. * * String is the default type for configuration entries and is not considered a 'type' by this resolver. Therefore * an UntypedResolver is returned by this method. To convert the configuration value to another type, call * {@link UntypedResolver#as(Class)}. * * @param name The property key to resolve * @return A builder for configuration resolution. */ public static UntypedResolver resolve(String name) { return getConfigProvider().getConfig().resolve(name); } public static ConfigProvider getConfigProvider() { if (configProvider == null) { synchronized (ConfigResolver.class) { if (configProvider == null) { Iterator configProviders = ServiceLoader.load(ConfigProvider.class).iterator(); if (!configProviders.hasNext()) { throw new RuntimeException("Could not load ConfigProvider"); } configProvider = configProviders.next(); if (configProviders.hasNext()) { throw new RuntimeException("Found more than one ConfigProvider"); } } } } return configProvider; } /** * Provide access to the underlying {@link Config} instance. * */ public interface ConfigProvider { /** * Return either an existing Config associated with the current TCCL or a * new Config and associate it with the TCCL. * * @return the Config associated with the current ThreadContextClassLoader */ Config getConfig(); /** * Return either an existing Config associated with the given ClassLoader or a * new Config and associate it with the given ClassLoader. * * @return the Config associated with the given ClassLoader */ Config getConfig(ClassLoader cl); /** * Release the Config associated with the given ClassLoader. * This will also properly close all the ConfigSources, Converters, etc * managed by this Config. * * ATTENTION: Usually this method doesn't need to be invoked manually! * It will automatically get invoked in BeforeShutdown via our ConfigExtension internally. */ void releaseConfig(ClassLoader cl); /** * Provide access to the ConfigHelper */ ConfigHelper getHelper(); } /** * Some utility functions which are useful for implementing own ConfigSources, etc. */ public interface ConfigHelper { /** * @return A Set of all the attributes which differ between the old and new config Map * or an empty Set if there is no difference. */ Set diffConfig(Map oldValues, Map newValues); } /** * Callback which can be used with {@link TypedResolver#onChange(ConfigChanged)} */ public interface ConfigChanged { void onValueChange(String key, T oldValue, T newValue); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigSnapshot.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; /** * A value holder for TypedResolver values which all got resolved in a guaranteed atomic way. * * @see Config#snapshotFor(ConfigResolver.TypedResolver[]) * @see ConfigResolver.TypedResolver#getValue(ConfigSnapshot) */ public interface ConfigSnapshot { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Configuration.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.util.concurrent.TimeUnit.SECONDS; /** * Marker to let DeltaSpike pick this interface and create a proxy getting values * from the configuration. * * The underlying Bean should be normal-scoped. */ @Target(TYPE) @Retention(RUNTIME) @Documented public @interface Configuration { /** * @return the duration while the value is not reloaded. */ long cacheFor() default -1; /** * @return the duration unit for {@see cacheFor()}. */ TimeUnit cacheUnit() default SECONDS; /** * @return the key prefix to apply to all methods. */ String prefix() default ""; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/DeltaSpikeConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import java.io.Serializable; /** * Marker interface for all classes used for dynamic configuration of DeltaSpike itself. The term Dynamic * configuration refers to values which can be determined and changed during runtime and shouldn't be accessed * during container boot time. * *

* All DeltaSpike dynamic configuration objects implement this interface so they can be found more easily. There is no * other functionality implied with this interface.

* *

* DeltaSpike uses a type-safe configuration approach for most internal configuration. Instead of writing a * properties file or XML, you just implement one of the configuration interfaces which will then be picked up as a * CDI bean. If* there is already a default configuration for some functionality in DeltaSpike, you can use @ * Specializes or @Alternative to change those.

* *

* See {@link org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig} for static DeltaSpike configuration * based on properties.

* */ public interface DeltaSpikeConfig extends Serializable { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Filter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Marker to let DeltaSpike pick automatically the decorated instance * as a ConfigFilter of current CDI module. * * The underlying Bean should be normal-scoped. */ @Target({ METHOD, TYPE }) @Retention(RUNTIME) @Documented public @interface Filter { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; /** *

* If you implement this interface, the property files with the given file name will be registered as * {@link org.apache.deltaspike.core.spi.config.ConfigSource}s.

*

There are 2 ways to register a {@code PropertyFileConfig}

* *

1. Automatic pickup via {@code ProcessAnnotatedType} phase

*

* DeltaSpike will automatically pick up all the implementations which are * inside a Bean Archive (a JAR or ClassPath entry with a META-INF/beans.xml file) during the * {@link jakarta.enterprise.inject.spi.ProcessAnnotatedType} phase and create a new instance via reflection. Thus the * implementations will need a non-private default constructor. There is no CDI injection being performed in * those instances! The scope of the implementations will also be ignored as they will not get picked up as CDI * beans.

* *

* Please note that the configuration will only be available after the boot is finished. This means that you cannot use * this configuration inside a CDI Extension before the boot is finished!

* *

Attention: When using this logic inside an EAR then you might get * different behaviour depending on the Java EE * server you are using. Some EE container use a different ClassLoader to bootstrap * the application than later to serve Requests. * In that case we would register the ConfigSources on the wrong ConfigResolver * (means we register it to the wrong ClassLoader). If you did hit such an application server * then you might need to switch back to manually register the * {@link org.apache.deltaspike.core.spi.config.ConfigSource} or * {@link org.apache.deltaspike.core.spi.config.ConfigSourceProvider} via the * {@link java.util.ServiceLoader} mechanism described there.

. * *

2. Automatic pickup via {@code java.util.ServiceLoader} mechanism

*

In case you have an EAR or you need the configured values already during the CDI container start * then you can also register the PropertyFileConfig via the {@code java.util.ServiceLoader} mechanism. * To not have this configuration picked up twice it is required to annotate your own * {@code PropertyFileConfig} implementation with {@link org.apache.deltaspike.core.api.exclude.Exclude}.

* *

The {@code ServiceLoader} mechanism requires to have a file *

 *     META-INF/services/org.apache.deltaspike.core.api.config.PropertyFileConfig
 * 
* containing the fully qualified Class name of your own {@code PropertyFileConfig} implementation class. *
 *     com.acme.my.own.SomeSpecialPropertyFileConfig
 * 
* The implementation will look like the following: *
 *     @Exclude
 *     public class SomeSpecialPropertyFileConfig implements PropertyFileConfig {
 *         public String getPropertyFileName() {
 *             return "myconfig/specialconfig.properties"
 *         }
 *         public boolean isOptional() {
 *             return false;
 *         }
 *     }
 * 
*

* */ public interface PropertyFileConfig { /** * All the property files on the classpath which have this name will get picked up and registered as * {@link org.apache.deltaspike.core.spi.config.ConfigSource}. * * If the the returned String starts with 'file://' then we pick up the configuration from a file * on the File System instead of the ClassPath. * The same works for other URLs which are passed, e.g. 'http://'. * Note that reading the property values only gets performed once right now. * * @return the full file name (including path) of the property files to pick up. */ String getPropertyFileName(); /** * @return true if the file is optional, false if the specified file has to be in place. */ boolean isOptional(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/PropertyLoader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * Utility class to load configuration properties via arbitrary property files in a well defined order. * *

* This will also pick up property files with names suffixed with {@code -}, e.g. * myconfig-Production.properties.

*

* User configurations should have {@code deltaspike_ordinal} as the first property, with a value greater than * 100.

* */ public class PropertyLoader { public static final int CONFIGURATION_ORDINAL_DEFAULT_VALUE = 100; private static final String FILE_EXTENSION = ".properties"; private static final Logger LOG = Logger.getLogger(PropertyLoader.class.getName()); private PropertyLoader() { // utility class doesn't have a public ct } /** * Looks for all properties files with the given name in the classpath, loads them in ascending order determined by * their ordinal and merges them. * *

* The idea is to be able to override properties by just providing a new properties file with the same name but a * higher 'deltaspike_ordinal' than the old one.

* *

* If a property file defines no 'deltaspike_ordinal' property than a default value of * {@link #CONFIGURATION_ORDINAL_DEFAULT_VALUE} is assumed. Any sensitive default which is provided by the system * parsing for the configuration should have a 'deltaspike_ordinal' value lower than 10. In most cases a value of * 1.

* *

* If two property files have the same 'deltaspike_ordinal', their order is undefined. The Properties file which * gets found first will be processed first and thus gets overwritten by the one found later.

* * @param propertyFileName the name of the properties file, without the extension '.properties' * * @return the final property values */ public static synchronized Properties getProperties(String propertyFileName) { if (propertyFileName == null) { throw new IllegalArgumentException("propertyFileName must not be null!"); } try { if (propertyFileName.endsWith(FILE_EXTENSION)) { // if the given propertyFileName already contains the extension, then remove it. propertyFileName = propertyFileName.substring(0, propertyFileName.length() - FILE_EXTENSION.length()); } List allProperties = loadAllProperties(propertyFileName); if (allProperties == null) { return null; } List sortedProperties = sortProperties(allProperties); Properties properties = mergeProperties(sortedProperties); return properties; } catch (IOException e) { LOG.log(Level.SEVERE, "Error while loading the propertyFile " + propertyFileName, e); return null; } } private static List loadAllProperties(String propertyFileName) throws IOException { ClassLoader cl = ClassUtils.getClassLoader(null); List properties = new ArrayList(); // read the normal property file names Enumeration propertyUrls = cl.getResources(propertyFileName + FILE_EXTENSION); while (propertyUrls != null && propertyUrls.hasMoreElements()) { URL propertyUrl = propertyUrls.nextElement(); fillProperties(properties, propertyUrl); } // and also read the ones post-fixed with the projectStage ProjectStage ps = ProjectStageProducer.getInstance().getProjectStage(); propertyUrls = cl.getResources(propertyFileName + "-" + ps + FILE_EXTENSION); while (propertyUrls != null && propertyUrls.hasMoreElements()) { URL propertyUrl = propertyUrls.nextElement(); fillProperties(properties, propertyUrl); } if (properties.isEmpty()) { if (LOG.isLoggable(Level.INFO)) { LOG.info("could not find any property files with name " + propertyFileName); } return null; } return properties; } private static void fillProperties(List properties, URL propertyUrl) throws IOException { InputStream is = null; try { is = propertyUrl.openStream(); Properties prop = new Properties(); prop.load(is); properties.add(prop); // a bit debugging output int ordinal = getConfigurationOrdinal(prop); if (LOG.isLoggable(Level.FINE)) { LOG.fine("loading properties with ordinal " + ordinal + " from file " + propertyUrl.getFile()); } } finally { if (is != null) { is.close(); } } } /** * Implement a quick and dirty sorting mechanism for the given Properties. * @param allProperties * @return the Properties list sorted by it's 'configuration.ordinal' in ascending order. */ private static List sortProperties(List allProperties) { List sortedProperties = new ArrayList(); for (Properties p : allProperties) { int configOrder = getConfigurationOrdinal(p); int i; for (i = 0; i < sortedProperties.size(); i++) { int listConfigOrder = getConfigurationOrdinal(sortedProperties.get(i)); if (listConfigOrder > configOrder) { // only go as far as we found a higher priority Properties file break; } } sortedProperties.add(i, p); } return sortedProperties; } /** * Determine the 'deltaspike_ordinal' of the given properties. * {@link #CONFIGURATION_ORDINAL_DEFAULT_VALUE} if * {@link ConfigSource#DELTASPIKE_ORDINAL} is not set in the * Properties file. * * @param p the Properties from the file. * @return the ordinal number of the given Properties file. */ private static int getConfigurationOrdinal(Properties p) { int configOrder = CONFIGURATION_ORDINAL_DEFAULT_VALUE; String configOrderString = p.getProperty(ConfigSource.DELTASPIKE_ORDINAL); if (configOrderString != null && configOrderString.length() > 0) { try { configOrder = Integer.parseInt(configOrderString); } catch (NumberFormatException nfe) { LOG.severe(ConfigSource.DELTASPIKE_ORDINAL + " must be an integer value!"); throw nfe; } } return configOrder; } /** * Merge the given Properties in order of appearance. * @param sortedProperties * @return the merged Properties */ private static Properties mergeProperties(List sortedProperties) { Properties mergedProperties = new Properties(); for (Properties p : sortedProperties) { for (Map.Entry entry : p.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); if (!ConfigSource.DELTASPIKE_ORDINAL.equals(key)) { // simply overwrite the old properties with the new ones. mergedProperties.setProperty(key, value); } } } return mergedProperties; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/Source.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Marker to let DeltaSpike pick automatically the decorated instance * as a ConfigSource of current CDI module. * * The underlying Bean should be normal-scoped. */ @Target({ METHOD, TYPE }) @Retention(RUNTIME) @Documented public @interface Source { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/base/CoreBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.base; import org.apache.deltaspike.core.api.config.ConfigResolver; import java.util.concurrent.TimeUnit; public interface CoreBaseConfig extends DeltaSpikeBaseConfig { interface BeanManagerIntegration { /** * Whether to use CDI.current() if available. * This might fail in some CDI containers in some situations. * Try switching to 'false' to enforce the 'old' DeltaSpike BeanManager lookup. */ Boolean DELEGATE_LOOKUP = ConfigResolver.resolve("deltaspike.bean-manager.delegate_lookup") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.TRUE) .getValue(); } interface MBeanIntegration { Boolean AUTO_UNREGISTER = ConfigResolver.resolve("deltaspike.mbean.auto-unregister") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.TRUE) .getValue(); } interface ScopeCustomization { interface WindowRestriction { String MAX_COUNT_KEY = "deltaspike.scope.window.max-count"; Integer MAX_COUNT = ConfigResolver.resolve(MAX_COUNT_KEY) .as(Integer.class) .withCurrentProjectStage(true) .withDefault(1024) .getValue(); } } interface TimeoutCustomization { Integer FUTUREABLE_TERMINATION_TIMEOUT_IN_MILLISECONDS = ConfigResolver.resolve("deltaspike.futureable.termination-timeout_in_milliseconds") .as(Integer.class) .withCurrentProjectStage(true) .withDefault((int) TimeUnit.MINUTES.toMillis(1)) .getValue(); } interface ParentExtensionCustomization { Boolean PARENT_EXTENSION_ENABLED = ConfigResolver.resolve("deltaspike.parent.extension.enabled") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); } interface InterDynCustomization { /** * All interdyn rules start with this prefix and contains a 'match' and a 'annotation' part. * The 'match' is a regular expression which depicts the classes which should get annotated. * The 'annotation' is the annotation name which should get applied to all the classes which * match the 'match' regexp. * * A sample config might look like: *
         * deltaspike.interdyn.rule.1.match=com\.mycorp\..*Service.*
         * deltaspike.interdyn.rule.1.annotation=org.apache.deltaspike.core.api.monitoring.InvocationMonitored
         * 
*/ String INTERDYN_RULE_PREFIX = "deltaspike.interdyn.rule."; /** * Whether the InterDyn feature is enabled or not. * * If the feature is enabled at startup then we will apply the interceptors dynamically * to all the matching classes. * Otherwise we will skip the instrumentation. */ ConfigResolver.TypedResolver INTERDYN_ENABLED = ConfigResolver.resolve("deltaspike.interdyn.enabled") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE); /** * Set this configuration to 'false' (case sensitive string) to disable the built-in InvocationResultLogger */ String CONFIG_INVOCATIONRESULTLOGGER_ENABLED = "deltaspike.invocationresultlogger.enabled"; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/base/DeltaSpikeBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.base; /** * Marker interface for all classes used for static configuration of DeltaSpike itself. The term Static * configuration refers to values which are set using DeltaSpike's configuration mechanism (e.g. in {@code * META-INF/apache-deltaspike.properties}) and remain fixed during runtime and can be accessed even during container * boot time. * *

* All DeltaSpike static configuration objects implement this interface so they can be found more easily. There is no * other functionality implied with this interface.

*/ public interface DeltaSpikeBaseConfig { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/DefaultErrorView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view; /** * Abstract class which marks an error view. * * It's an abstract class instead of an interface, because it can be used for navigation (which is restricted to * classes). */ public abstract class DefaultErrorView implements ViewConfig { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/ViewConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view; /** * Marker interface for type-safe view-config classes. Required for view-configs which represent a (logical) page and * optional for the rest (e.g. folder-configs). */ public interface ViewConfig { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/ViewRef.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view; import org.apache.deltaspike.core.api.literal.ViewControllerRefLiteral; import org.apache.deltaspike.core.api.config.view.metadata.InlineViewMetaData; import org.apache.deltaspike.core.spi.config.view.InlineMetaDataTransformer; import org.apache.deltaspike.core.spi.config.view.TargetViewConfigProvider; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Named; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * A reference to a view-config, applied on a view-controller. The opposite direction of {@link ViewControllerRef}. * * ViewRef annotation instances are not present at runtime as metadata, they are instead transformed to * ViewControllerRef instances during deployment. */ @Target({ TYPE, METHOD }) @Retention(RUNTIME) @Documented @InlineViewMetaData( targetViewConfigProvider = ViewRef.ViewRefTargetViewConfigProvider.class, inlineMetaDataTransformer = ViewRef.ViewRefInlineMetaDataTransformer.class) public @interface ViewRef { abstract class Manual implements ViewConfig { } /** * Specifies the views to bind to the view-controller. * * @return {@link ViewConfig}s of views bound to the view-controller */ @Nonbinding Class[] config(); class ViewRefTargetViewConfigProvider implements TargetViewConfigProvider { @Override public Class[] getTarget(ViewRef inlineMetaData) { return inlineMetaData.config(); } } class ViewRefInlineMetaDataTransformer implements InlineMetaDataTransformer { @Override public ViewControllerRef convertToViewMetaData(ViewRef inlineMetaData, Class sourceClass) { Named named = sourceClass.getAnnotation(Named.class); String beanName; if (named == null) { beanName = null; } else { beanName = named.value(); } return new ViewControllerRefLiteral(sourceClass, beanName); } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/controller/InitView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.controller; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Callback annotation for view-controllers. Methods annotated with this annotation will be invoked as soon as a view * has been initialized. */ @Target(METHOD) @Retention(RUNTIME) @Documented public @interface InitView { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/controller/PostRenderView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.controller; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Callback annotation for view-controllers. Methods annotated with this annotation will be invoked after the view gets * rendered. */ @Target(METHOD) @Retention(RUNTIME) @Documented public @interface PostRenderView { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/controller/PreRenderView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.controller; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Callback annotation for view-controllers. Methods annotated with this annotation will be invoked before the view gets * rendered. */ @Target(METHOD) @Retention(RUNTIME) @Documented public @interface PreRenderView { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/controller/PreViewAction.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.controller; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Callback annotation for view-controllers. Methods annotated with this annotation will be invoked before the method * binding gets invoked. Can be used as a callback in a view-controller in parallel with 3rd party flow-engines. */ @Target(METHOD) @Retention(RUNTIME) @Documented public @interface PreViewAction { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/controller/ViewControllerRef.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.controller; import org.apache.deltaspike.core.api.config.view.metadata.SimpleCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Specifies one or more view-controllers for the view-config which has this annotation applied. View-controllers can * handle callbacks like {@link InitView}, {@link PreRenderView}, etc. */ //don't use @Inherited @Target(TYPE) @Retention(RUNTIME) @Documented @ViewMetaData(preProcessor = ViewControllerRef.AnnotationPreProcessor.class) public @interface ViewControllerRef { /** * Class of the view-controller. * * @return class of the view-controller */ Class value(); /** * Currently not implemented. * Optional name of the view-controller. * * @return name of the view-controller */ //TODO String name() default ""; class AnnotationPreProcessor implements ConfigPreProcessor { @Override public ViewControllerRef beforeAddToConfig(ViewControllerRef metaData, ViewConfigNode viewConfigNode) { viewConfigNode.registerCallbackDescriptors( ViewControllerRef.class, new Descriptor(metaData.value(), InitView.class)); viewConfigNode.registerCallbackDescriptors( ViewControllerRef.class, new Descriptor(metaData.value(), PreViewAction.class)); viewConfigNode.registerCallbackDescriptors( ViewControllerRef.class, new Descriptor(metaData.value(), PreRenderView.class)); viewConfigNode.registerCallbackDescriptors( ViewControllerRef.class, new Descriptor(metaData.value(), PostRenderView.class)); return metaData; //no change needed } } //not needed outside class Descriptor extends SimpleCallbackDescriptor { protected Descriptor(Class beanClass, Class callbackType) { super(beanClass, callbackType); } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/Aggregated.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Marks view-metadata annotations or their fields as aggregated metadata. That results in retention of multiple * instances of such annotation per view instead of the metadata getting overriden by lower levels. * * Core just provides this annotation, but the concrete behaviour is defined by a concrete ConfigNodeConverter. E.g. * DefaultConfigNodeConverter uses the result stored in * {@link org.apache.deltaspike.core.spi.config.view.ViewConfigNode#getInheritedMetaData} to replace default- (/ null-) * values of "higher" levels with custom values of "lower" levels, if #value is 'true'. */ //TODO re-visit and discuss method-level (for annotation-attributes) @Target({ ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented public @interface Aggregated { /** * @return false to override the same metadata type of the parent view-config, and true to allow multiple instances * of a metadata per view */ boolean value(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/CallbackDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.api.provider.BeanProvider; import jakarta.inject.Named; import java.beans.Introspector; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Basic descriptor for a given class and callback type. It finds and caches the method(s) of the given class which are * annotated with the given callback-type. */ public abstract class CallbackDescriptor { protected List callbacks = new ArrayList(); protected Class callbackType; protected CallbackDescriptor(Class beanClass, Class callbackMarker) { init(new Class[]{beanClass}, callbackMarker); } protected CallbackDescriptor(Class[] beanClasses, Class callbackMarker) { init(beanClasses, callbackMarker); } protected void init(Class[] targetBeanClasses, Class callbackMarker) { if (callbackMarker == null) { callbackMarker = DefaultCallback.class; } this.callbackType = callbackMarker; //TODO discuss how deep we should scan for (Class targetBeanClass : targetBeanClasses) { CallbackEntry callbackEntry = new CallbackEntry(targetBeanClass, callbackMarker); if (!callbackEntry.callbackMethods.isEmpty()) { this.callbacks.add(callbackEntry); } } } public Map, List> getCallbackMethods() { Map, List> result = new HashMap, List>(this.callbacks.size()); for (CallbackEntry callbackEntry : this.callbacks) { result.put(callbackEntry.targetBeanClass, new ArrayList(callbackEntry.callbackMethods)); } return result; } protected T getTargetObject(Class targetType) { return BeanProvider.getContextualReference(targetType, true); } protected Object getTargetObjectByName(String beanName) { return BeanProvider.getContextualReference(beanName, true); } public boolean isBoundTo(Class callbackType) { return this.callbackType.equals(callbackType); } protected static class CallbackEntry { private List callbackMethods = new ArrayList(); private final Class targetBeanClass; private final String beanName; private CallbackEntry(Class beanClass, Class callbackMarker) { this.targetBeanClass = beanClass; Named named = this.targetBeanClass.getAnnotation(Named.class); if (named != null && !"".equals(named.value())) { this.beanName = named.value(); } else { //fallback to the default (which might exist) -> TODO check meta-data of Bean this.beanName = Introspector.decapitalize(targetBeanClass.getSimpleName()); } List processedMethodNames = new ArrayList(); findMethodWithCallbackMarker(callbackMarker, beanClass, processedMethodNames); } private void findMethodWithCallbackMarker(Class callbackMarker, Class classToAnalyze, List processedMethodNames) { Class currentClass = classToAnalyze; while (currentClass != null && !Object.class.getName().equals(currentClass.getName())) { for (Method currentMethod : currentClass.getDeclaredMethods()) { //don't process overridden methods //ds now allows callbacks with parameters -> TODO refactor this approach if (processedMethodNames.contains(currentMethod.getName())) { continue; } if (currentMethod.isAnnotationPresent(callbackMarker)) { processedMethodNames.add(currentMethod.getName()); if (Modifier.isPrivate(currentMethod.getModifiers())) { throw new IllegalStateException( "Private methods aren't supported to avoid side-effects with normal-scoped CDI beans." + " Please use e.g. protected or public instead. "); } currentMethod.setAccessible(true); this.callbackMethods.add(currentMethod); } } //scan interfaces for (Class interfaceClass : currentClass.getInterfaces()) { findMethodWithCallbackMarker(callbackMarker, interfaceClass, processedMethodNames); } currentClass = currentClass.getSuperclass(); } } public List getCallbackMethods() { return callbackMethods; } public Class getTargetBeanClass() { return targetBeanClass; } public String getBeanName() { return beanName; } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/ConfigDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import java.lang.annotation.Annotation; import java.util.List; /** * Base descriptor for all type-safe view-configs which describes the config class, metadata, callbacks and other * properties of a view-config. * * @param class of the view-config */ public interface ConfigDescriptor { Class getConfigClass(); /** * Metadata configured for this view-config. Resolves {@link ViewMetaData}-annotated annotations which are inherited * or directly present on the view-config class. * * @return metadata of this view-config */ List getMetaData(); /** * Metadata which is configured for this view-config. Resolves {@link ViewMetaData}-annotated annotations which are * inherited or directly present on the view-config class. * * @param target target type * * @return custom metadata for the given type of this view-config */ List getMetaData(Class target); /** * Callbacks which are configured for this view-config and bound to the given metadata type. * * @param metaDataType type of the metadata (e.g. ViewControllerRef.class) * * @return descriptor for the callback or null if there is no callback method */ CallbackDescriptor getCallbackDescriptor(Class metaDataType); /** * Callbacks which are configured for this view-config and bound to the given metadata type. * * @param metaDataType type of the metadata (e.g. ViewControllerRef.class) * @param callbackType type of the callback (e.g. PreRenderView.class) * * @return descriptor for the callback null if there is no callback-method */ CallbackDescriptor getCallbackDescriptor(Class metaDataType, Class callbackType); /** * Callbacks which are configured for this view-config and bound to the given metadata type. * * @param metaDataType type of the metadata (e.g. ViewControllerRef.class) * @param executorType type of the executor which returns a typed result (e.g. Secured.Descriptor) * * @return executable descriptor for the callback or null if there is no callback method */ @SuppressWarnings("rawtypes") //TODO > when major version is incremented T getExecutableCallbackDescriptor(Class metaDataType, Class executorType); /** * Callbacks which are configured for this view-config and bound to the given metadata type. * * @param metaDataType type of the metadata (e.g. ViewControllerRef.class) * @param callbackType type of the callback (e.g. PreRenderView.class) * @param executorType type of the executor which returns a typed result (e.g. Secured.Descriptor) * * @return executable descriptor for the callback or null if there is no callback method */ @SuppressWarnings("rawtypes") //TODO > when major version is incremented T getExecutableCallbackDescriptor(Class metaDataType, Class callbackType, Class executorType); /** * Returns the string representation of the resource (page, folder) represented by this view-config. * * @return relative path to the folder or page */ String getPath(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/DefaultCallback.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * A ConfigDescriptor can contain CallbackDescriptors or ExecutableCallbackDescriptors. An ExecutableCallbackDescriptor * can reference one or more callback method(s). If there is only one callback type, it's possible to annotate it with * {@code @DefaultCallback}. That eliminates the need for a special marker annotation for the target method. * * If there are multiple callback types, it's necessary to use custom annotations as marker for the target method (e.g. * see {@code @Secured} vs. {@code @ViewControllerRef}). * *
 * {@code
 * ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SomePage.class);
 *
 * viewConfigDescriptor.getExecutableCallbackDescriptor(
 *   Secured.class, Secured.Descriptor.class).execute(accessDecisionVoterContext);
 * }
is short for *
 * {@code
 * viewConfigDescriptor.getExecutableCallbackDescriptor(
 *   Secured.class, DefaultCallback.class, Secured.Descriptor.class).execute(accessDecisionVoterContext);
 * }
* * whereas e.g. *
 * {@code
 * viewConfigDescriptor.getExecutableCallbackDescriptor(
 *   ViewControllerRef.class, PreRenderView.class, ViewControllerRef.Descriptor.class).execute();
 * }
or just *
 * {@code
 * viewConfigDescriptor.getExecutableCallbackDescriptor(
 *   ViewControllerRef.class, PreRenderView.class, SimpleCallbackDescriptor.class).execute();
 * }
are needed to call @PreRenderView callbacks specifically (instead of the others like @InitView which are also * bound to @ViewControllerRef). */ //TODO find a better name @Target( METHOD ) @Retention(RUNTIME) @Documented public @interface DefaultCallback { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/ExecutableCallbackDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.util.ExceptionUtils; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; /** * Specialized {@link CallbackDescriptor} which provides {@link #execute} only for concrete descriptors, but doesn't * expose it (and can't get used by accident). Concrete implementations can provide type-safe versions of it, but * delegate the final execution to {@link #execute}. * * @param return type */ public abstract class ExecutableCallbackDescriptor extends CallbackDescriptor { protected ExecutableCallbackDescriptor(Class beanClass, Class callbackMarker) { super(beanClass, callbackMarker); } protected ExecutableCallbackDescriptor(Class[] beanClasses, Class callbackMarker) { super(beanClasses, callbackMarker); } protected List execute(Object... parameters) { List results = new ArrayList(); for (CallbackEntry callbackEntry : this.callbacks) { for (Method callbackMethod : callbackEntry.getCallbackMethods()) { try { Class targetBeanClass = callbackEntry.getTargetBeanClass(); Object bean = getTargetObject(targetBeanClass); if (bean == null) { String beanName = callbackEntry.getBeanName(); bean = getTargetObjectByName(beanName); if (bean == null) { throw new IllegalStateException("Can't find bean by type " + targetBeanClass + " or by name: " + beanName); } } @SuppressWarnings("unchecked") R result = (R) callbackMethod.invoke(bean, parameters); if (result != null) { results.add(result); } } catch (Exception e) { if (e instanceof InvocationTargetException) { ExceptionUtils.throwAsRuntimeException(e.getCause()); } ExceptionUtils.throwAsRuntimeException(e); } } } return results; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/InlineViewMetaData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.spi.config.view.InlineMetaDataTransformer; import org.apache.deltaspike.core.spi.config.view.TargetViewConfigProvider; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Provides the ability to apply metadata to a view-config "remotely" – from a * different place than the view-config itself (and with different syntax and a different annotation). * *

* For example, the @ViewControllerRef (main) vs. @ViewRef (inline) – the @ViewControllerRef is applied * directly on a view-config and references a view-controller, but there's also @ViewRef, which has the same purpose, * but is applied in reverse – on a view-controller, referencing a view-config. *

*/ @Target({ ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented public @interface InlineViewMetaData { Class> targetViewConfigProvider(); @SuppressWarnings("rawtypes") Class inlineMetaDataTransformer() default InlineMetaDataTransformer.class; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/SimpleCallbackDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import java.lang.annotation.Annotation; import java.util.List; /** * {@link ExecutableCallbackDescriptor} for simple callback methods without (supported) parameters, which exposes * #execute without parameters. * * @param return type */ public abstract class SimpleCallbackDescriptor extends ExecutableCallbackDescriptor { protected SimpleCallbackDescriptor(Class beanClass, Class callbackMarker) { super(beanClass, callbackMarker); } protected SimpleCallbackDescriptor(Class[] beanClasses, Class callbackMarker) { super(beanClasses, callbackMarker); } public List execute() { return super.execute(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/SkipMetaDataMerge.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Disables metadata merging on attributes of @ViewMetaData annotations. Used in cases (e.g. @Folder#name) where it * doesn't make sense to merge that part with inherited information. */ @Target( METHOD ) @Retention(RUNTIME) @Documented public @interface SkipMetaDataMerge { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/ViewConfigDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.api.config.view.ViewConfig; /** * Descriptor which represents a concrete view (page). */ public interface ViewConfigDescriptor extends ConfigDescriptor { /** * View ID of the current descriptor. The default implementation returns the same as ConfigDescriptor#getPath. For * the default implementation (and default integration with JSF) it's in place to provide a straightforward API. * However, e.g. an integration for a different view technology can use it e.g. for a logical id. * * @return current view ID */ String getViewId(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/ViewConfigResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.api.config.view.ViewConfig; import java.util.List; /** * Resolver of view-configs. * * A {@link ConfigDescriptor} can be bound to any config class (without required base type). That's needed e.g. for * folder-configs. Whereas {@link ViewConfigDescriptor}s only represent classes which inherit from {@link ViewConfig} * which is required for all view-configs. * * Use {@link org.apache.deltaspike.core.spi.config.view.ViewConfigRoot} to register a custom resolver. */ //TODO re-visit name since we also need ConfigDescriptor public interface ViewConfigResolver { ConfigDescriptor getConfigDescriptor(String path); /** * Resolves the {@link ConfigDescriptor} for the given class. * * @param configClass config class which usually represents a folder node * * @return config descriptor which represents the given config class */ ConfigDescriptor getConfigDescriptor(Class configClass); //TODO re-visit name (depends on other discussions) /** * Resolves all descriptors for folders. * * @return all descriptors for the known folder-configs */ List> getConfigDescriptors(); /** * Resolves the {@link ViewConfigDescriptor} for the given view-id. * * @param viewId view-id of the page * * @return view-config descriptor which represents the given view-id, null otherwise */ ViewConfigDescriptor getViewConfigDescriptor(String viewId); /** * Resolves the {@link ViewConfigDescriptor} for the given view-config class. * * @param viewDefinitionClass view-config class of the page * * @return view-config descriptor which represents the given view-config class */ ViewConfigDescriptor getViewConfigDescriptor(Class viewDefinitionClass); /** * Resolves all descriptors for the known {@link ViewConfig}s. * * @return all descriptors for the known view-configs */ List getViewConfigDescriptors(); /** * Resolves the descriptor for the default error page. * * @return descriptor for the default error page */ ViewConfigDescriptor getDefaultErrorViewConfigDescriptor(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/metadata/ViewMetaData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.metadata; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Meta-annotation for custom metadata which can be applied to view-configs. * * By default, metadata of a lower level overrides metadata of the same type from a higher level (cascading behaviour). * This behaviour can be changed by annotating the target annotation (or only chosen fields of it) with * {@code @Aggregated(true)}. */ @Target({ ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @Aggregated(false) public @interface ViewMetaData { @SuppressWarnings("rawtypes") Class preProcessor() default ConfigPreProcessor.class; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/navigation/NavigationParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.navigation; import org.apache.deltaspike.core.api.config.view.metadata.Aggregated; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Used on JSF action methods, this adds navigation parameters (key-value pairs) to the resulting navigation string. * Alternatively, {@link org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext} can be used * to add the parameters. */ @Target({ METHOD, TYPE }) @Retention(RUNTIME) @Documented @ViewMetaData @Aggregated(true) @InterceptorBinding public @interface NavigationParameter { /** * Key of the parameter. * * @return name of the key */ @Nonbinding String key(); /** * Value of the parameter, a plain String or an EL expression. * * @return ref or expression */ @Nonbinding String value(); @Target({ METHOD, TYPE }) @Retention(RUNTIME) @Documented //TODO add special support for list-annotations (add value automatically) /** * A container for multiple NavigationParameters. */ @ViewMetaData @Aggregated(true) @InterceptorBinding public static @interface List { /** * One or more navigation parameters. * * @return parameters */ @Nonbinding NavigationParameter[] value(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/navigation/NavigationParameterContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.navigation; import java.io.Serializable; import java.util.Map; /** * Can be used to add parameters dynamically to the final navigation string. */ public interface NavigationParameterContext extends Serializable { void addPageParameter(String key, Object value); Map getPageParameters(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/navigation/ViewNavigationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.navigation; import org.apache.deltaspike.core.api.config.view.ViewConfig; /** * A type-safe {@link ViewConfig}-based NavigationHandler wrapper. */ public interface ViewNavigationHandler { /** * Triggers navigation to the given view. * * @param targetView the navigation target */ void navigateTo(Class targetView); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/view/navigation/event/PreViewConfigNavigateEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.config.view.navigation.event; import org.apache.deltaspike.core.api.config.view.ViewConfig; /** * This event is fired before a navigation from/to a view-config-based page occurs. With {@link #navigateTo(Class)} it's * possible to change the navigation target. */ public class PreViewConfigNavigateEvent { private final Class fromView; private Class toView; /** * Constructor for creating the event for the given source and target view. * * @param fromView source-view * @param toView target-view */ public PreViewConfigNavigateEvent(Class fromView, Class toView) { this.fromView = fromView; this.toView = toView; } /** * Provides the navigation source. * * @return source of the navigation */ public Class getFromView() { return fromView; } /** * Provides the navigation target. * * @return target of the navigation */ public Class getToView() { return toView; } /** * Changes the navigation target. * * @param toView new navigation target */ public void navigateTo(Class toView) { this.toView = toView; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/crypto/CipherService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.crypto; import java.io.IOException; /** * handle Encryption */ public interface CipherService { /** * Store a hash based on the given masterpassword and masterSalt in * ~/.deltaspike/master.hash * * @param masterPassword * @param masterSalt same masterSalt as later used by the application to decrypt the hash * @param overwrite whether an existing passkey file does not get overwritten. * * @return {@code true} if the master hash got successfully written * @throws IOException if the master hash file could not be written * @throws IllegalStateException if a masterhash already exists */ void setMasterHash(String masterPassword, String masterSalt, boolean overwrite) throws IOException; /** * Encrypt the given cleartext. * We use the masterSalt to access the MasterHash to use as key for encryption * * @param cleartext to get encrypted * @param masterSalt the same as used for {@link #setMasterHash(String, String, boolean)} * @return the encrypted String to store somewhere */ String encrypt(String cleartext, String masterSalt); /** * Decrypt the given encrypted value. * We use the masterSalt to access the MasterHash to use as key for encryption * * @param encryptedValue to get decrypted * @param masterSalt the same as used for {@link #setMasterHash(String, String, boolean)} * @return the decrypted plaintext */ String decrypt(String encryptedValue, String masterSalt); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/exclude/Exclude.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.exclude; import org.apache.deltaspike.core.api.interpreter.ExpressionInterpreter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Supported usages: *
 * @Exclude
 * @Exclude(ifProjectStage=Production.class)
 * @Exclude(exceptIfProjectStage=UnitTest.class)
 * @Exclude(onExpression="myProperty==myValue")
 * @Exclude(onExpression="[my custom expression syntax]", interpretedBy=CustomExpressionInterpreter.class)
 * 
* * Examples: *
*
    *
  • * The following bean gets excluded in any case *
     * @Exclude
     * public class NoBean {}
     * 
    *
  • * *
  • * The following bean gets excluded when the ProjectStage is 'Development' *
     * @Exclude(ifProjectStage = ProjectStage.Development.class)
     * public class ProductionBean {}
     * 
    *
  • * *
  • * The following bean gets excluded in every case except when then ProjectStage is 'Development' *
     * @Exclude(exceptIfProjectStage = ProjectStage.Development.class)
     * public class DevBean {}
     * 
    *
  • * *
  • * The following bean gets excluded if the expression evaluates to true, which means there is a configured property * called 'myProperty' with the value 'myValue' *
     * @Exclude(onExpression="myProperty==myValue")
     * public class ProductionBean {}
     * 
    *
  • * *
  • The following bean gets excluded if the expression evaluates to true *
     * @Exclude(onExpression="[my custom expression syntax]", interpretedBy=CustomExpressionInterpreter.class)
     * public class ProductionBean {}
     * 
    *
  • *
*/ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE }) public @interface Exclude { /** * The {@link org.apache.deltaspike.core.api.projectstage.ProjectStage}s which lead to deactivating this bean. If * the current ProjectStage is in this list, the bean will get vetoed. * * @return 1-n project-stages which are not allowed for the annotated artifact */ Class[] ifProjectStage() default { }; /** * The {@link org.apache.deltaspike.core.api.projectstage.ProjectStage}s which lead to activating this bean. If the * current ProjectStage is not in this list, the bean will get vetoed. * * @return 1-n project-stages which are allowed for the annotated artifact */ Class[] exceptIfProjectStage() default { }; /** * Expression which signals if the annotated bean should be deactivated or not. * * @return expression-string which will be interpreted */ String onExpression() default ""; /** * @return class of the interpreter which should be used (default leads to a simple config-property interpreter) */ @SuppressWarnings("rawtypes") Class interpretedBy() default ExpressionInterpreter.class; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/future/Futureable.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.future; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Mark the method as execute in a thread pool and not synchronously. * Note: it should return a CompletionStage, Future or void. */ @InterceptorBinding @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Futureable { /** * @return pool name, if not existing will use a default one based on processor count. */ @Nonbinding String value() default ""; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/interpreter/BasePropertyExpressionInterpreter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.interpreter; /** * Base implementation for simple (property) expressions. * * Supported operations:

*

    *
  • [key]==[value]
  • *
  • [key]!=[value]
  • *
  • [key]==* (a value is required)
  • *
  • ; (separator)
  • *
*/ public abstract class BasePropertyExpressionInterpreter implements ExpressionInterpreter { private static final String ASTERISK = "*"; @Override public final Boolean evaluate(String expressions) { boolean result = false; String[] foundExpressions = expressions.split(";"); SimpleOperationEnum operation; for (String expression : foundExpressions) { result = false; if (expression.contains(SimpleOperationEnum.IS.getValue())) { operation = SimpleOperationEnum.IS; } else if (expression.contains(SimpleOperationEnum.NOT.getValue())) { operation = SimpleOperationEnum.NOT; } else { throw new IllegalStateException("expression: " + expression + " isn't supported by " + getClass().getName() + " supported operations: " + SimpleOperationEnum.getOperations() + "separator: ';'"); } String[] keyValue = expression.split(operation.getValue()); String configuredValue = getConfiguredValue(keyValue[0]); if (configuredValue != null) { configuredValue = configuredValue.trim(); } else { configuredValue = ""; } if (!ASTERISK.equals(keyValue[1]) && "".equals(configuredValue)) { continue; } if (ASTERISK.equals(keyValue[1]) && !"".equals(configuredValue)) { result = true; continue; } if (SimpleOperationEnum.IS.equals(operation) && !keyValue[1].equalsIgnoreCase(configuredValue)) { return false; } else if (SimpleOperationEnum.NOT.equals(operation) && keyValue[1].equalsIgnoreCase(configuredValue)) { return false; } result = true; } return result; } protected abstract String getConfiguredValue(String key); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/interpreter/ExpressionInterpreter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.interpreter; /** * Generic interface for evaluation of expressions, like the ones provided by * {@link org.apache.deltaspike.core.api.exclude.Exclude#onExpression()}. * * @param expression type * @param result type */ public interface ExpressionInterpreter { /** * Evaluates the given expression and returns the result for it. * * @param expression expression to evaluate * * @return result of the evaluated expression */ R evaluate(E expression); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/interpreter/SimpleOperationEnum.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.interpreter; /** * Operations supported by {@link BasePropertyExpressionInterpreter}. */ enum SimpleOperationEnum { IS("=="), NOT("!="); private final String value; SimpleOperationEnum(String value) { this.value = value; } String getValue() { return value; } static String getOperations() { StringBuilder operations = new StringBuilder(); for (SimpleOperationEnum operation : SimpleOperationEnum.values()) { operations.append(operation); operations.append(" "); } return operations.toString(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import javax.management.Notification; /** * Interface used to send JMX message from "CDI MBeans". It can only be used from CDI MBeans and should get injected in * other beans. */ public interface JmxBroadcaster { /** * @param notification the notification to send from the current MBean. */ void send(Notification notification); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxManaged.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Describes a JMX operation or attribute, when used on a method or a field, respectively. *

* Used on a method it describes a JMX operation with an optional description. * An exception thrown by the method will be wrapped in a {@link javax.management.MBeanException} * unless it already is a {@code MBeanException}. *

* Used on a field it describes a JMX attribute. This attribute is readable if a getter on this field is available and * writable if a setter is found. */ @Retention(RUNTIME) @Target({ FIELD, METHOD }) @Documented public @interface JmxManaged { /** * @return the description either of the operation or the attribute exported through JMX. */ String description() default ""; /** * @return if {@code true} a Map or Table will be converted to a TabularData with a CompositeData entry, * if {@code false} the Map or Table will be returned directly. */ boolean convertToTabularData() default true; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/JmxParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Describes a parameter of a JMX operation. */ @Retention(RUNTIME) @Target(PARAMETER) @Documented public @interface JmxParameter { /** * @return the description of the parameter. */ String description() default ""; /** * @return the name of the parameter. */ String name() default ""; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/MBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * This annotation marks a CDI managed bean as exported through JMX. */ @Stereotype @Retention(RUNTIME) @Target(TYPE) @Inherited public @interface MBean { /** * @return the category to use if no objectName was specified. Default is "org.apache.deltaspike" and can be * overriden either directly by the value or by a key used to resolve a value using * {@link org.apache.deltaspike.core.api.config.ConfigResolver}. It is a key if the value is between * brackets. Default key is "org.apache.deltaspike.mbean.category". */ String category() default "{org.apache.deltaspike.mbean.category}"; /** * @return the name of the bean used if no objectName was specified. It is used with category value to create the * MBean {@link javax.management.ObjectName} using the following pattern: * <category>:type=MBeans,name=<name> */ String name() default ""; /** * @return the properties part of the objectName if no objectName was specified. * If name and type are specified this segment is concatenated after. */ String properties() default ""; /** * @return the type to use if no objectName was specified. Default is

MBeans
and can be * overriden either directly by the value or by a key used to resolve a value using * {@link org.apache.deltaspike.core.api.config.ConfigResolver}. It is a key if the value is between * brackets. */ String type() default ""; /** * @return the direct object name used to export the decorated bean. */ String objectName() default ""; /** * @return the description used to describe the JMX bean. */ String description() default ""; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/NotificationInfo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import javax.management.Notification; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Documented @Target(TYPE) @Retention(RUNTIME) public @interface NotificationInfo { String[] types() default { }; String description() default ""; Class notificationClass() default Notification.class; String[] descriptorFields() default { }; @Target(TYPE) @Retention(RUNTIME) static @interface List { NotificationInfo[] value(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/jmx/Table.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.jmx; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import static java.util.Arrays.asList; /** * Allows to expose in JMX a STRING TabularData without having to built it in the MBean. * * Ensure to register columns before the lines. * * You just have to type the operation or attribute with this type to expose it as a TabularData. */ public class Table { private Collection columns = new ArrayList(); private Collection> values = new ArrayList>(); public Table withColumns(final Collection names) { columns.addAll(names); return this; } public Table withColumns(final String... names) { columns.addAll(asList(names)); return this; } public Table withLines(final Collection> lines) { for (final Collection line : lines) { withLine(line); } return this; } public Table withLine(final Collection line) { if (line.size() != columns.size()) { throw new IllegalArgumentException("Please set columns before lines"); } values.add(line); return this; } public Table withLine(final String... line) { if (line.length != columns.size()) { throw new IllegalArgumentException("Please set columns before lines"); } values.add(asList(line)); return this; } public Collection getColumnNames() { return Collections.unmodifiableCollection(columns); } public Collection> getLines() { return Collections.unmodifiableCollection(values); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageBundleLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import jakarta.enterprise.util.AnnotationLiteral; import org.apache.deltaspike.core.api.message.MessageBundle; /** * Literal for {@link MessageBundle} */ public class MessageBundleLiteral extends AnnotationLiteral implements MessageBundle { private static final long serialVersionUID = 5116646785333766333L; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/MessageContextConfigLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import org.apache.deltaspike.core.api.message.LocaleResolver; import org.apache.deltaspike.core.api.message.MessageContextConfig; import org.apache.deltaspike.core.api.message.MessageInterpolator; import org.apache.deltaspike.core.api.message.MessageResolver; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link org.apache.deltaspike.core.api.message.MessageContextConfig} */ public class MessageContextConfigLiteral extends AnnotationLiteral implements MessageContextConfig { private static final long serialVersionUID = -5888417869986174834L; private final Class messageResolver; private final Class messageInterpolator; private final Class localeResolver; private final String[] messageSource; public MessageContextConfigLiteral() { this(MessageResolver.class, MessageInterpolator.class, LocaleResolver.class, new String[0]); } public MessageContextConfigLiteral(Class messageResolver, Class messageInterpolator, Class localeResolver, String[] messageSource) { this.messageResolver = messageResolver; this.messageInterpolator = messageInterpolator; this.localeResolver = localeResolver; this.messageSource = messageSource; } @Override public String[] messageSource() { return messageSource; } @Override public Class messageResolver() { return messageResolver; } @Override public Class messageInterpolator() { return messageInterpolator; } @Override public Class localeResolver() { return localeResolver; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/literal/ViewControllerRefLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.literal; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef} */ public class ViewControllerRefLiteral extends AnnotationLiteral implements ViewControllerRef { private static final long serialVersionUID = 8582580975876369665L; private final Class value; private final String name; public ViewControllerRefLiteral(Class value, String name) { this.value = value; this.name = name; } @Override public Class value() { return this.value; } @Override public String name() { return this.name; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/lock/Locked.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.lock; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReadWriteLock; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * The access to the method is protected by a read/write lock. */ @InterceptorBinding @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Locked { /** * @return if the lock is fair. */ @Nonbinding boolean fair() default false; /** * @return the operation used on the lock, default to read but you can use write. */ @Nonbinding Operation operation() default Operation.READ; /** * @return how to retrieve the lock for this method. Default uses a lock per class. */ @Nonbinding Class factory() default LockFactory.class; /** * @return the access timeout for this method. Ignored by default since it is 0. */ @Nonbinding long timeout() default 0L; /** * @return the timeout unit (default ms). */ @Nonbinding TimeUnit timeoutUnit() default TimeUnit.MILLISECONDS; enum Operation { READ, WRITE } /** * Provide a way to switch the ReadWriteLock implementation for @Locked. */ interface LockFactory { /** * @param method the intercepted method. * @param fair is the lock fair. * @return a read/write lock used for @Locked implementation. */ ReadWriteLock newLock(AnnotatedMethod method, boolean fair); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/LocaleResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.io.Serializable; import java.util.Locale; import org.apache.deltaspike.core.api.config.DeltaSpikeConfig; /** * Provides the current {@link java.util.Locale}. * *

* DeltaSpike provides a default implementation which returns the current system Locale.

*

* An application can provide custom implementation as an @Alternative. This could e.g. examine a JSF View or the * Locale of any currently logged in User.

*/ public interface LocaleResolver extends Serializable, DeltaSpikeConfig { /** * @return the current locale */ Locale getLocale(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/Message.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.io.Serializable; import java.util.Collection; /** * Basic interface for all messages. * *

* A Message is not a simple String but all the information needed to create those Strings for multiple * situations. The situation is determined by the used {@link MessageContext}.

*/ public interface Message extends Serializable { /** * @param messageTemplate message key (or plain text) for the current message * * @return the current instance of the message builder to allow a fluent API */ Message template(String messageTemplate); /** * @param arguments numbered and/or named argument(s) for the current message * * @return the current instance of the message builder to allow a fluent API */ Message argument(Serializable... arguments); /** * Argument array. Similar to argument except it is meant to handle an array being passed in via a chain. * * @param arguments the arguments * * @return the message */ Message argumentArray(Serializable[] arguments); /** * Argument. Similar to the other argument methods, this one handles collections. * * @param arguments the arguments * * @return the message */ Message argument(Collection arguments); /** * @return the message key (or plain text) of the current message */ String getTemplate(); /** * @return all named and numbered arguments */ Object[] getArguments(); /** * Renders the Message to a String, using the {@link MessageContext} which created the Message. */ String toString(); /** * Renders the Message to a String, using an arbitrary {@link MessageContext}. */ String toString(MessageContext messageContext); /** * Renders the Message to a String, using the {@link MessageContext} which created the Message. While resolving the * message we will first search for a messageTemplate with the given category by just adding an underscore '_' and * the category String to the {@link #getTemplate()}. If no such template exists we will fall back to the version * without the category String. *

* DeltaSpike JSF messages e.g. distinguish between categories * {@code "summary"} and {@code "detail"} * to allow a short and a more detailed explanation in Error, Warn and Info popups at the same time. *

*/ String toString(String category); /** * Renders the Message to a String, using an arbitrary {@link MessageContext}. While resolving the message we will * first search for a messageTemplate with the given category by just adding an underscore '_' and the category * String to the {@link #getTemplate()}. If no such template exists we will fall back to the version without the * category String. */ String toString(MessageContext messageContext, String category); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageBundle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Marker annotation for a message-bundle interface which provides type-safe messages. * *

* This annotation must only be used on interfaces. If this annotation gets used on a concrete class, a deployment error * results!

* *

Type-safe Messages

*

* Each method on an interface annotated with @MessageBundle will form a type-safe message. The * message lookup key (resource bundle key) can either be defined by annotating those methods with * @{@link MessageTemplate}) or by convention. if no @{@link MessageTemplate} annotation is used on a method, * the case sensitive method name name will be used as resource key.

* *

Message Parameters

*

* The parameters of the declared methods will be automatically passed as message parameters to the * {@link org.apache.deltaspike.core.api.message.MessageResolver}. Please note that all passed parameters should be * {@link java.io.Serializable}. If a parameter is not Serializable, we will instead store the toString() * of the passed parameter.

* * *

Message Sources

*

* The {@link java.util.ResourceBundle} or other resource lookup source which might be used is determined by the * {@link org.apache.deltaspike.core.api.message.MessageResolver} in conjunction with * {@link org.apache.deltaspike.core.api.message.MessageContext#messageSource(String...)}. The fully qualified class * name of the interface annotated with @MessageBundle will automatically be registered as additional * messageSource for those messages.

*

* By default the Message Source is a resource bundle with the same name as the {@code @MessageBundle} * annotated interface, e.g. {@code com.acme.MyMessages_en.properties}. *

* *

* @MessageBundle can be combined with {@link MessageContextConfig} to further customize the * message resolution and processing. To use a different resourcebundle, e.g. * {@code somepath/myownmessages_en.properties} you might write: *

 * @MessageBundle
 * @MessageContextConfig(messageSource = "somepath/myownmessages")
 * 
* *

* *

* Debug hint: Set a breakpoint in MessageBundleInvocationHandler#invoke. This will get called for every * message bundle invocation.

*/ @Stereotype @Target({ TYPE }) @Retention(RUNTIME) @Documented public @interface MessageBundle { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.io.Serializable; import java.util.List; /** * Central context for handling dynamic messages. *
* Instances of this type are mutable but also {@link Cloneable}. If you need a new instance, then use * {@link Object#clone()}. */ public interface MessageContext extends LocaleResolver, Serializable, Cloneable { /** * Clones the current MessageContext. */ MessageContext clone(); /** * @return a message based on the current context modifiable via a fluent API */ Message message(); /** * Configures a message source instance for use by a {@link MessageResolver}. * * @param messageSource message source to add * * @return the instance of the current message context builder */ MessageContext messageSource(String... messageSource); /** * @param messageInterpolator a new message interpolator to be set * @return the instance of the current message context builder */ MessageContext messageInterpolator(MessageInterpolator messageInterpolator); /** * @param messageResolver a new message resolver to be set * @return the instance of the current message context builder */ MessageContext messageResolver(MessageResolver messageResolver); /** * @param localeResolver a new locale resolver to be set * @return the instance of the current message context builder */ MessageContext localeResolver(LocaleResolver localeResolver); /** * @return the current message interpolator */ MessageInterpolator getMessageInterpolator(); /** * @return the current message resolver */ MessageResolver getMessageResolver(); /** * @return the current locale resolver */ LocaleResolver getLocaleResolver(); /** * @return list of registered message sources */ List getMessageSources(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageContextConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Configures message resolution and processing of a {@link MessageBundle}. */ @Target({ TYPE }) @Retention(RUNTIME) @Documented public @interface MessageContextConfig { /** *

Additional message source.

* *

A message source is a lookup hint for the {@link MessageResolver}. For the default MessageResolver this is the * name of the {@link java.util.ResourceBundle}.

* *

Example: To use 2 additional ResourceBundles for the lookup, you can configure the MessageContextConfig like * this: *

     *  @MessageBundle
     *  @MessageContextConfig(messageSource = {"mycomp.ErrorMessages","mycomp.BusinessMessages"})
     *  public interface MyCompanyMessages {...
     * 
. *

* * @return classes of the message-sources */ String[] messageSource() default { }; /** * {@link MessageResolver} to use for resolution of message templates to message text. * * @return class of the {@link MessageResolver} bean or the default marker */ Class messageResolver() default MessageResolver.class; /** * {@link MessageInterpolator} to use for interpolation of placeholders in the resolved text. * * @return class of the {@link MessageInterpolator} bean or the default marker */ Class messageInterpolator() default MessageInterpolator.class; /** * {@link LocaleResolver} providing the locale for message template resolution. * * @return class of the {@link LocaleResolver} bean or the default marker */ Class localeResolver() default LocaleResolver.class; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageInterpolator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.io.Serializable; import java.util.Locale; import org.apache.deltaspike.core.api.config.DeltaSpikeConfig; /** * Implementations are responsible to replace placeholders in a message with the final value. * *

* An application can provide a custom implementation as @Alternative.

* *

* A simple implementation which uses the {@link String#format(java.util.Locale, String, Object...)} will be used by * default.

*/ public interface MessageInterpolator extends Serializable, DeltaSpikeConfig { /** * Replaces the arguments of the given message with the given arguments. * * @param messageText the message text which has to be interpolated * @param arguments a list of numbered and/or named arguments for the current message * @param locale to use for the formatting * * @return the final (interpolated) message text if it was possible to replace the parameters with the given * arguments, or the unmodified messageText otherwise */ String interpolate(String messageText, Serializable[] arguments, Locale locale); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.io.Serializable; /** * Implementations have to resolve the text stored for a given key in the message source they are aware of. * Implementations should always be @Dependent scoped! */ public interface MessageResolver extends Serializable { String MISSING_RESOURCE_MARKER = "???"; /** * * @param messageContext messageContext which should be used * @param messageTemplate the message key (or inline text) of the current message * @param category the category of the message, e.g. 'longText'. Can be null * * @return the final but not interpolated message text or null if an error happened or the resource * could not be resolved. */ String getMessage(MessageContext messageContext, String messageTemplate, String category); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/message/MessageTemplate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.message; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Provides the message (template) for type-safe messages. * *

* This only works on interfaces which are annotated with {@link MessageBundle}.

* *

* Depending on the {@link org.apache.deltaspike.core.api.message.MessageResolver} this message template value might be * used as key to lookup internationalized values from a {@link java.util.ResourceBundle}.

* *

* A MessageTemplate value which starts and ends with brackets '{', '}' will be interpreted as key for resolving from a * ResourceBundle or any other lookup mechanism determined by the * {@link org.apache.deltaspike.core.api.message.MessageResolver}. A small example: *

 * @MessageTemplate("{welcome_to}")
 * 
This will lookup a welcome_to = Hello to Aruba from the configured resource bundle. *

* *

* MessageTemplate values without '{', '}' bracelets will be directly used without resource lookup.

*/ @Target(METHOD) @Retention(RUNTIME) @Documented public @interface MessageTemplate { /** * The default format string of this message. * * @return the format string */ String value(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/monitoring/InvocationMonitored.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.monitoring; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Use this annotation to mark a bean as being monitored. * This will activate a CDI Interceptor which will track * all method invocations on that class and measure how * often they got invoked and how much time they consume. * * At the end of a request the final times will get sent out * as {@link MonitorResultEvent}. */ @Inherited @InterceptorBinding @Target( { ElementType.TYPE, ElementType.METHOD } ) @Retention(RetentionPolicy.RUNTIME) public @interface InvocationMonitored { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/monitoring/MonitorResultEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.monitoring; import jakarta.enterprise.inject.Vetoed; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * This class will be used as event to transport final monitor values * * @see InvocationMonitored */ @Vetoed public class MonitorResultEvent { private Map methodInvocations = new HashMap(); private Map classInvocations = new HashMap(); private Map methodDurations = new HashMap(); public MonitorResultEvent(Map methodInvocations, Map classInvocations, Map methodDurations) { this.methodInvocations = methodInvocations; this.classInvocations = classInvocations; this.methodDurations = methodDurations; } /** * @return Map with Counters for all method invocations * key = fully qualified method name (includes class) * value = AtomicInteger with invocation count value */ public Map getMethodInvocations() { return methodInvocations; } /** * @return Map with Counter for all class invocations * key = fully qualified class name * value = AtomicInteger with invocation count value */ public Map getClassInvocations() { return classInvocations; } /** * @return Map with duration for all method invocations * key = fully qualified method name (includes class) * value = AtomicLong with duration nanos */ public Map getMethodDurations() { return methodDurations; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/projectstage/ProjectStage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.projectstage; import org.apache.deltaspike.core.util.ServiceUtils; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; /** * This class is the base of all ProjectStages. A ProjectStage identifies the environment the application currently runs * in. It provides the same functionality as the JSF2 ProjectStage but has a few additional benefits: *
    *
  • it works for JSF 1.0, JSF 1.1 and JSF 1.2 applications
  • *
  • it works in pure backends and unit tests without any JSF API
  • *
  • it is dynamic. Everyone can add their own ProjectStages!
  • *
* *

* Technically this is kind of a 'dynamic enum'.

* *

* The following ProjectStages are provided by default:

*
    *
  • UnitTest
  • *
  • Development
  • *
  • SystemTest
  • *
  • IntegrationTest
  • *
  • Staging
  • *
  • Production
  • *
* *

* The following resolution mechanism is used to determine the current ProjectStage:

*
    *
  • TODO specify!
  • *
* *

* New ProjectStages can be added via the {@link java.util.ServiceLoader} mechanism. A class deriving from * {@link ProjectStage} must be provided and used for creating a single static instance of it.

* *

* Custom ProjectStages can be implemented by writing anonymous ProjectStage members into a registered * {@link ProjectStageHolder} as shown in the following example:

* *
 * package org.apache.deltaspike.test.core.api.projectstage;
 * public class TestProjectStages implements ProjectStageHolder {
 *     public static final class MyOwnProjectStage extends ProjectStage {};
 *     public static final MyOwnProjectStage MyOwnProjectStage = new MyOwnProjectStage();
 *
 *     public static final class MyOtherProjectStage extends ProjectStage {};
 *     public static final MyOtherProjectStage MyOtherProjectStage = new MyOtherProjectStage();
 * }
 * 
* *

* To activate those ProjectStages, you have to register the ProjectStageHolder class to get picked up via the * ServiceLoader mechanism. Simply create a file *

 * META-INF/services/org.apache.deltaspike.core.api.projectstage.ProjectStageHolder
 * 
which contains the fully qualified class name of custom ProjectStageHolder implementation: *
 * # this class now gets picked up by java.util.ServiceLoader
 * org.apache.deltaspike.test.core.api.projectstage.TestProjectStages
 * 
*

* *

* You can use your own ProjectStages exactly the same way as all the ones provided by the system: *

 * ProjectStage myOwnPs = ProjectStage.valueOf("MyOwnProjectStage");
 * if (myOwnPs.equals(MyOwnProjectStage.MyOwnProjectStage)) ...
 * 
*

* *

* Note: DeltaSpike will only find {@link ProjectStageHolder}s which are accessible by this very class. If you * deploy the deltaspike-core jar to a shared EAR classloader, it will e.g. not be able to register ProjectStages * defined in a web application's WEB-INF/classes directory! *

* */ @Vetoed public abstract class ProjectStage implements Serializable { private static final long serialVersionUID = -1210639662598734888L; /** * This map contains a static map with all registered projectStages. * * We don't need to use a ConcurrentHashMap because writing to it will * only be performed in the static initializer block which is guaranteed * to be atomic by the VM spec. */ private static Map projectStages = new HashMap(); /** * All the registered ProjectStage values. * We don't need to make this volatile because of the classloader guarantees of * the VM. */ private static ProjectStage[] values = null; /** * logger for the ProjectStage */ private static final Logger LOG = Logger.getLogger(ProjectStage.class.getName()); /** * The static initializer block will register all custom ProjectStages * by simply touching their classes due loading it with the. * {@link java.util.ServiceLoader}. */ static { List projectStageHolders = ServiceUtils.loadServiceImplementations(ProjectStageHolder.class); for (ProjectStageHolder projectStageHolder : projectStageHolders) { LOG.fine("registering ProjectStages from ProjectStageHolder " + projectStageHolder.getClass().getName()); } } /** the name of the ProjectStage*/ private String psName; /** * The protected constructor will register the given ProjectStage via its name. * The name is returned by the {@link #toString()} method of the ProjectStage. */ protected ProjectStage() { String projectStageClassName = getClass().getSimpleName(); psName = projectStageClassName; init(projectStageClassName, this); } /** * This function exists to prevent findbugs from complaining about * setting a static member from a non-static function. * * @param projectStageClassName name of the project-stage * @param projectStage instance of the project-stage */ private static void init(String projectStageClassName, ProjectStage projectStage) { if (!projectStages.containsKey(projectStageClassName)) { projectStages.put(projectStageClassName, projectStage); } else { throw new IllegalArgumentException("ProjectStage with name " + projectStageClassName + " already exists!"); } // we cannot do this in the static block since it's not really deterministic // when all ProjectStages got resolved. values = projectStages.values().toArray(new ProjectStage[ projectStages.size() ]); } /** * @param projectStageClassName the name of the ProjectStage * @return the ProjectStage which is identified by it's name */ public static ProjectStage valueOf(String projectStageClassName) { return projectStages.get(projectStageClassName); } /** * Exposes all registered {@link ProjectStage} implementations. * * @return provided and custom ProjectStage implementations */ public static ProjectStage[] values() { ProjectStage[] result = new ProjectStage[values.length]; System.arraycopy(values, 0, result, 0, values.length); return result; } /** * {@inheritDoc} */ @Override public String toString() { return psName; } // CHECKSTYLE:OFF /** * Project-stage for unit-tests */ @Vetoed public static final class UnitTest extends ProjectStage implements TestStage { private static final long serialVersionUID = -7910349894182034559L; } /** * Type-safe {@link ProjectStage} */ public static final UnitTest UnitTest = new UnitTest(); /** * Project-stage for development */ @Vetoed public static final class Development extends ProjectStage { private static final long serialVersionUID = 1977308277341527250L; } /** * Type-safe {@link ProjectStage} */ public static final Development Development = new Development(); /** * Project-stage for system-tests */ @Vetoed public static final class SystemTest extends ProjectStage implements TestStage { private static final long serialVersionUID = -7444003351466372539L; } /** * Type-safe {@link ProjectStage} */ public static final SystemTest SystemTest = new SystemTest(); /** * Project-stage for integration-tests */ @Vetoed public static final class IntegrationTest extends ProjectStage implements TestStage { private static final long serialVersionUID = 2034474361615347127L; } /** * Type-safe {@link ProjectStage} */ public static final IntegrationTest IntegrationTest = new IntegrationTest(); /** * Project-stage for staging */ @Vetoed public static final class Staging extends ProjectStage { private static final long serialVersionUID = -8426149532860809553L; } /** * Type-safe {@link ProjectStage} */ public static final Staging Staging = new Staging(); /** * Default project-stage for production */ @Vetoed public static final class Production extends ProjectStage { private static final long serialVersionUID = -4030601958667812084L; } /** * Type-safe {@link ProjectStage} */ public static final Production Production = new Production(); // CHECKSTYLE:ON } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/projectstage/ProjectStageHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.projectstage; /** * A marker interface for custom ProjectStage holders. A ProjectStage holder is a class which contains one or more * {@link ProjectStage}s. * *

* Any custom ProjectStageHolder must get registered via the {@link java.util.ServiceLoader} mechanism. Simply create a * file *

 *     META-INF/services/org.apache.deltaspike.core.api.projectstage.ProjectStageHolder
 * 
and write the fully qualified class name of your ProjectStageHolder into it. *

*/ public interface ProjectStageHolder { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/projectstage/TestStage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.projectstage; /** * Marker interface for {@link ProjectStage} implementations which are used for tests. E.g. used to enable logging in * all 'testing' ProjectStages. */ public interface TestStage { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/provider/BeanManagerProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.provider; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeShutdown; import jakarta.enterprise.inject.spi.CDI; import jakarta.enterprise.inject.spi.Extension; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.util.ClassUtils; /** * This class provides access to the {@link BeanManager} by registering the current {@link BeanManager} in an extension * and making it available via a singleton factory for the current application. * *

This is really handy when you need to access CDI functionality from places where no injection is available.

* *

If a simple but manual bean lookup is needed, it's easier to use the {@link BeanProvider}.

* *

As soon as an application shuts down, the reference to the {@link BeanManager} is removed.

* *

* Usage: *

 * BeanManager bm = BeanManagerProvider.getInstance().getBeanManager();
*

*

* Attention: This approach is intended for use in user code at runtime. If BeanManagerProvider is used during * Container boot (in an Extension), non-portable behaviour results. During bootstrapping, an Extension shall * @Inject BeanManager to get access to the underlying BeanManager (see e.g. {@link #cleanupFinalBeanManagers}). * This is the only way to guarantee that the right BeanManager is obtained in more complex Container scenarios.

*/ public class BeanManagerProvider implements Extension { private static final Logger LOG = Logger.getLogger(BeanManagerProvider.class.getName()); private static BeanManagerProvider bmpSingleton; /** * This data container is used for storing the BeanManager for each web application. This is needed in EAR or other * multi-webapp scenarios when the DeltaSpike classes (jars) are provided in a shared ClassLoader. */ private static class BeanManagerInfo { /** * The BeanManager picked up via Extension loading. */ private BeanManager loadTimeBm; /** * The final BeanManager. After the container did finally boot, we first try to resolve them from JNDI, and only * if we don't find any BM there we take the ones picked up at startup. */ private BeanManager finalBm; /** * Whether the CDI Application has finally booted. Please note that this is only a nearby value as there is no * reliable event for this status in EE6. */ private boolean booted; } /** * The BeanManagerInfo for the current ClassLoader. * *

Attention: This instance must only be used through the {@link #bmpSingleton} singleton!

*/ private volatile Map bmInfos = new ConcurrentHashMap<>(); /** * Indicates whether the {@link BeanManagerProvider} has been initialized. Usually it's not necessary to call this * method in application code. It's useful e.g. for other frameworks to check if DeltaSpike and the CDI container in * general have been started. * * @return true if the BeanManagerProvider is ready to be used */ public static boolean isActive() { // CDI#current delegation enabled, skip everything if (CoreBaseConfig.BeanManagerIntegration.DELEGATE_LOOKUP) { return bmpSingleton != null; } return bmpSingleton != null && bmpSingleton.bmInfos.containsKey(ClassUtils.getClassLoader(null)); } /** * Returns the current provider instance which provides access to the current {@link BeanManager}. * * @throws IllegalStateException if the {@link BeanManagerProvider} isn't ready to be used. That's the case if the * environment isn't configured properly and therefore the {@link AfterBeanDiscovery} * hasn't been called before this method gets called. * @return the singleton BeanManagerProvider */ public static BeanManagerProvider getInstance() { if (bmpSingleton == null) { throw new IllegalStateException("No " + BeanManagerProvider.class.getName() + " in place! " + "Please ensure that you configured the CDI implementation of your choice properly. " + "If your setup is correct, please clear all caches and compiled artifacts."); } return bmpSingleton; } /** * It doesn't really matter which of the system events is used to obtain the BeanManager, but * {@link AfterBeanDiscovery} has been chosen since it allows all events which occur after the * {@link AfterBeanDiscovery} to use the {@link BeanManagerProvider}. * * @param afterBeanDiscovery event which we don't actually use ;) * @param beanManager the BeanManager we store and make available. */ public void setBeanManager(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { setBeanManagerProvider(this); // CDI#current delegation enabled, skip everything if (CoreBaseConfig.BeanManagerIntegration.DELEGATE_LOOKUP && resolveBeanManagerViaStaticHelper() != null) { return; } BeanManagerInfo bmi = getBeanManagerInfo(ClassUtils.getClassLoader(null)); bmi.loadTimeBm = beanManager; } /** * The active {@link BeanManager} for the current application (current {@link ClassLoader}). This method will throw * an {@link IllegalStateException} if the BeanManager cannot be found. * * @return the current BeanManager, never null * * @throws IllegalStateException if the BeanManager cannot be found */ public BeanManager getBeanManager() { // CDI#current delegation enabled, skip everything if (CoreBaseConfig.BeanManagerIntegration.DELEGATE_LOOKUP) { BeanManager bm = resolveBeanManagerViaStaticHelper(); if (bm != null) { return bm; } } BeanManagerInfo bmi = getBeanManagerInfo(ClassUtils.getClassLoader(null)); if (!bmi.booted) { // This is a workaround for some containers with messed up EAR handling. // Those containers might boot up with the shared ear ClassLoader // and later run the WARs with their own child ClassLoaders. if (bmi.loadTimeBm == null) { BeanManagerInfo parentBmi = getParentBeanManagerInfo(ClassUtils.getClassLoader(null)); if (parentBmi != null) { bmi.loadTimeBm = parentBmi.loadTimeBm; } } } BeanManager result = bmi.finalBm; if (result == null) { synchronized (bmi) { result = bmi.finalBm; if (result == null) { // first we look for a BeanManager from JNDI result = resolveBeanManagerViaJndi(); if (result == null) { // if none found, we take the one we got from the Extension loading result = bmi.loadTimeBm; } if (result == null) { throw new IllegalStateException("Unable to find BeanManager. " + "Please ensure that you configured the CDI implementation of your choice properly."); } // store the resolved BeanManager in the result cache until #cleanupFinalBeanManagers gets called // -> afterwards the next call of #getBeanManager will trigger the final lookup bmi.finalBm = result; } } } return result; } /** * By cleaning the final BeanManager map after the deployment gets validated, premature loading of information from * JNDI is prevented in cases where the container might not be fully setup yet. * * This might happen if the BeanManagerProvider is used in an extension during CDI bootstrap. This should be * generally avoided. Instead, an injected BeanManager should be used in Extensions and propagated using setters. * * In EARs with multiple webapps, each WAR might get a different Extension. This depends on the container used. */ public void cleanupFinalBeanManagers(@Observes AfterDeploymentValidation adv) { // CDI#current delegation enabled, skip everything if (CoreBaseConfig.BeanManagerIntegration.DELEGATE_LOOKUP && resolveBeanManagerViaStaticHelper() != null) { return; } for (BeanManagerInfo bmi : bmpSingleton.bmInfos.values()) { bmi.finalBm = null; bmi.booted = true; /*possible issue with >weld< based servers: if #getBeanManager gets called in a custom AfterDeploymentValidation observer >after< this observer, the wrong bean-manager might get stored (not deterministic due to the unspecified order of observers). finally a bean-manager for a single bda will be stored and returned (which isn't the bm exposed via jndi).*/ } } /** * Cleanup on container shutdown. * * @param beforeShutdown CDI shutdown event */ public void cleanupStoredBeanManagerOnShutdown(@Observes BeforeShutdown beforeShutdown) { // CDI#current delegation enabled, skip everything if (CoreBaseConfig.BeanManagerIntegration.DELEGATE_LOOKUP) { return; } if (bmpSingleton == null) { // this happens if there has been a failure at startup return; } bmpSingleton.bmInfos.remove(ClassUtils.getClassLoader(null)); } /** * Get the BeanManager from the JNDI registry. * * @return current {@link BeanManager} which is provided via JNDI */ private BeanManager resolveBeanManagerViaJndi() { try { // this location is specified in JSR-299 and must be // supported in all certified EE environments return (BeanManager) new InitialContext().lookup("java:comp/BeanManager"); } catch (NamingException e) { //workaround didn't work -> return null return null; } } private BeanManager resolveBeanManagerViaStaticHelper() { try { return CDI.current().getBeanManager(); } catch (Throwable t) { LOG.log(Level.FINEST, "failed to delegate bean-manager lookup -> fallback to default.", t); return null; } } /** * Get or create the BeanManagerInfo for the given ClassLoader. */ private BeanManagerInfo getBeanManagerInfo(ClassLoader cl) { BeanManagerInfo bmi = bmpSingleton.bmInfos.get(cl); if (bmi == null) { synchronized (this) { bmi = bmpSingleton.bmInfos.get(cl); if (bmi == null) { bmi = new BeanManagerInfo(); bmpSingleton.bmInfos.put(cl, bmi); if (cl.getParent() != null && !bmpSingleton.bmInfos.containsKey(cl.getParent())) { bmpSingleton.bmInfos.put(cl.getParent(), bmi); } } } } return bmi; } /** * This function exists to prevent findbugs from complaining about setting a static member from a non-static * function. * * @param beanManagerProvider the bean-manager-provider which should be used if there isn't an existing provider * * @return the first BeanManagerProvider */ private static BeanManagerProvider setBeanManagerProvider(BeanManagerProvider beanManagerProvider) { if (bmpSingleton == null) { bmpSingleton = beanManagerProvider; } return bmpSingleton; } /** * This method recurses into the parent ClassLoaders and checks whether a BeanManagerInfo for it exists. * * @return the BeanManagerInfo of the parent ClassLoader hierarchy if any exists, or null if there is * no {@link BeanManagerInfo} for the ClassLoaders in the hierarchy. */ private BeanManagerInfo getParentBeanManagerInfo(ClassLoader classLoader) { ClassLoader parentClassLoader = classLoader.getParent(); if (parentClassLoader == null) { return null; } BeanManagerInfo bmi = getBeanManagerInfo(parentClassLoader); if (bmi == null) { // recursive call up to the root ClassLoader bmi = getParentBeanManagerInfo(parentClassLoader); } return bmi; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/provider/BeanProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.provider; import jakarta.enterprise.inject.Any; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionTarget; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * This class contains utility methods for resolution of contextual references in situations where no injection is * available because the current class is not managed by the CDI Container. This can happen in e.g. a JPA 2.0 * EntityListener, a ServletFilter, a Spring managed Bean, etc. * *

* Attention: This approach is intended for use in user code at runtime. If BeanProvider is used during Container * boot (in an Extension), non-portable behaviour results. The CDI specification only allows injection of the * BeanManager during CDI container boot time.

* * @see DependentProvider * @see BeanManagerProvider */ @Vetoed public final class BeanProvider { private static final Logger LOG = Logger.getLogger(BeanProvider.class.getName()); private static final boolean LOG_DEPENDENT_WARNINGS; static { LOG_DEPENDENT_WARNINGS = Arrays.asList(ProjectStage.Development, ProjectStage.UnitTest).contains( ProjectStageProducer.getInstance().getProjectStage()); } private BeanProvider() { // this is a utility class which doesn't get instantiated. } /** * Get a Contextual Reference by its type and qualifiers. You can use this method to get contextual references of a * given type. A "Contextual Reference" is a proxy which will automatically resolve the correct contextual instance * when you access any method. * *

* Attention: You shall not use this method to manually resolve a @Dependent bean! The reason is that * contextual instances usually live in the well-defined lifecycle of their injection point (the bean they got * injected into). But if we manually resolve a @Dependent bean, then it does not belong to such well * defined lifecycle (because @Dependent is not @NormalScoped) and thus will not be automatically * destroyed at the end of the lifecycle. You need to manually destroy this contextual instance via * {@link jakarta.enterprise.context.spi.Contextual#destroy(Object, jakarta.enterprise.context.spi.CreationalContext)}. * Thus you also need to manually store the CreationalContext and the Bean you used to create the contextual * instance.

* * @param type the type of the bean in question * @param qualifiers additional qualifiers which further distinct the resolved bean * @param target type * * @return the resolved Contextual Reference * * @throws IllegalStateException if the bean could not be found. * @see #getContextualReference(Class, boolean, Annotation...) */ public static T getContextualReference(Class type, Annotation... qualifiers) { return getContextualReference(type, false, qualifiers); } /** * {@link #getContextualReference(Class, Annotation...)} which returns null if the 'optional' parameter * is set to true. * * @param type the type of the bean in question * @param optional if true it will return null if no bean could be found or created. * Otherwise it will throw an {@code IllegalStateException} * @param qualifiers additional qualifiers which distinguish the resolved bean * @param target type * * @return the resolved Contextual Reference * * @see #getContextualReference(Class, Annotation...) */ public static T getContextualReference(Class type, boolean optional, Annotation... qualifiers) { BeanManager beanManager = getBeanManager(); return getContextualReference(beanManager, type, optional, qualifiers); } /** * {@link #getContextualReference(Class, Annotation...)} which returns null if the 'optional' parameter * is set to true. This method is intended for usage where the BeanManger is known, e.g. in Extensions. * * @param beanManager the BeanManager to use * @param type the type of the bean in question * @param optional if true it will return null if no bean could be found or created. * Otherwise it will throw an {@code IllegalStateException} * @param qualifiers additional qualifiers which further distinct the resolved bean * @param target type * * @return the resolved Contextual Reference * * @see #getContextualReference(Class, Annotation...) */ public static T getContextualReference(BeanManager beanManager, Class type, boolean optional, Annotation... qualifiers) { Set> beans = beanManager.getBeans(type, qualifiers); if (beans == null || beans.isEmpty()) { if (optional) { return null; } throw new IllegalStateException("Could not find beans for Type=" + type + " and qualifiers:" + Arrays.toString(qualifiers)); } return getContextualReference(type, beanManager, beans); } /** * Get a Contextual Reference by its EL Name. This only works for beans with the @Named annotation. * *

* Attention: please see the notes on manually resolving @Dependent beans in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

* * @param name the EL name of the bean * * @return the resolved Contextual Reference * * @throws IllegalStateException if the bean could not be found. * @see #getContextualReference(String, boolean) */ public static Object getContextualReference(String name) { return getContextualReference(name, false); } /** * Get a Contextual Reference by its EL Name. This only works for beans with the @Named annotation. * *

* Attention: please see the notes on manually resolving @Dependent beans in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

* * @param name the EL name of the bean * @param optional if true it will return null if no bean could be found or created. * Otherwise it will throw an {@code IllegalStateException} * * @return the resolved Contextual Reference */ public static Object getContextualReference(String name, boolean optional) { return getContextualReference(name, optional, Object.class); } /** * Get a Contextual Reference by its EL Name. This only works for beans with the @Named annotation. * *

* Attention: please see the notes on manually resolving @Dependent beans in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

* * @param name the EL name of the bean * @param optional if true it will return null if no bean could be found or created. * Otherwise it will throw an {@code IllegalStateException} * @param type the type of the bean in question - use {@link #getContextualReference(String, boolean)} if the * type is unknown e.g. in dyn. use-cases * @param target type * * @return the resolved Contextual Reference */ public static T getContextualReference(String name, boolean optional, Class type) { return getContextualReference(getBeanManager(), name, optional, type); } /** *

Get a Contextual Reference by its EL Name. * This only works for beans with the @Named annotation.

* *

Attention: please see the notes on manually resolving @Dependent bean * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!

* * * @param beanManager the BeanManager to use * @param name the EL name of the bean * @param optional if true it will return null if no bean could be found or created. * Otherwise it will throw an {@code IllegalStateException} * @param type the type of the bean in question - use {@link #getContextualReference(String, boolean)} * if the type is unknown e.g. in dyn. use-cases * @param target type * @return the resolved Contextual Reference */ public static T getContextualReference(BeanManager beanManager, String name, boolean optional, Class type) { Set> beans = beanManager.getBeans(name); if (beans == null || beans.isEmpty()) { if (optional) { return null; } throw new IllegalStateException("Could not find beans for Type=" + type + " and name:" + name); } return getContextualReference(type, beanManager, beans); } /** * Get the Contextual Reference for the given bean. * *

* Attention: please see the notes on manually resolving @Dependent beans in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

* * @param type the type of the bean in question * @param bean bean definition for the contextual reference * @param target type * * @return the resolved Contextual Reference */ public static T getContextualReference(Class type, Bean bean) { return getContextualReference(type, getBeanManager(), bean); } private static T getContextualReference(Class type, BeanManager beanManager, Bean bean) { //noinspection unchecked return getContextualReference(type, beanManager, Collections.> singleton(bean)); } /** * Get a list of Contextual References by type, regardless of qualifiers (including dependent scoped beans). * * You can use this method to get all contextual references of a given type. A 'Contextual Reference' is a proxy * which will automatically resolve the correct contextual instance when you access any method. * *

* Attention: please see the notes on manually resolving @Dependent beans in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

*

* Attention: This will also return instances of beans for which an Alternative exists! The @Alternative * resolving is only done via {@link BeanManager#resolve(java.util.Set)} which we cannot use in this case!

* * @param type the type of the bean in question * @param optional if true it will return an empty list if no bean could be found or created. Otherwise * it will throw an {@code IllegalStateException} * @param target type * * @return the resolved list of Contextual Reference or an empty-list if optional is true */ public static List getContextualReferences(Class type, boolean optional) { return getContextualReferences(type, optional, true); } /** * Get a list of Contextual References by type, regardless of the qualifier. * * Further details are available at {@link #getContextualReferences(Class, boolean)}. *

* Attention: please see the notes on manually resolving @Dependent bean in * {@link #getContextualReference(Class, java.lang.annotation.Annotation...)}!

*

* Attention: This will also return instances of beans for which an Alternative exists! The @Alternative * resolving is only done via {@link BeanManager#resolve(java.util.Set)} which we cannot use in this case!

* * @param type the type of the bean in question * @param optional if true it will return an empty list if no bean could be found or * created. Otherwise it will throw an {@code IllegalStateException} * @param includeDefaultScopedBeans specifies if dependent scoped beans should be included in the result * @param target type * * @return the resolved list of Contextual Reference or an empty-list if optional is true */ public static List getContextualReferences(Class type, boolean optional, boolean includeDefaultScopedBeans) { BeanManager beanManager = getBeanManager(); Set> beans = getBeanDefinitions(type, optional, includeDefaultScopedBeans, beanManager); List result = new ArrayList(beans.size()); for (Bean bean : beans) { //noinspection unchecked result.add(getContextualReference(type, beanManager, bean)); } return result; } public static DependentProvider getDependent(Class type, Annotation... qualifiers) { BeanManager beanManager = getBeanManager(); return getDependent(beanManager, type, qualifiers); } public static DependentProvider getDependent(BeanManager beanManager, Class type, Annotation... qualifiers) { Set> beans = beanManager.getBeans(type, qualifiers); @SuppressWarnings("unchecked") Bean bean = (Bean) beanManager.resolve(beans); return createDependentProvider(beanManager, type, bean); } public static DependentProvider getDependent(String name) { BeanManager beanManager = getBeanManager(); return getDependent(beanManager, name); } public static DependentProvider getDependent(BeanManager beanManager, String name) { Set> beans = beanManager.getBeans(name); @SuppressWarnings("unchecked") Bean bean = (Bean) beanManager.resolve(beans); @SuppressWarnings("unchecked") Class beanClass = (Class) bean.getBeanClass(); return createDependentProvider(beanManager, beanClass, bean); } private static DependentProvider createDependentProvider(BeanManager beanManager, Class type, Bean bean) { CreationalContext cc = beanManager.createCreationalContext(bean); @SuppressWarnings("unchecked") T instance = (T) beanManager.getReference(bean, type, cc); return new DependentProvider(bean, cc, instance); } /** * Get a set of {@link Bean} definitions by type, regardless of qualifiers. * * @param type the type of the bean in question * @param optional if true it will return an empty set if no bean could be found. * Otherwise it will throw an {@code IllegalStateException} * @param includeDefaultScopedBeans specifies whether dependent scoped beans should be included in the result * @param target type * * @return the resolved set of {@link Bean} definitions or an empty set if optional is true */ public static Set> getBeanDefinitions(Class type, boolean optional, boolean includeDefaultScopedBeans) { BeanManager beanManager = getBeanManager(); return getBeanDefinitions(type, optional, includeDefaultScopedBeans, beanManager); } /** * Get a set of {@link Bean} definitions by type, regardless of qualifiers. * * @param type the type of the bean in question * @param optional if true it will return an empty set if no bean could be found. * Otherwise it will throw an {@code IllegalStateException} * @param includeDefaultScopedBeans specifies whether dependent scoped beans should be included in the result * @param target type * @param beanManager the {@link BeanManager} to use * * @return the resolved set of {@link Bean} definitions or an empty set if optional is true */ public static Set> getBeanDefinitions(Class type, boolean optional, boolean includeDefaultScopedBeans, BeanManager beanManager) { Set> beans = beanManager.getBeans(type, Any.Literal.INSTANCE); if (beans == null || beans.isEmpty()) { if (optional) { return Collections.emptySet(); } throw new IllegalStateException("Could not find beans for Type=" + type); } if (!includeDefaultScopedBeans) { beans = filterDefaultScopedBeans(beans); } Set> result = new HashSet>(); for (Bean bean : beans) { //noinspection unchecked @SuppressWarnings("unchecked") Bean beanT = (Bean) bean; result.add(beanT); } return result; } /** * Performs dependency injection on an instance. Useful for instances which aren't managed by CDI. *

* Attention:
* The resulting instance isn't managed by CDI; only fields annotated with @Inject get initialized. * * @param instance current instance * @param current type * * @return instance with injected fields (if possible - or null if the given instance is null) */ @SuppressWarnings("unchecked") public static T injectFields(T instance) { if (instance == null) { return null; } BeanManager beanManager = getBeanManager(); CreationalContext creationalContext = beanManager.createCreationalContext(null); AnnotatedType annotatedType = beanManager.createAnnotatedType((Class) instance.getClass()); InjectionTarget injectionTarget = beanManager.getInjectionTargetFactory(annotatedType) .createInjectionTarget(null); injectionTarget.inject(instance, creationalContext); return instance; } private static Set> filterDefaultScopedBeans(Set> beans) { Set> result = new HashSet>(beans.size()); for (Bean currentBean : beans) { if (!Dependent.class.isAssignableFrom(currentBean.getScope())) { result.add(currentBean); } } return result; } /** * Internal helper method to resolve the right bean and resolve the contextual reference. * * @param type the type of the bean in question * @param beanManager current bean-manager * @param beans beans in question * @param target type * @return the contextual reference */ private static T getContextualReference(Class type, BeanManager beanManager, Set> beans) { Bean bean = beanManager.resolve(beans); logWarningIfDependent(bean); CreationalContext creationalContext = beanManager.createCreationalContext(bean); @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" }) T result = (T) beanManager.getReference(bean, type, creationalContext); return result; } /** * Log a warning if the given bean is of @Dependent scope as we cannot properly clean up the contextual * instance afterwards. */ private static void logWarningIfDependent(Bean bean) { if (LOG_DEPENDENT_WARNINGS && bean.getScope().equals(Dependent.class)) { LOG.log(Level.WARNING, "BeanProvider shall not be used to create @Dependent scoped beans. " + "Bean: " + bean.toString()); } } /** * Internal method to resolve the BeanManager via the {@link BeanManagerProvider}. * * @return current BeanManager */ private static BeanManager getBeanManager() { return BeanManagerProvider.getInstance().getBeanManager(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/provider/DependentProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.provider; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.PassivationCapable; import jakarta.inject.Provider; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * A {@link Provider} for @Dependent scoped contextual instances. We need this to be able to properly clean them up * when they are not needed anymore via the {@link #destroy()} method. * * Instances of this class can be retrieved using the {@link BeanProvider}. * * Instances of this class are Serializable if the wrapped contextual instance is Serializable. * * @see BeanProvider#getDependent(java.lang.Class, java.lang.annotation.Annotation...) */ public class DependentProvider implements Provider, Serializable { private static final long serialVersionUID = 23423413412001L; private T instance; private CreationalContext creationalContext; private transient Bean bean; DependentProvider(Bean bean, CreationalContext creationalContext, T instance) { this.bean = bean; this.creationalContext = creationalContext; this.instance = instance; } @Override public T get() { return instance; } /** * This method will properly destroy the @Dependent scoped instance. * It will have no effect if the bean is NormalScoped as those have their * own lifecycle which we must not disrupt. */ public void destroy() { if (!BeanManagerProvider.getInstance().getBeanManager().isNormalScope(bean.getScope())) { bean.destroy(instance, creationalContext); } } private void writeObject(ObjectOutputStream out) throws IOException { if (!(bean instanceof PassivationCapable)) { throw new NotSerializableException("Bean is not PassivationCapable: " + bean.toString()); } String passivationId = ((PassivationCapable) bean).getId(); if (passivationId == null) { throw new NotSerializableException(bean.toString()); } out.writeLong(serialVersionUID); out.writeObject(passivationId); out.writeObject(instance); out.writeObject(creationalContext); } @SuppressWarnings("unchecked") private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { long oldSerialId = in.readLong(); if (oldSerialId != serialVersionUID) { throw new NotSerializableException(getClass().getName() + " serialVersion does not match"); } String passivationId = (String) in.readObject(); bean = (Bean) BeanManagerProvider.getInstance().getBeanManager().getPassivationCapableBean(passivationId); instance = (T) in.readObject(); creationalContext = (CreationalContext) in.readObject(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/ConversationGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * * @see GroupedConversationScoped * @see ConversationSubGroup */ @Target( { PARAMETER, FIELD, METHOD, CONSTRUCTOR, TYPE } ) @Retention(RUNTIME) @Documented @Qualifier public @interface ConversationGroup { /** * Class or interface which should be used as type-safe key for identification of the conversation group. * * @return class or interface which should be used as key */ Class value(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/ConversationSubGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Represents a subgroup of a conversation group. Useful for closing a subset of {@code @GroupConversationScoped} beans * in a {@code ConversationGroup}. * *

 * public class MyGroup{}
 *
 * @ConversationScoped
 * @ConversationGroup(MyGroup.class)
 * public class BeanA {}
 *
 * @ConversationScoped
 * @ConversationGroup(MyGroup.class)
 * public class BeanB {}
 *
 * @ConversationScoped
 * @ConversationGroup(MyGroup.class)
 * public class BeanC {}
 *
 * @ConversationSubGroup(of = MyGroup.class, subGroup = {BeanA.class, BeanB.class})
 * public class MySubGroup {}
 * 
or *
 * @ConversationSubGroup(subGroup = {BeanA.class, BeanB.class})
 * public class MySubGroup extends MyGroup {}
 *
 * //...
 * this.groupedConversationManager.closeConversation(MySubGroup.class)
 * 
or it's possible to use implicit subgroups (point to the interface instead of the bean class itself): *
 * public interface MyUseCase {}
 *
 * @ConversationSubGroup(of = MyGroup.class, subGroup = MyUseCase.class)
 * public class ImplicitSubGroup {}
 *
 * @Named("myController")
 * @ConversationScoped
 * @ConversationGroup(MyGroup.class)
 * public class MyController implements Serializable, MyUseCase
 * {
 *    //...
 * }
 * //...
 * this.groupedConversationManager.closeConversation(ImplicitSubGroup.class)
 * 
* * @see ConversationGroup * @see GroupedConversationScoped */ @Target(TYPE) @Retention(RUNTIME) @Documented public @interface ConversationSubGroup { /** * Optionally defines the base conversation group. * * @return base conversation group or ConversationSubGroup if the subgroup inherits from the base conversation group */ Class of() default ConversationSubGroup.class; /** * Members of the subgroup. * * @return beans to include in the subgroup */ Class[] subGroup(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/GroupedConversation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import java.io.Serializable; public interface GroupedConversation extends Serializable { void close(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/GroupedConversationScoped.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import jakarta.enterprise.context.NormalScope; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target( { METHOD,TYPE,FIELD } ) @Retention(RUNTIME) @Inherited @Documented @NormalScope(passivating = true) public @interface GroupedConversationScoped { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/ViewAccessScoped.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import jakarta.enterprise.context.NormalScope; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * The scope is active as long as its bean is accessed by a view. Basically @ViewAccessScoped is a DeltaSpike * Conversation which automatically gets ended when the next view tree gets restored without hitting the bean. */ @Target( { METHOD,TYPE,FIELD } ) @Retention(RUNTIME) @Inherited @Documented @NormalScope(passivating = true) public @interface ViewAccessScoped { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/scope/WindowScoped.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.scope; import jakarta.enterprise.context.NormalScope; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Beans in this scope are bound to an application window (or browser tab). */ @Target( { METHOD,TYPE,FIELD } ) @Retention(RUNTIME) @Inherited @Documented @NormalScope(passivating = true) public @interface WindowScoped { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/throttling/Throttled.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.throttling; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.TimeUnit; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Mark a bean/method as relying on a throttler. */ @InterceptorBinding @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Throttled { /** * @return the duration to wait to acquire the permits. */ @Nonbinding long timeout() default 0L; /** * @return the unit of timeout(). */ @Nonbinding TimeUnit timeoutUnit() default TimeUnit.MILLISECONDS; /** * @return how many permits to require. */ @Nonbinding int weight() default 1; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/throttling/Throttling.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.api.throttling; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.enterprise.inject.spi.AnnotatedMethod; import java.util.concurrent.Semaphore; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Configure the throttler associated to the class/method. */ @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Throttling { /** * @return how to get the semaphore. Default to a plain Semaphore of the JVM. */ @Nonbinding Class factory() default SemaphoreFactory.class; /** * @return true if the semaphore is fair false otherwise. */ @Nonbinding boolean fair() default false; /** * @return how many permits has the semaphore. */ @Nonbinding int permits() default 1; /** * @return name/bucket of this configuration (allow to have multiple buckets per class but default is 1 per class). */ @Nonbinding String name() default ""; interface SemaphoreFactory { /** * @param method the intercepted method. * @param name bucket name. * @param fair should the semaphore be fair. * @param permits maximum permits the semaphore shoulg get. * @return the semaphore build accordingly the parameters. */ Semaphore newSemaphore(AnnotatedMethod method, String name, boolean fair, int permits); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/InterceptorStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi; import jakarta.interceptor.InvocationContext; import java.io.Serializable; /** * Base interface for all interceptor strategies which allow to provide * custom implementations for DeltaSpike interceptors. */ public interface InterceptorStrategy extends Serializable { /** * Method which will be invoked by the interceptor method annotated with {@link jakarta.interceptor.AroundInvoke} * @param invocationContext current invocation-context * @return result of the intercepted method * @throws Exception exception which might be thrown by the intercepted method */ Object execute(InvocationContext invocationContext) throws Exception; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/ClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.activation; import java.io.Serializable; /** *

DeltaSpike allows you to deactivate pre-configured parts (like Extensions, event-broadcasters,...). * Therefore DeltaSpike offers {@link ClassDeactivator} and {@link Deactivatable}.

* *

A {@link ClassDeactivator} allows to specify deactivated classes (if they implement {@link Deactivatable}) * which can't be deactivated/customized via std. CDI mechanisms * (like the veto-method or alternative/specialized CDI-beans). * This might be the case e.g. for CDI Extensions because CDI mechanisms are not available at startup time.

* *

Use it mainly to deactivate specific parts explicitly (blacklist approach), * if there is an issue with such parts (and waiting for the next release isn't an option).

* *

A class-deactivator will be resolved from the environment via the default resolvers or via a custom resolver which * allows to use any type of configuration-format. See {@link org.apache.deltaspike.core.api.config.ConfigResolver} * for more information about how to configure it. The configuration key is * org.apache.deltaspike.core.spi.activation.ClassDeactivator

* *

All ClassDeactivators will get picked up in order of their ordinal and might explicitly activate or * deactivate {@link Deactivatable} classes. Returning a null value means that the ClassDeactivator * doesn't care about the Deactivatable class.

* *

An implementation has to be stateless.

*/ public interface ClassDeactivator extends Serializable { /** * Provides classes which should be deactivated. * * @param targetClass class which should be checked * @return {@link Boolean#FALSE} if class should get activated, {@link Boolean#FALSE} if class must be available * and null to let it as is (defined by default or other */ Boolean isActivated(Class targetClass); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/activation/Deactivatable.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.activation; /** *

Interface to allow easier detection of deactivatable classes.

* *

These classes are activated by default and can be disabled on demand (e.g. via CDI config). * Since CDI, JSF,... currently don't allow to deactivate default implementations, * DeltaSpike has to introduce a proprietary mechanism.

* *

This is e.g. used to disable CDI Extensions in DeltaSpike and might get * used for other Extension libraries as well.

* *

Note: It is suggested that the implementations * use the {@link org.apache.deltaspike.core.util.ClassDeactivationUtils} for implementing the lookup

*/ public interface Deactivatable { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/BaseConfigPropertyProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.BeanUtils; /** *

This contains the fundamental parts for implementing own * ConfigProperty producers.

* *

Providing own Converters and Type injection

*

DeltaSpikes own configuration system natively supports only Strings. * If you'd like to apply own Converters or extract other types from those Strings, * you can simply do this by providing an own Qualifier and a simple * CDI producer method for it.

* *

First we write a simple Qualifier: *

 * @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE })
 * @Retention(RUNTIME)
 * @ConfigProperty(named="unused") // the name
 * @Qualifier
 * public @interface NumberConfig
 * {
 *     @Nonbinding
 *     boolean name(); // the name of the configuration-key to lookup the value
 *
 *     @Nonbinding
 *     String defaultValue() default ConfigProperty.NULL;
 *
 *     @Nonbinding
 *     boolean pattern(); // the pattern for NumberFormatter
 * }
 * 
*

* *

The producer method implementation is pretty easy as well: *

 * @ApplicationScoped
 * public class NumberConfigProducer extends BaseConfigPropertyProducer
 * {
 *     @Produces
 *     @Dependent
 *     @NumberConfig
 *     public Float produceNumberConfig(InjectionPoint injectionPoint)
 *     {
 *         // resolve the annotation
 *         NumberConfig metaData = getAnnotation(injectionPoint, NumberConfig.class);

 *         // get the configured value from the underlying configuration system
 *         String configuredValue = getPropertyValue(metaData.name(), metaData.defaultValue());
 *         if (configuredValue == null)
 *         {
 *             return null;
 *         }
 *
 *         // format according to the given pattern
 *         DecimalFormat df = new DecimalFormat(metaData.pattern(), new DecimalFormatSymbols(Locale.US));
 *         return df.parse(configuredValue).floatValue();
 *     }
 * }
 * 
*

*/ public abstract class BaseConfigPropertyProducer { /** *

Inspects the given InjectionPoint and search for a {@link ConfigProperty} * annotation or an Annotation with a {@link ConfigProperty} meta-Annotation. * The name and defaultValue information will be used to resolve the * configured value.

* * @param injectionPoint current injection point * @return the configured value for the given InjectionPoint */ protected String getStringPropertyValue(InjectionPoint injectionPoint) { ConfigProperty configProperty = getAnnotation(injectionPoint, ConfigProperty.class); if (configProperty == null) { throw new IllegalStateException("producer method called without @ConfigProperty being present!"); } return getPropertyValue(injectionPoint, String.class); } protected T getPropertyValue(InjectionPoint injectionPoint, Class ipCls) { return getUntypedPropertyValue(injectionPoint, ipCls); } protected T getUntypedPropertyValue(InjectionPoint injectionPoint, Type ipCls) { ConfigProperty configProperty = getAnnotation(injectionPoint, ConfigProperty.class); if (configProperty == null) { throw new IllegalStateException("producer method called without @ConfigProperty being present!"); } return readEntry(configProperty.name(), configProperty.defaultValue(), ipCls, configProperty.converter(), configProperty.parameterizedBy(), configProperty.projectStageAware(), configProperty.evaluateVariables()); } /** * @param propertyName the name of the property key * @param defaultValue the default value to return if no configured property is found or * {@link ConfigProperty#NULL} if no default value should be returned. * @return the configured value or the defaultValue according to the NULL logic. */ protected String getPropertyValue(String propertyName, String defaultValue) { String configuredValue; if (ConfigProperty.NULL.equals(defaultValue)) { // no special defaultValue has been configured configuredValue = ConfigResolver.getProjectStageAwarePropertyValue(propertyName); } else { configuredValue = ConfigResolver.getProjectStageAwarePropertyValue(propertyName, defaultValue); } return configuredValue; } /** * @param injectionPoint current injection point * @param targetType target type * @param type * @return annotation instance extracted from the injection point which matches the given type */ protected T getAnnotation(InjectionPoint injectionPoint, Class targetType) { return BeanUtils.extractAnnotation(injectionPoint.getAnnotated(), targetType); } public T readEntry(final String key, final String stringDefault, final Type ipCls, final Class converterType, final String parameterizedBy, final boolean projectStageAware, final boolean evaluate) { final ConfigResolver.TypedResolver resolver = asResolver( key, stringDefault, ipCls, converterType, parameterizedBy, projectStageAware, evaluate); return resolver.getValue(); } public ConfigResolver.TypedResolver asResolver(final String key, final String stringDefault, final Type ipCls, final Class converterType, final String parameterizedBy, final boolean projectStageAware, final boolean evaluate) { final Config config = ConfigResolver.getConfig(); final ConfigResolver.UntypedResolver untypedResolver = config.resolve(key); final ConfigResolver.TypedResolver resolver; if (ConfigResolver.Converter.class != converterType) { resolver = untypedResolver.as(ipCls, BeanProvider.getContextualReference(converterType)); } else if (converterExists(config, ipCls)) { resolver = untypedResolver.as(Class.class.cast(ipCls)); } else { resolver = untypedResolver.asBean(Class.class.cast(ipCls)); } resolver.withCurrentProjectStage(projectStageAware); if (!ConfigProperty.NULL.equals(stringDefault)) { resolver.withStringDefault(stringDefault); } if (!ConfigProperty.NULL.equals(parameterizedBy)) { resolver.parameterizedBy(parameterizedBy); } return resolver.evaluateVariables(evaluate); } /** * TODO we should make Converters for single attributes configurable. * Until then the list is fixed. * See TypedResolverImpl#convert */ private boolean converterExists(Config config, Type ipCls) { return (String.class == ipCls || Integer.class == ipCls || Boolean.class == ipCls || Long.class == ipCls || Float.class == ipCls || Double.class == ipCls || Class.class == ipCls ); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config; /** *

A filter which can be added to the * {@link org.apache.deltaspike.core.api.config.ConfigResolver}. * The filter can be used to decrypt config values or prepare * values for logging.

* *

Registering a {@code ConfigFilter} can either be done via the * {@code java.util.ServiceLoader} pattern or by manually adding it via * {@link org.apache.deltaspike.core.api.config.ConfigResolver#addConfigFilter(ConfigFilter)}.

*/ public interface ConfigFilter { /** * Filter the given configuration value * @param key * @param value * @return the filtered value or the original input String if no filter shall be applied */ String filterValue(String key, String value); /** * Filter the given configuration value for usage in logs. * This might be used to mask out passwords, etc. * @param key * @param value * @return the filtered value or the original input String if no filter shall be applied */ String filterValueForLog(String key, String value); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config; import java.util.Map; import java.util.Set; import java.util.function.Consumer; /** *

Implement this interfaces to provide a ConfigSource. * A ConfigSource provides properties from a specific place, like * JNDI configuration, a properties file, etc

* *

The custom implementation can be 'registered' using a * {@link ConfigSourceProvider} or via the * {@link java.util.ServiceLoader} mechanism. In the later case * it must get registered via creating a * META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource * file and adding the fully qualified class name of your ConfigSource * implementation into it.

* *

If a ConfigSource implements the {@link java.lang.AutoCloseable} interface it will automatically * be released when the Config is shut down.

*/ public interface ConfigSource { /** * The default name for the ordinal field. * Any ConfigSource might use it's own though or even return a hardcoded * in {@link #getOrdinal()}. */ String DELTASPIKE_ORDINAL = "deltaspike_ordinal"; /** * The default value if no special ordinal is defined for this ConfigSource. */ int DELTASPIKE_DEFAULT_ORDINAL = 100; /** * Lookup order: * *
    *
  1. System properties (ordinal 400)
  2. *
  3. Environment properties (ordinal 300)
  4. *
  5. JNDI values (ordinal 200)
  6. *
  7. Properties file values (/META-INF/apache-deltaspike.properties) (ordinal 100)
  8. *
*

*

Important Hints for custom implementations:

*

* If a custom implementation should be invoked before the default implementations, use a value > 400 *

*

* If a custom implementation should be invoked after the default implementations, use a value < 100 *

*

* * IMPORTANT: Have a look at the abstract base-implementation DeltaSpike is using internally, * if a custom implementation should load the ordinal value from the config-source like the default * implementations provided by DeltaSpike do. * *

*

*

Reordering of the default order of the config-sources:

*

Example: If the properties file/s should be used before the other implementations, * you have to configure an ordinal > 400. That means, you have to add e.g. deltaspike_ordinal=401 to * /META-INF/apache-deltaspike.properties . Hint: In case of property files every file is handled as independent * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.

* *

This method will only get evaluated once at startup and whenever a new ConfigSource is added.

* * @return the 'importance' aka ordinal of the configured values. The higher, the more important. */ default int getOrdinal() { String ordinal = getPropertyValue(DELTASPIKE_ORDINAL); if (ordinal != null && ordinal.length() > 0) { return Integer.valueOf(ordinal); } return DELTASPIKE_DEFAULT_ORDINAL; } /** * Return properties contained in this config source. * @return Properties available in this config source. */ Map getProperties(); /** * @param key for the property * @return configured value or null if this ConfigSource doesn't provide any value for the given key. */ String getPropertyValue(String key); /** * @return the 'name' of the configuration source, e.g. 'property-file mylocation/myproperty.properties' */ String getConfigName(); /** * Determines if this config source should be scanned for its list of properties. * * Generally, slow ConfigSources should return false here. * * @return true if this ConfigSource should be scanned for its list of properties, * false if it should not be scanned. */ default boolean isScannable() { return true; } /** * This callback should get invoked if an attribute change got detected inside the ConfigSource. * * An example would be a database backed ConfigSource which scans the DB every second in a background task. * And once it detects a change in values, it will notify the Config about the changed attributes * by invoking {@code reportAttributeChange.accept(changedKeys);} * * @param reportAttributeChange will be set by the {@link org.apache.deltaspike.core.api.config.Config} after this * {@code ConfigSource} got created and before any configured values * get served. */ default void setOnAttributeChange(Consumer> reportAttributeChange) { // do nothing by default. Just for compat with older ConfigSources. } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigSourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config; import java.util.List; /** *

Implement this interfaces to provide a ConfigSource provider which * is able to maintain multiple ConfigSources. This is e.g. needed if * there are multiple property files of a given name.

* *

If a ConfigSource like JNDI only exists once, then there is no need * to implement it via the ConfigSourceProvider but should directly * expose a {@link ConfigSource}.

* *

A ConfigSourceProvider will get picked up via the * {@link java.util.ServiceLoader} mechanism and must get registered via * META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider

*/ public interface ConfigSourceProvider { /** * @return For each e.g. property file, we return a single ConfigSource or an empty list if no ConfigSource exists. */ List getConfigSources(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/ConfigValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config; import java.util.Set; public interface ConfigValidator { /** * @return a set of violation-messages if an invalid state is found * those messages will be used to add one deployment-problem per message */ Set processValidation(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ConfigDescriptorValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; /** * Allows to validate the final view-config descriptors before they get deployed. * Since the config-descriptor contains e.g. the final path, * it's also possible to validate if the corresponding file exists. * Use {@link ViewConfigRoot} to configure 1-n validators. */ public interface ConfigDescriptorValidator { /** * Validates the given config-descriptor * @param configDescriptor (merged) config-descriptor directly before it gets deployed * @return true if the descriptor is valid, false otherwise */ boolean isValid(ConfigDescriptor configDescriptor); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ConfigNodeConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; /** * Allows to provide multiple strategies to process the nodes of the built config-tree. * Use {@link ViewConfigRoot} to configure a custom converter. */ public interface ConfigNodeConverter { /** * Converts a {@link ViewConfigNode} created during the scanning process to the final {@link ConfigDescriptor} * used at runtime */ ConfigDescriptor convert(ViewConfigNode node); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ConfigPreProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import java.lang.annotation.Annotation; /** * Allows to change the found meta-data (e.g. replace default values - example: * Page.extension needs "" as a default for the meta-data-merging process, but "xhtml" should be the final default) * or the {@link ViewConfigNode} itself. E.g. to register callbacks supported by the meta-data * (see {@link org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData#preProcessor()} ) * * @param meta-data type */ public interface ConfigPreProcessor { /** * @param metaData The annotation-instance which was found or the inherited instance. * Since it's possible to override annotation-attributes alongside the inheritance-path, * it can be a merged representation. * To get rid of meta-data which is only inherited, * it's required to check the presence of the physical annotation e.g. via * ViewConfigNode#getSource#isAnnotationPresent * and return a synthetic literal-instance (as a marker/placeholder), * because 'null' isn't supported as return-value. * @param viewConfigNode Instance which represents the current node * @return The annotation-instance which should be used for the final meta-data */ T beforeAddToConfig(T metaData, ViewConfigNode viewConfigNode); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/InlineMetaDataTransformer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import java.lang.annotation.Annotation; /** * Allows to transform an annotation annotated with @InlineViewMetaData to an annotation annotated with @ViewMetaData. * This transformer is optional and only needed if it should result in the same at runtime, but the inline-meta-data * needs a different syntax via a different annotation (compared to the view-config meta-data). * E.g. see @ViewRef vs. @ViewControllerRef. * * @param type of the inline-meta-data * @param type of the target-meta-data */ public interface InlineMetaDataTransformer { T convertToViewMetaData(I inlineMetaData, Class sourceClass); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/TargetViewConfigProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import org.apache.deltaspike.core.api.config.view.ViewConfig; import java.lang.annotation.Annotation; /** * It's restricted to reference {@link ViewConfig} classes to force more solid references. * (This restriction is intended.) * To reference folder-nodes, it's needed that the corresponding config-class implements {@link ViewConfig} as well. * * It's used instead of a marker annotation to be more flexible (e.g. for special cases like conditional references). * * @param type of the annotation which provides the information about the target view-config/s */ public interface TargetViewConfigProvider { Class[] getTarget(T inlineMetaData); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ViewConfigInheritanceStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import java.lang.annotation.Annotation; import java.util.List; /** * Allows to customize the inheritance-strategy for meta-data. * E.g. inheritance via std. java inheritance vs. inheritance via nested interfaces. * Use {@link ViewConfigRoot} to configure a custom inheritance-strategy. */ public interface ViewConfigInheritanceStrategy { /** * @param viewConfigNode current view-config node * @return annotation instances which should be merged with the annotation instances of the node itself */ List resolveInheritedMetaData(ViewConfigNode viewConfigNode); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ViewConfigNode.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import java.lang.annotation.Annotation; import java.util.List; import java.util.Map; import java.util.Set; /** * Node-type used for building the meta-data-tree during the bootstrapping process. */ public interface ViewConfigNode { ViewConfigNode getParent(); List getChildren(); Class getSource(); Set getMetaData(); List getInheritedMetaData(); Map, List> getCallbackDescriptors(); //TODO List getCallbackDescriptors(Class metaDataType); void registerCallbackDescriptors(Class metaDataType, CallbackDescriptor callbackDescriptor); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/config/view/ViewConfigRoot.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.config.view; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Allows to customize the default behaviour for processing the meta-data-tree */ @Target(TYPE) @Retention(RUNTIME) @Documented /** * Optional annotation which allows to provide custom implementations. * Only annotate one {@link org.apache.deltaspike.core.api.config.view.ViewConfig} class which represents the root node. */ public @interface ViewConfigRoot { Class viewConfigResolver() default ViewConfigResolver.class; Class configNodeConverter() default ConfigNodeConverter.class; Class viewConfigInheritanceStrategy() default ViewConfigInheritanceStrategy.class; Class[] configDescriptorValidators() default { }; } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/filter/ClassFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.filter; import org.apache.deltaspike.core.spi.activation.Deactivatable; public interface ClassFilter extends Deactivatable { boolean isFiltered(Class currentClass); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/future/FutureableStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.future; import org.apache.deltaspike.core.spi.InterceptorStrategy; public interface FutureableStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/lock/LockedStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.lock; import org.apache.deltaspike.core.spi.InterceptorStrategy; public interface LockedStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/scope/conversation/GroupedConversationManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.scope.conversation; import org.apache.deltaspike.core.util.context.ContextualStorage; import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.Set; public interface GroupedConversationManager extends Serializable { /** * @param conversationGroup group of the conversation in question * @param qualifiers optional qualifiers for the conversation * @return the removed conversation - null otherwise */ ContextualStorage closeConversation(Class conversationGroup, Annotation... qualifiers); /** * destroys all conversation of a group independent of the qualifiers * * @param conversationGroup group of the conversation in question * @return the removed storages - null otherwise */ Set closeConversationGroup(Class conversationGroup); /** * invalidate all conversations immediately (within the current window) */ void closeConversations(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/scope/viewaccess/ViewAccessContextManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.scope.viewaccess; import java.io.Serializable; public interface ViewAccessContextManager extends Serializable { void close(); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/scope/window/WindowContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.scope.window; import java.io.Serializable; /** *

We support the general notion of multiple 'windows' * That might be different parallel edit pages in a * desktop application (think about different open documents * in an editor) or multiple browser tabs in a * web application.

*

For web applications each browser tab or window will be * represented by an own {@link WindowContext} slice. All those * {@link WindowContext} slices will be held in the users servlet * session as @SessionScoped bean. *

*

Every WindowContext is uniquely identified via a * 'windowId' inside the current Session. * Each Thread is associated with at most * one single windowId at a time. The {@link WindowContext} * is the interface which allows resolving the current windowId * associated with this very Thread.

*/ public interface WindowContext extends Serializable { /** * @return the windowId associated with the very Thread or null. */ String getCurrentWindowId(); /** * Set the current windowId as the currently active for the very Thread. * If no WindowContext exists with the very windowId we will create a new one. * @param windowId */ void activateWindow(String windowId); /** * close the WindowContext with the given windowId. * @return true if any did exist, false otherwise */ boolean closeWindow(String windowId); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/scope/window/WindowContextQuotaHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.scope.window; import org.apache.deltaspike.core.spi.activation.Deactivatable; import java.io.Serializable; /** * Allows to create a custom handler for a custom window-quota */ public interface WindowContextQuotaHandler extends Deactivatable, Serializable { void checkWindowContextQuota(String windowId); } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/spi/throttling/ThrottledStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.spi.throttling; import org.apache.deltaspike.core.spi.InterceptorStrategy; public interface ThrottledStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/AggregatedClassLoader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import java.io.IOException; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class AggregatedClassLoader extends ClassLoader { private final List classLoaders; public AggregatedClassLoader(List classLoaders) { super(); this.classLoaders = classLoaders; } public static AggregatedClassLoader newInstance() { return new AggregatedClassLoader(Arrays.asList( AggregatedClassLoader.class.getClassLoader(), Thread.currentThread().getContextClassLoader(), ClassLoader.getSystemClassLoader())); } @Override public URL getResource(String name) { for (ClassLoader loader : classLoaders) { URL url = loader.getResource(name); if (url != null) { return url; } } return super.getResource(name); } @Override public Enumeration getResources(String name) throws IOException { final Set result = new LinkedHashSet(); for (ClassLoader loader : classLoaders) { Enumeration urls = loader.getResources(name); while (urls.hasMoreElements()) { result.add(urls.nextElement()); } } return new Enumeration() { private final Iterator iterator = result.iterator(); @Override public URL nextElement() { return iterator.next(); } @Override public boolean hasMoreElements() { return iterator.hasNext(); } }; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/Annotateds.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedCallable; import jakarta.enterprise.inject.spi.AnnotatedConstructor; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.AnnotatedType; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; /** *

* Utilities for working with {@link Annotated}s. *

*

*

* Includes utilities to check the equality of and create unique id's for * Annotated instances. *

*/ public final class Annotateds { private static final char SEPARATOR = ';'; private Annotateds() { // this is a utility class with statics only } /** * Does the first stage of comparing AnnoatedCallables, however it cannot * compare the method parameters */ @Vetoed private static class AnnotatedCallableComparator implements Comparator>, Serializable { public int compare(AnnotatedCallable arg0, AnnotatedCallable arg1) { // compare the names first int result = (arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName())); if (result != 0) { return result; } result = arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember() .getDeclaringClass().getName()); if (result != 0) { return result; } result = arg0.getParameters().size() - arg1.getParameters().size(); return result; } } @Vetoed private static class AnnotatedMethodComparator implements Comparator>, Serializable { private AnnotatedCallableComparator callableComparator = new AnnotatedCallableComparator(); public static Comparator> instance() { return new AnnotatedMethodComparator(); } public int compare(AnnotatedMethod arg0, AnnotatedMethod arg1) { int result = callableComparator.compare(arg0, arg1); if (result != 0) { return result; } for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i) { Class p0 = arg0.getJavaMember().getParameterTypes()[i]; Class p1 = arg1.getJavaMember().getParameterTypes()[i]; result = p0.getName().compareTo(p1.getName()); if (result != 0) { return result; } } return 0; } } @Vetoed private static class AnnotatedConstructorComparator implements Comparator>, Serializable { private AnnotatedCallableComparator callableComparator = new AnnotatedCallableComparator(); public static Comparator> instance() { return new AnnotatedConstructorComparator(); } public int compare(AnnotatedConstructor arg0, AnnotatedConstructor arg1) { int result = callableComparator.compare(arg0, arg1); if (result != 0) { return result; } for (int i = 0; i < arg0.getJavaMember().getParameterTypes().length; ++i) { Class p0 = arg0.getJavaMember().getParameterTypes()[i]; Class p1 = arg1.getJavaMember().getParameterTypes()[i]; result = p0.getName().compareTo(p1.getName()); if (result != 0) { return result; } } return 0; } } @Vetoed private static class AnnotatedFieldComparator implements Comparator>, Serializable { public static Comparator> instance() { return new AnnotatedFieldComparator(); } public int compare(AnnotatedField arg0, AnnotatedField arg1) { if (arg0.getJavaMember().getName().equals(arg1.getJavaMember().getName())) { return arg0.getJavaMember().getDeclaringClass().getName().compareTo(arg1.getJavaMember() .getDeclaringClass().getName()); } return arg0.getJavaMember().getName().compareTo(arg1.getJavaMember().getName()); } } @Vetoed private static class AnnotationComparator implements Comparator, Serializable { public static final Comparator INSTANCE = new AnnotationComparator(); public int compare(Annotation arg0, Annotation arg1) { return arg0.annotationType().getName().compareTo(arg1.annotationType().getName()); } } @Vetoed private static class MethodComparator implements Comparator { public static final Comparator INSTANCE = new MethodComparator(); public int compare(Method arg0, Method arg1) { return arg0.getName().compareTo(arg1.getName()); } } /** * Generates a deterministic signature for an {@link AnnotatedType}. Two * AnnotatedTypes that have the same annotations and underlying * type will generate the same signature. *

* This can be used to create a unique bean id for a passivation capable bean * that is added directly through the SPI. * * @param annotatedType The type to generate a signature for * @return A string representation of the annotated type */ public static String createTypeId(AnnotatedType annotatedType) { return createTypeId(annotatedType.getJavaClass(), annotatedType.getAnnotations(), annotatedType.getMethods(), annotatedType.getFields(), annotatedType.getConstructors()); } /** * Generates a unique signature for a concrete class. Annotations are not * read directly from the class, but are read from the * annotations, methods, fields and * constructors arguments * * @param clazz The java class type * @param annotations Annotations present on the java class * @param methods The AnnotatedMethods to include in the signature * @param fields The AnnotatedFields to include in the signature * @param constructors The AnnotatedConstructors to include in the signature * @return A string representation of the type */ public static String createTypeId(Class clazz, Collection annotations, Collection> methods, Collection> fields, Collection> constructors) { StringBuilder builder = new StringBuilder(); builder.append(clazz.getName()); builder.append(createAnnotationCollectionId(annotations)); builder.append("{"); // now deal with the fields List> sortedFields = new ArrayList>(); sortedFields.addAll(fields); Collections.sort(sortedFields, AnnotatedFieldComparator.instance()); for (AnnotatedField field : sortedFields) { if (!field.getAnnotations().isEmpty()) { builder.append(createFieldId(field)); builder.append(SEPARATOR); } } // methods List> sortedMethods = new ArrayList>(); sortedMethods.addAll(methods); Collections.sort(sortedMethods, AnnotatedMethodComparator.instance()); for (AnnotatedMethod method : sortedMethods) { if (!method.getAnnotations().isEmpty() || hasMethodParameters(method)) { builder.append(createCallableId(method)); builder.append(SEPARATOR); } } // constructors List> sortedConstructors = new ArrayList>(); sortedConstructors.addAll(constructors); Collections.sort(sortedConstructors, AnnotatedConstructorComparator.instance()); for (AnnotatedConstructor constructor : sortedConstructors) { if (!constructor.getAnnotations().isEmpty() || hasMethodParameters(constructor)) { builder.append(createCallableId(constructor)); builder.append(SEPARATOR); } } builder.append("}"); return builder.toString(); } /** * Generates a deterministic signature for an {@link AnnotatedField}. Two * AnnotatedFields that have the same annotations and * underlying field will generate the same signature. */ public static String createFieldId(AnnotatedField field) { return createFieldId(field.getJavaMember(), field.getAnnotations()); } /** * Creates a deterministic signature for a {@link Field}. * * @param field The field to generate the signature for * @param annotations The annotations to include in the signature */ public static String createFieldId(Field field, Collection annotations) { StringBuilder builder = new StringBuilder(); builder.append(field.getDeclaringClass().getName()); builder.append('.'); builder.append(field.getName()); builder.append(createAnnotationCollectionId(annotations)); return builder.toString(); } /** * Generates a deterministic signature for an {@link AnnotatedCallable}. Two * AnnotatedCallables that have the same annotations and * underlying callable will generate the same signature. */ public static String createCallableId(AnnotatedCallable method) { StringBuilder builder = new StringBuilder(); builder.append(method.getJavaMember().getDeclaringClass().getName()); builder.append('.'); builder.append(method.getJavaMember().getName()); builder.append(createAnnotationCollectionId(method.getAnnotations())); builder.append(createParameterListId(method.getParameters())); return builder.toString(); } /** * Creates a deterministic signature for a {@link Method}. * * @param method The method to generate the signature for * @param annotations The annotations to include in the signature * @param parameters The {@link AnnotatedParameter}s to include in the * signature */ public static String createMethodId(Method method, Set annotations, List> parameters) { StringBuilder builder = new StringBuilder(); builder.append(method.getDeclaringClass().getName()); builder.append('.'); builder.append(method.getName()); builder.append(createAnnotationCollectionId(annotations)); builder.append(createParameterListId(parameters)); return builder.toString(); } /** * Creates a deterministic signature for a {@link Constructor}. * * @param constructor The constructor to generate the signature for * @param annotations The annotations to include in the signature * @param parameters The {@link AnnotatedParameter}s to include in the * signature */ public static String createConstructorId(Constructor constructor, Set annotations, List> parameters) { StringBuilder builder = new StringBuilder(); builder.append(constructor.getDeclaringClass().getName()); builder.append('.'); builder.append(constructor.getName()); builder.append(createAnnotationCollectionId(annotations)); builder.append(createParameterListId(parameters)); return builder.toString(); } /** * Generates a unique string representation of a list of * {@link AnnotatedParameter}s. */ public static String createParameterListId(List> parameters) { StringBuilder builder = new StringBuilder(); builder.append("("); for (int i = 0; i < parameters.size(); ++i) { AnnotatedParameter ap = parameters.get(i); builder.append(createParameterId(ap)); if (i + 1 != parameters.size()) { builder.append(','); } } builder.append(")"); return builder.toString(); } /** * Creates a string representation of an {@link AnnotatedParameter}. */ public static String createParameterId(AnnotatedParameter annotatedParameter) { return createParameterId(annotatedParameter.getBaseType(), annotatedParameter.getAnnotations()); } /** * Creates a string representation of a given type and set of annotations. */ public static String createParameterId(Type type, Set annotations) { StringBuilder builder = new StringBuilder(); if (type instanceof Class) { Class c = (Class) type; builder.append(c.getName()); } else { builder.append(type.toString()); } builder.append(createAnnotationCollectionId(annotations)); return builder.toString(); } /** *

* Compares {@link AnnotatedField}s for equality. *

*

* Two {@link AnnotatedField}s are considered equal if they have the same * underlying field and annotations. *

*/ public static boolean compareAnnotatedField(AnnotatedField f1, AnnotatedField f2) { if (!f1.getJavaMember().equals(f2.getJavaMember())) { return false; } return compareAnnotated(f1, f2); } /** *

* Compare {@link AnnotatedCallable}s for equality. *

*

*

* Two {@link AnnotatedCallable}s are considered equal if they have the same * underlying callable and annotations. *

*/ public static boolean compareAnnotatedCallable(AnnotatedCallable m1, AnnotatedCallable m2) { if (!m1.getJavaMember().equals(m2.getJavaMember())) { return false; } if (!compareAnnotated(m1, m2)) { return false; } return compareAnnotatedParameters(m1.getParameters(), m2.getParameters()); } /** *

* Compares two {@link AnnotatedType}s for equality. *

*

*

* Two {@link AnnotatedType}s are considered equal if they have the same * underlying type and annotations, and all members have the same * annotations. *

*/ public static boolean compareAnnotatedTypes(AnnotatedType t1, AnnotatedType t2) { if (!t1.getJavaClass().equals(t2.getJavaClass())) { return false; } if (!compareAnnotated(t1, t2)) { return false; } if (t1.getFields().size() != t2.getFields().size()) { return false; } Map> fields = new HashMap>(); for (AnnotatedField f : t2.getFields()) { fields.put(f.getJavaMember(), f); } for (AnnotatedField f : t1.getFields()) { if (fields.containsKey(f.getJavaMember())) { if (!compareAnnotatedField(f, fields.get(f.getJavaMember()))) { return false; } } else { return false; } } if (t1.getMethods().size() != t2.getMethods().size()) { return false; } Map> methods = new HashMap>(); for (AnnotatedMethod f : t2.getMethods()) { methods.put(f.getJavaMember(), f); } for (AnnotatedMethod f : t1.getMethods()) { if (methods.containsKey(f.getJavaMember())) { if (!compareAnnotatedCallable(f, methods.get(f.getJavaMember()))) { return false; } } else { return false; } } if (t1.getConstructors().size() != t2.getConstructors().size()) { return false; } Map, AnnotatedConstructor> constructors = new HashMap, AnnotatedConstructor>(); for (AnnotatedConstructor f : t2.getConstructors()) { constructors.put(f.getJavaMember(), f); } for (AnnotatedConstructor f : t1.getConstructors()) { if (constructors.containsKey(f.getJavaMember())) { if (!compareAnnotatedCallable(f, constructors.get(f.getJavaMember()))) { return false; } } else { return false; } } return true; } private static boolean hasMethodParameters(AnnotatedCallable callable) { for (AnnotatedParameter parameter : callable.getParameters()) { if (!parameter.getAnnotations().isEmpty()) { return true; } } return false; } private static String createAnnotationCollectionId(Collection annotations) { if (annotations.isEmpty()) { return ""; } StringBuilder builder = new StringBuilder(); builder.append('['); List annotationList = new ArrayList(annotations.size()); annotationList.addAll(annotations); Collections.sort(annotationList, AnnotationComparator.INSTANCE); for (Annotation a : annotationList) { builder.append('@'); builder.append(a.annotationType().getName()); builder.append('('); Method[] declaredMethods = a.annotationType().getDeclaredMethods(); List methods = new ArrayList(declaredMethods.length); methods.addAll(Arrays.asList(declaredMethods)); Collections.sort(methods, MethodComparator.INSTANCE); for (int i = 0; i < methods.size(); ++i) { Method method = methods.get(i); try { Object value = method.invoke(a); builder.append(method.getName()); builder.append('='); if (value.getClass().isArray()) { Class componentType = value.getClass().getComponentType(); if (componentType.isAnnotation()) { builder.append(Arrays.asList((Object[]) value)); } else if (componentType instanceof Class) { builder.append(createArrayId(value)); } else { builder.append(value.toString()); } } else { builder.append(value.toString()); } } catch (NullPointerException e) { throw new RuntimeException("NullPointerException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (IllegalArgumentException e) { throw new RuntimeException("IllegalArgumentException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (IllegalAccessException e) { throw new RuntimeException("IllegalAccessException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } catch (InvocationTargetException e) { throw new RuntimeException("InvocationTargetException accessing annotation member, annotation:" + a.annotationType().getName() + " member: " + method.getName(), e); } if (i + 1 != methods.size()) { builder.append(','); } } builder.append(')'); } builder.append(']'); return builder.toString(); } /** * Appends comma separated list of class names from classArray to builder */ private static String createArrayId(Object value) { if (value instanceof int[]) { return Arrays.toString((int[]) value); } if (value instanceof short[]) { return Arrays.toString((short[]) value); } if (value instanceof byte[]) { return Arrays.toString((byte[]) value); } if (value instanceof char[]) { return Arrays.toString((char[]) value); } if (value instanceof long[]) { return Arrays.toString((long[]) value); } if (value instanceof float[]) { return Arrays.toString((float[]) value); } if (value instanceof double[]) { return Arrays.toString((double[]) value); } if (value instanceof String[]) { return Arrays.toString((String[]) value); } return createClassArrayId((Class[]) value); } /** * Appends comma separated list of class names from classArray to builder */ private static String createClassArrayId(Class[] classArray) { StringBuilder builder = new StringBuilder(); builder.append('['); for (int i = 0; i < classArray.length; i++) { builder.append(classArray[i].getName()); if (i + 1 != classArray.length) { builder.append(','); } } builder.append(']'); return builder.toString(); } /** * Compares two annotated elements to see if they have the same annotations */ private static boolean compareAnnotated(Annotated a1, Annotated a2) { return a1.getAnnotations().equals(a2.getAnnotations()); } /** * Compares two annotated elements to see if they have the same annotations */ private static boolean compareAnnotatedParameters(List> p1, List> p2) { if (p1.size() != p2.size()) { return false; } for (int i = 0; i < p1.size(); ++i) { if (!compareAnnotated(p1.get(i), p2.get(i))) { return false; } } return true; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/AnnotationUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; @Vetoed public abstract class AnnotationUtils { private AnnotationUtils() { // prevent instantiation } public static T extractAnnotationFromMethodOrClass( BeanManager beanManager, Method targetMethod, Class targetClass, Class targetAnnotationType) { T result = extractAnnotationFromMethod(beanManager, targetMethod, targetAnnotationType); if (result == null) { //see DELTASPIKE-517 Class unproxiedTargetClass = ProxyUtils.getUnproxiedClass(targetClass); // and if not found search on the class result = findAnnotation(beanManager, unproxiedTargetClass.getAnnotations(), targetAnnotationType); } return result; } public static T extractAnnotationFromMethod( BeanManager beanManager, Method targetMethod, Class targetAnnotationType) { return findAnnotation(beanManager, targetMethod.getAnnotations(), targetAnnotationType); } public static T findAnnotation( BeanManager beanManager, Annotation[] annotations, Class targetAnnotationType) { for (Annotation annotation : annotations) { if (targetAnnotationType.equals(annotation.annotationType())) { return (T) annotation; } if (beanManager.isStereotype(annotation.annotationType())) { T result = findAnnotation( beanManager, annotation.annotationType().getAnnotations(), targetAnnotationType); if (result != null) { return result; } } } return null; } //based on org.apache.webbeans.container.BeanCacheKey#getQualifierHashCode public static int getQualifierHashCode(Annotation annotation) { Class annotationClass = annotation.annotationType(); int hashCode = getTypeHashCode(annotationClass); for (Method member : annotationClass.getDeclaredMethods()) { if (member.isAnnotationPresent(Nonbinding.class)) { continue; } final Object annotationMemberValue = ReflectionUtils.invokeMethod(annotation, member, Object.class, true); final int arrayValue; if (annotationMemberValue == null /*possible with literals*/) { arrayValue = 0; } else if (annotationMemberValue.getClass().isArray()) { Class annotationMemberType = annotationMemberValue.getClass().getComponentType(); if (annotationMemberType.isPrimitive()) { if (Long.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((long[]) annotationMemberValue); } else if (Integer.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((int[]) annotationMemberValue); } else if (Short.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((short[]) annotationMemberValue); } else if (Double.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((double[]) annotationMemberValue); } else if (Float.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((float[]) annotationMemberValue); } else if (Boolean.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((boolean[]) annotationMemberValue); } else if (Byte.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((byte[]) annotationMemberValue); } else if (Character.TYPE == annotationMemberType) { arrayValue = Arrays.hashCode((char[]) annotationMemberValue); } else { arrayValue = 0; } } else { arrayValue = Arrays.hashCode((Object[]) annotationMemberValue); } } else { arrayValue = annotationMemberValue.hashCode(); } hashCode = 29 * hashCode + arrayValue; hashCode = 29 * hashCode + member.getName().hashCode(); } return hashCode; } private static int getTypeHashCode(Type type) { int typeHash = type.hashCode(); if (typeHash == 0 && type instanceof Class) { return ((Class)type).getName().hashCode(); } return typeHash; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ArraysUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * A collection of utilities for working with Arrays */ @Vetoed public abstract class ArraysUtils { private ArraysUtils() { // prevent instantiation } /** * Create a set from an array. If the array contains duplicate objects, the * last object in the array will be placed in resultant set. * * @param the type of the objects in the set * @param array the array from which to create the set * @return the created sets */ public static Set asSet(T... array) { Set result = new HashSet(); Collections.addAll(result, array); return result; } public static boolean isEmpty(Object[] array) { return array == null || array.length == 0; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanConfiguratorUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Typed; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.configurator.BeanConfigurator; import jakarta.inject.Named; import java.beans.Introspector; import java.lang.annotation.Annotation; public class BeanConfiguratorUtils { private BeanConfiguratorUtils() { } public static BeanConfigurator read(BeanManager beanManager, BeanConfigurator beanConfigurator, AnnotatedType type) { // Weld doesnt support interfaces... if (!type.getJavaClass().isInterface()) { return beanConfigurator.read(type); } boolean qualifierAdded = false; for (Annotation annotation : type.getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { beanConfigurator.addQualifier(annotation); qualifierAdded = true; } else if (beanManager.isScope(annotation.annotationType())) { beanConfigurator.scope(annotation.annotationType()); } else if (beanManager.isStereotype(annotation.annotationType())) { beanConfigurator.addStereotype(annotation.annotationType()); } if (annotation instanceof Named) { String name = ((Named) annotation).value(); if (name == null || name.isBlank()) { name = Introspector.decapitalize(type.getJavaClass().getSimpleName()); } beanConfigurator.name(name); } } if (type.isAnnotationPresent(Typed.class)) { Typed typed = type.getAnnotation(Typed.class); beanConfigurator.types(typed.value()); } else { for (Class c = type.getJavaClass(); c != Object.class && c != null; c = c.getSuperclass()) { beanConfigurator.addTypes(c); } beanConfigurator.addTypes(type.getJavaClass().getInterfaces()); beanConfigurator.addTypes(Object.class); } if (!qualifierAdded) { beanConfigurator.addQualifier(Default.Literal.INSTANCE); } beanConfigurator.addQualifier(Any.Literal.INSTANCE); return beanConfigurator; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/BeanUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import org.apache.deltaspike.core.util.metadata.builder.ImmutableInjectionPoint; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * A set of utility methods for working with beans. */ @Vetoed public abstract class BeanUtils { private BeanUtils() { // prevent instantiation } /** * Extract the qualifiers from a set of annotations. * * @param beanManager the beanManager to use to determine if an annotation is * a qualifier * @param annotations the annotations to check * @return any qualifiers present in annotations */ @SuppressWarnings("unchecked") public static Set getQualifiers(BeanManager beanManager, Iterable annotations) { Set qualifiers = new HashSet(); for (Annotation annotation : annotations) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } return qualifiers; } /** * Extract the qualifiers from a set of annotations. * * @param beanManager the beanManager to use to determine if an annotation is * a qualifier * @param annotations the annotations to check * @return any qualifiers present in annotations */ public static Set getQualifiers(BeanManager beanManager, Annotation[]... annotations) { Set qualifiers = new HashSet(); for (Annotation[] annotationArray : annotations) { for (Annotation annotation : annotationArray) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } } return qualifiers; } /** * @param annotated element to search in * @param targetType target type to search for * @param type of the Annotation which get searched * @return annotation instance extracted from the annotated member */ public static T extractAnnotation(Annotated annotated, Class targetType) { T result = annotated.getAnnotation(targetType); if (result == null) { for (Annotation annotation : annotated.getAnnotations()) { result = annotation.annotationType().getAnnotation(targetType); if (result != null) { break; } } } return result; } /** * Given a method, and the bean on which the method is declared, create a * collection of injection points representing the parameters of the method. * * @param the type declaring the method * @param method the method * @param declaringBean the bean on which the method is declared * @param beanManager the bean manager to use to create the injection points * @return the injection points */ public static List createInjectionPoints(AnnotatedMethod method, Bean declaringBean, BeanManager beanManager) { List injectionPoints = new ArrayList(); for (AnnotatedParameter parameter : method.getParameters()) { InjectionPoint injectionPoint = new ImmutableInjectionPoint(parameter, beanManager, declaringBean, false, false); injectionPoints.add(injectionPoint); } return injectionPoints; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * Helper methods for {@link ClassDeactivator} */ @Vetoed public abstract class ClassDeactivationUtils { private static final Logger LOG = Logger.getLogger(ClassDeactivationUtils.class.getName()); /** * This Map holds the ClassLoader as first level to make it possible to have different configurations per * WebApplication in an EAR or other Multi-ClassLoader scenario. * * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal. */ private static Map> classDeactivatorMap = new ConcurrentHashMap<>(); /** * Cache for the result. It won't contain many classes but it might be accessed frequently. * Valid entries are only true or false. If an entry isn't available or null, it gets calculated. */ private static Map, Boolean> activationStatusCache = new ConcurrentHashMap, Boolean>(); private static ProjectStage previouslyDetectedProjectStage; private ClassDeactivationUtils() { // prevent instantiation } /** * Flush the caches to prevent ClassLoader leaks. * This is called internally by DeltaSpike. * Users do not have to explicitly call this method. * Does not have side effects as the cache is idempotent anyway. */ public static void clearCache() { classDeactivatorMap.clear(); } /** * Evaluates if the given {@link Deactivatable} is active. * * @param targetClass {@link Deactivatable} under test. * @return true if it is active, false otherwise */ public static boolean isActivated(Class targetClass) { performProjectStageDependentCleanup(); //just to support parallel access to #isActivated (+ reset) in project-stage unit-test and development Map, Boolean> activeCache = activationStatusCache; Boolean activatedClassCacheEntry = activeCache.get(targetClass); if (activatedClassCacheEntry == null) { initDeactivatableCacheFor(targetClass, activeCache); activatedClassCacheEntry = activeCache.get(targetClass); } return activatedClassCacheEntry; } private static void performProjectStageDependentCleanup() { ProjectStage currentProjectStage = ProjectStageProducer.getInstance().getProjectStage(); if (previouslyDetectedProjectStage != currentProjectStage) { previouslyDetectedProjectStage = currentProjectStage; //don't use #clear to support parallel access to #isActivated (+ reset) without synchronization activationStatusCache = new ConcurrentHashMap, Boolean>(); //#clear is ok here due to the handling in the synchronized method #initDeactivatableCacheFor classDeactivatorMap.clear(); } else if (currentProjectStage == ProjectStage.UnitTest || currentProjectStage == ProjectStage.Development) { activationStatusCache = new ConcurrentHashMap, Boolean>(); } } private static synchronized void initDeactivatableCacheFor(Class targetClass, Map, Boolean> activeCache) { Boolean activatedClassCacheEntry = activeCache.get(targetClass); if (activatedClassCacheEntry != null) //double-check { return; } List classDeactivators = getClassDeactivators(); Boolean isActivated = Boolean.TRUE; Class deactivatedBy = null; LOG.fine("start evaluation if " + targetClass.getName() + " is de-/activated"); // we get the classActivators ordered by it's ordinal // thus the last one which returns != null 'wins' ;) for (ClassDeactivator classDeactivator : classDeactivators) { Boolean isLocallyActivated = classDeactivator.isActivated(targetClass); if (isLocallyActivated != null) { isActivated = isLocallyActivated; /* * Check and log the details across class-deactivators */ if (!isActivated) { deactivatedBy = classDeactivator.getClass(); LOG.fine("Deactivating class " + targetClass); } else if (deactivatedBy != null) { LOG.fine("Reactivation of: " + targetClass.getName() + " by " + classDeactivator.getClass().getName() + " - original deactivated by: " + deactivatedBy.getName() + ".\n" + "If that isn't the intended behaviour, you have to use a higher ordinal for " + deactivatedBy.getName()); } } } cacheResult(targetClass, isActivated, activeCache); } private static void cacheResult(Class targetClass, Boolean activated, Map, Boolean> activeCache) { activeCache.put(targetClass, activated); if (LOG.isLoggable(Level.FINE)) { LOG.fine("class: " + targetClass.getName() + " activated=" + activated); } } /** * @return the List of configured @{link ClassDeactivator}s for the current context ClassLoader. */ private static List getClassDeactivators() { ClassLoader classLoader = ClassUtils.getClassLoader(null); List classDeactivators = classDeactivatorMap.get(classLoader); if (classDeactivators == null) { return initConfiguredClassDeactivators(classLoader); } return classDeactivators; } //synchronized isn't needed - #initDeactivatableCacheFor is already synchronized private static List initConfiguredClassDeactivators(ClassLoader classLoader) { List classDeactivatorClassNames = ConfigResolver.getAllPropertyValues(ClassDeactivator.class.getName()); List classDeactivators = new ArrayList(); for (String classDeactivatorClassName : classDeactivatorClassNames) { LOG.fine("processing ClassDeactivator: " + classDeactivatorClassName); try { ClassDeactivator currentClassDeactivator = (ClassDeactivator) ClassUtils.instantiateClassForName(classDeactivatorClassName); classDeactivators.add(currentClassDeactivator); } catch (Exception e) { LOG.warning(classDeactivatorClassName + " can't be instantiated"); throw new IllegalStateException(e); } } classDeactivatorMap.put(classLoader, classDeactivators); return classDeactivators; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.jar.Manifest; import java.util.jar.Attributes; import java.net.URL; /** * Util methods for classes, {@link ClassLoader} and {@link Manifest} handling. * * Abstract to not get picked up as CDI bean on old containers. */ @Vetoed public abstract class ClassUtils { /** * Constructor which prevents the instantiation of this class */ private ClassUtils() { // prevent instantiation } /** * Detect the right ClassLoader. * The lookup order is determined by: *
    *
  1. ContextClassLoader of the current Thread
  2. *
  3. ClassLoader of the given Object 'o'
  4. *
  5. ClassLoader of this very ClassUtils class
  6. *
* * @param o if not null it may get used to detect the classloader. * @return The {@link ClassLoader} which should get used to create new instances */ public static ClassLoader getClassLoader(Object o) { return getClassLoaderInternal(o); } private static ClassLoader getClassLoaderInternal(Object o) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null && o != null) { loader = o.getClass().getClassLoader(); } if (loader == null) { loader = ClassUtils.class.getClassLoader(); } return loader; } /** * Checks whether the CDI rules for proxyable beans are met. * See * * CDI spec unproxyable bean types * * @param type * @return {@code true} if all proxy conditions are met, {@code false} otherwise */ public static boolean isProxyableClass(Type type) { Class clazz = null; if (type instanceof Class) { clazz = (Class) type; } if (type instanceof ParameterizedType && ((ParameterizedType) type).getRawType() instanceof Class) { clazz = (Class) ((ParameterizedType) type).getRawType(); } if (clazz == null) { return false; } // classes which don’t have a non-private constructor with no parameters try { Constructor constructor = clazz.getConstructor(); if (Modifier.isPrivate(constructor.getModifiers())) { return false; } } catch (NoSuchMethodException e) { return false; } // classes which are declared final if (Modifier.isFinal(clazz.getModifiers())) { return false; } // classes which have non-static, final methods with public, protected or default visibility, for (Method method : clazz.getMethods()) { if (method.getDeclaringClass() == Object.class) { continue; } if (!method.isBridge() && !method.isSynthetic() && !Modifier.isStatic(method.getModifiers()) && !Modifier.isPrivate(method.getModifiers()) && Modifier.isFinal(method.getModifiers())) { return false; } } // primitive types, // and array types. if (clazz.isPrimitive() || clazz.isArray()) { return false; } return true; } /** * Tries to load a class based on the given name and interface or abstract class. * @param name name of the concrete class * @param targetType target type (interface or abstract class) * @param current type * @return loaded class or null if it isn't in the classpath */ public static Class tryToLoadClassForName(String name, Class targetType) { return (Class) tryToLoadClassForName(name); } /** * Tries to load a class based on the given name and interface or abstract class. * @param name name of the concrete class * @param targetType target type (interface or abstract class) * @param classLoader The {@link ClassLoader}. * @param current type * @return loaded class or null if it isn't in the classpath */ public static Class tryToLoadClassForName(String name, Class targetType, ClassLoader classLoader) { return (Class) tryToLoadClassForName(name, classLoader); } /** * Tries to load a class based on the given name * @param name name of the class * @return loaded class or null if it isn't in the classpath */ public static Class tryToLoadClassForName(String name) { try { return loadClassForName(name); } catch (ClassNotFoundException e) { //do nothing - it's just a try return null; } } /** * Tries to load a class based on the given name * @param name name of the class * @param classLoader The {@link ClassLoader}. * @return loaded class or null if it isn't in the classpath */ public static Class tryToLoadClassForName(String name, ClassLoader classLoader) { try { return classLoader.loadClass(name); } catch (ClassNotFoundException e) { //do nothing - it's just a try return null; } } /** * Loads class for the given name * @param name name of the class * @return loaded class * @throws ClassNotFoundException if the class can't be loaded */ public static Class loadClassForName(String name) throws ClassNotFoundException { try { // Try WebApp ClassLoader first return Class.forName(name, false, // do not initialize for faster startup getClassLoader(null)); } catch (ClassNotFoundException ignore) { // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib) return Class.forName(name, false, // do not initialize for faster startup ClassUtils.class.getClassLoader()); } } /** * Instantiates a given class via the default constructor * @param targetClass class which should be instantiated * @param current type * @return created instance or null if the instantiation failed */ public static T tryToInstantiateClass(Class targetClass) { try { return targetClass.newInstance(); } catch (InstantiationException e) { //do nothing - it was just a try } catch (IllegalAccessException e) { //do nothing - it was just a try } return null; } /** * Tries to instantiate a class for the given name and type via the default constructor * @param className name of the class * @param targetType target type * @param current type * @return created instance or null if the instantiation failed */ public static T tryToInstantiateClassForName(String className, Class targetType) { Object result = tryToInstantiateClassForName(className); //noinspection unchecked return result != null ? (T) result : null; } /** * Tries to instantiate a class for the given name via the default constructor * @param className name of the class * @return created instance or null if the instantiation failed */ public static Object tryToInstantiateClassForName(String className) { try { return instantiateClassForName(className); } catch (Exception e) { //do nothing - it was just a try } return null; } /** * Creates an instance for the given class-name * @param className name of the class which should be instantiated * @return created instance * @throws ClassNotFoundException if the instantiation failed * @throws IllegalAccessException if the instantiation failed * @throws InstantiationException if the instantiation failed */ public static Object instantiateClassForName(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException { return loadClassForName(className).newInstance(); } /** * Reads the version of the jar which contains the given class * @param targetClass class within the jar * @return version-string which has been found in the manifest or null if there is no version information available */ public static String getJarVersion(Class targetClass) { String manifestFileLocation = getManifestFileLocationOfClass(targetClass); try { return new Manifest(new URL(manifestFileLocation).openStream()) .getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION); } catch (Exception e) { return null; } } /** * Reads the VCS revision which was used for creating the jar * @param targetClass class within the jar * @return revision-string which has been found in the manifest or null if there is no information available */ public static String getRevision(Class targetClass) { String manifestFileLocation = getManifestFileLocationOfClass(targetClass); try { return new Manifest(new URL(manifestFileLocation).openStream()) .getMainAttributes().getValue("Revision"); } catch (Exception e) { return null; } } private static String getManifestFileLocationOfClass(Class targetClass) { String manifestFileLocation; try { manifestFileLocation = getManifestLocation(targetClass); } catch (Exception e) { //in this case we have a proxy manifestFileLocation = getManifestLocation(targetClass.getSuperclass()); } return manifestFileLocation; } private static String getManifestLocation(Class targetClass) { String classFilePath = targetClass.getCanonicalName().replace('.', '/') + ".class"; String manifestFilePath = "/META-INF/MANIFEST.MF"; String classLocation = targetClass.getResource(targetClass.getSimpleName() + ".class").toString(); return classLocation.substring(0, classLocation.indexOf(classFilePath) - 1) + manifestFilePath; } /** * Checks if the given class contains a method with the same signature. * * @param targetClass The class to check * @param method The source method * @return if it contains a method with the same signature. */ public static boolean containsMethod(Class targetClass, Method method) { return extractMethod(targetClass, method) != null; } /** * Extracts a method with same signature as the source method. * * @param clazz The target class * @param sourceMethod The source method. * @return the extracted method or null */ public static Method extractMethod(Class clazz, Method sourceMethod) { try { String name = sourceMethod.getName(); return clazz != null ? clazz.getMethod(name, sourceMethod.getParameterTypes()) : null; } catch (NoSuchMethodException e) { return null; } } /** * Extract a method with the given name and parameterTypes. * Return {@code null} if no such visible method exists on the given class. * * @param clazz * @param methodName * @param parameterTypes * @return */ public static Method extractMethod(Class clazz, String methodName, Class... parameterTypes) { try { return clazz != null ? clazz.getMethod(methodName, parameterTypes) : null; } catch (NoSuchMethodException e) { return null; } } /** * Checks if the given class has a method with the same signature, taking in to account generic types * @param targetClass * @param method * @return if it contains a method with the same signature. */ public static boolean containsPossiblyGenericMethod(Class targetClass, Method method) { return extractPossiblyGenericMethod(targetClass, method) != null; } /** * Extracts a method matching the source method, allowing generic type parameters to be substituted as * long as they are properly castable. * * @param clazz The target class * @param sourceMethod The source method. * @return the extracted method or null */ public static Method extractPossiblyGenericMethod(Class clazz, Method sourceMethod) { Method exactMethod = extractMethod(clazz, sourceMethod); if (exactMethod == null) { String methodName = sourceMethod.getName(); Class[] parameterTypes = sourceMethod.getParameterTypes(); for (Method method : clazz.getMethods()) { if (method.getName().equals(methodName) && allSameType(method.getParameterTypes(), parameterTypes)) { return method; } } return null; } else { return exactMethod; } } /** * Whether all of the parameters from left to right are equivalent. * In order to support generics, it takes the form of left.isAssignableFrom(right) * @param left left hand side to check * @param right right hand side to check * @return whether all of the left classes can be assigned to the right hand side types */ private static boolean allSameType(Class[] left, Class[] right) { if (left.length != right.length) { return false; } for (int p = 0; p < left.length; p++) { if (!left[p].isAssignableFrom(right[p])) { return false; } } return true; } public static boolean returns(Method method, Class clazz) { return method.getReturnType().isAssignableFrom(clazz); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ContextUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import java.lang.annotation.Annotation; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; /** * A set of utility methods for working with contexts. */ @Vetoed public abstract class ContextUtils { private ContextUtils() { // prevent instantiation } /** * Checks if the context for the given scope annotation is active. * * @param scopeAnnotationClass The scope annotation (e.g. @RequestScoped.class) * @return If the context is active. */ public static boolean isContextActive(Class scopeAnnotationClass) { return isContextActive(scopeAnnotationClass, BeanManagerProvider.getInstance().getBeanManager()); } /** * Checks if the context for the given scope annotation is active. * * @param scopeAnnotationClass The scope annotation (e.g. @RequestScoped.class) * @param beanManager The {@link BeanManager} * @return If the context is active. */ public static boolean isContextActive(Class scopeAnnotationClass, BeanManager beanManager) { try { if (beanManager.getContext(scopeAnnotationClass) == null || !beanManager.getContext(scopeAnnotationClass).isActive()) { return false; } } catch (ContextNotActiveException e) { return false; } return true; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ExceptionUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.Constructor; @Vetoed public abstract class ExceptionUtils { private ExceptionUtils() { // prevent instantiation } public static RuntimeException throwAsRuntimeException(Throwable throwable) { //Attention: helper which allows to use a trick to throw // a catched checked exception without a wrapping exception new ExceptionHelper().throwException(throwable); return null; //not needed due to the helper trick, but it's easier for using it } public static void changeAndThrowException(Throwable throwable, String customMessage) { Throwable newThrowable = createNewException(throwable, customMessage); //Attention: helper which allows to use a trick to throw a cached checked exception without a wrapping exception new ExceptionHelper().throwException(newThrowable); } private static Throwable createNewException(Throwable throwable, String message) { Class throwableClass = throwable.getClass(); try { Constructor constructor = throwableClass.getDeclaredConstructor(String.class); constructor.setAccessible(true); Throwable result = constructor.newInstance(message); result.initCause(throwable.getCause()); return result; } catch (Exception e) { //use the original exception if there is any issue return throwable; } } @SuppressWarnings({ "unchecked" }) private static class ExceptionHelper { private void throwException(Throwable exception) throws T { try { //exception-type is only checked at compile-time throw (T) exception; } catch (ClassCastException e) { //doesn't happen with existing JVMs! - if that changes the local ClassCastException needs to be ignored //-> throw original exception if (e.getStackTrace()[0].toString().contains(getClass().getName())) { if (exception instanceof RuntimeException) { throw (RuntimeException) exception; } throw new RuntimeException(exception); } //if the exception to throw is a ClassCastException, throw it throw e; } } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/HierarchyDiscovery.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * Utility class for resolving all bean types from a given type. */ //X TODO: Look at merging this with ClassUtils perhaps //X TODO: JavaDoc //X TODO review @Vetoed public class HierarchyDiscovery { private final Type type; private Map> types; public HierarchyDiscovery(Type type) { this.type = type; } protected void add(Class clazz, Type type) { types.put(type, clazz); } public Set getTypeClosure() { if (types == null) { init(); } // Return an independent set with no ties to the BiMap used return new HashSet(types.keySet()); } private void init() { types = new HashMap>(); try { discoverTypes(type); } catch (StackOverflowError e) { Logger logger = Logger.getLogger(HierarchyDiscovery.class.getName()); logger.log(Level.WARNING, "type: " + type.toString(), e); Thread.dumpStack(); throw e; } } public Type getResolvedType() { if (type instanceof Class) { Class clazz = (Class) type; return resolveType(clazz); } return type; } private void discoverTypes(Type type) { if (type != null) { if (type instanceof Class) { Class clazz = (Class) type; add(clazz, resolveType(clazz)); discoverFromClass(clazz); } else { Class clazz = null; if (type instanceof ParameterizedType) { Type rawType = ((ParameterizedType) type).getRawType(); if (rawType instanceof Class) { discoverFromClass((Class) rawType); clazz = (Class) rawType; } } add(clazz, type); } } } private Type resolveType(Class clazz) { if (clazz.getTypeParameters().length > 0) { TypeVariable[] actualTypeParameters = clazz.getTypeParameters(); @SuppressWarnings("UnnecessaryLocalVariable") ParameterizedType parameterizedType = new ParameterizedTypeImpl(clazz, actualTypeParameters, clazz.getDeclaringClass()); return parameterizedType; } else { return clazz; } } private void discoverFromClass(Class clazz) { discoverTypes(resolveType(type, type, clazz.getGenericSuperclass())); for (Type c : clazz.getGenericInterfaces()) { discoverTypes(resolveType(type, type, c)); } } /** * Gets the actual types by resolving TypeParameters. * * @return actual type */ private Type resolveType(Type beanType, Type beanType2, Type type) { if (type instanceof ParameterizedType) { if (beanType instanceof ParameterizedType) { return resolveParameterizedType((ParameterizedType) beanType, (ParameterizedType) type); } if (beanType instanceof Class) { return resolveType(((Class) beanType).getGenericSuperclass(), beanType2, type); } } if (type instanceof TypeVariable) { if (beanType instanceof ParameterizedType) { return resolveTypeParameter((ParameterizedType) beanType, beanType2, (TypeVariable) type); } if (beanType instanceof Class) { return resolveType(((Class) beanType).getGenericSuperclass(), beanType2, type); } } return type; } private Type resolveParameterizedType(ParameterizedType beanType, ParameterizedType parameterizedType) { Type rawType = parameterizedType.getRawType(); Type[] actualTypes = parameterizedType.getActualTypeArguments(); Type resolvedRawType = resolveType(beanType, beanType, rawType); Type[] resolvedActualTypes = new Type[actualTypes.length]; for (int i = 0; i < actualTypes.length; i++) { resolvedActualTypes[i] = resolveType(beanType, beanType, actualTypes[i]); } // reconstruct ParameterizedType by types resolved TypeVariable. return new ParameterizedTypeImpl(resolvedRawType, resolvedActualTypes, parameterizedType.getOwnerType()); } private Type resolveTypeParameter(ParameterizedType type, Type beanType, TypeVariable typeVariable) { // step1. raw type Class actualType = (Class) type.getRawType(); TypeVariable[] typeVariables = actualType.getTypeParameters(); Type[] actualTypes = type.getActualTypeArguments(); for (int i = 0; i < typeVariables.length; i++) { if (typeVariables[i].equals(typeVariable) && !actualTypes[i].equals(typeVariable)) { return resolveType(this.type, beanType, actualTypes[i]); } } // step2. generic super class Type genericSuperType = actualType.getGenericSuperclass(); Type resolvedGenericSuperType = resolveType(genericSuperType, beanType, typeVariable); if (!(resolvedGenericSuperType instanceof TypeVariable)) { return resolvedGenericSuperType; } // step3. generic interfaces if (beanType instanceof ParameterizedType) { for (Type interfaceType : ((Class) ((ParameterizedType) beanType).getRawType()).getGenericInterfaces()) { Type resolvedType = resolveType(interfaceType, interfaceType, typeVariable); if (!(resolvedType instanceof TypeVariable)) { return resolvedType; } } } // don't resolve type variable return typeVariable; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterUtil.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import jakarta.enterprise.inject.Vetoed; @Vetoed public abstract class ParameterUtil { private static boolean parameterSupported = true; private static Class parameterClass; private static Method getNameMethod; private static Method getParametersMethod; static { try { parameterClass = Class.forName("java.lang.reflect.Parameter"); getNameMethod = parameterClass.getMethod("getName"); getParametersMethod = Method.class.getMethod("getParameters"); } catch (Exception e) { parameterSupported = false; parameterClass = null; getNameMethod = null; getParametersMethod = null; } } public static boolean isParameterSupported() { return parameterSupported; } public static String getName(Method method, int parameterIndex) { if (!isParameterSupported() || method == null) { return null; } try { Object[] parameters = (Object[]) getParametersMethod.invoke(method); return (String) getNameMethod.invoke(parameters[parameterIndex]); } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } return null; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ParameterizedTypeImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Arrays; /** * A basic implementation of {@link ParameterizedType}. */ @Vetoed class ParameterizedTypeImpl implements ParameterizedType { private final Type[] actualTypeArguments; private final Type rawType; private final Type ownerType; ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type ownerType) { this.actualTypeArguments = actualTypeArguments; this.rawType = rawType; this.ownerType = ownerType; } public Type[] getActualTypeArguments() { return Arrays.copyOf(actualTypeArguments, actualTypeArguments.length); } public Type getOwnerType() { return ownerType; } public Type getRawType() { return rawType; } @Override public int hashCode() { return Arrays.hashCode(actualTypeArguments) ^ (ownerType == null ? 0 : ownerType.hashCode()) ^ (rawType == null ? 0 : rawType.hashCode()); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj instanceof ParameterizedType) { ParameterizedType that = (ParameterizedType) obj; Type thatOwnerType = that.getOwnerType(); Type thatRawType = that.getRawType(); return (ownerType == null ? thatOwnerType == null : ownerType.equals(thatOwnerType)) && (rawType == null ? thatRawType == null : rawType.equals(thatRawType)) && Arrays.equals(actualTypeArguments, that.getActualTypeArguments()); } else { return false; } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(rawType); if (actualTypeArguments.length > 0) { sb.append("<"); for (Type actualType : actualTypeArguments) { sb.append(actualType); sb.append(","); } sb.delete(sb.length() - 1, sb.length()); sb.append(">"); } return sb.toString(); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProjectStageProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import java.io.Serializable; import java.util.logging.Logger; /** *

Produces {@link org.apache.deltaspike.core.api.projectstage.ProjectStage} configurations.

* *

The producer will try to detect the currently active ProjectStage on startup * and use that for all generated fields.

*

Usage:

* Simply inject the current ProjectStage into any bean: *
 * public class MyBean {
 *   private @Inject ProjectStage projectStage;
 *
 *   public void fn() {
 *     if(projectStage == ProjectStage.Production) {
 *        // do some production stuff...
 *     }
 *   }
 * }
 * 
* *

Please note that there can only be one ProjectStage per EAR.

*/ @ApplicationScoped public class ProjectStageProducer implements Serializable { /** * These config keys will get used to detect the ProjectStage. * We iterate through them until we find the first non-empty value. */ public static final String[] CONFIG_SETTING_KEYS = { //TODO discuss it "org.apache.deltaspike.ProjectStage", "jakarta.faces.PROJECT_STAGE", "faces.PROJECT_STAGE" }; protected static final Logger LOG = Logger.getLogger(ProjectStageProducer.class.getName()); private static final long serialVersionUID = -2987762608635612074L; /** * The detected ProjectStage */ private static volatile ProjectStage projectStage; /** * for the singleton factory */ private static volatile ProjectStageProducer projectStageProducer; /** * ProjectStageProducers must only be created by subclassing producers */ protected ProjectStageProducer() { } /** * We can only produce @Dependent scopes since an enum is final. * @return current ProjectStage */ @Produces @Dependent @Default public ProjectStage getProjectStage() { if (projectStage == null) { //triggers initialization getInstance(); } return projectStage; } /** *

This factory method should only get used if there is absolutely no way * to get the current {@link ProjectStage} via @Inject.

* *

* * @return the ProjectStageProducer instance. */ public static ProjectStageProducer getInstance() { if (projectStageProducer == null) { lazyInit(); } if (projectStage == null) { projectStageProducer.initProjectStage(); } return projectStageProducer; } private static synchronized void lazyInit() { // switch into paranoia mode if (projectStageProducer != null) { return; } ProjectStageProducer newProjectStageProducer = new ProjectStageProducer(); newProjectStageProducer.initProjectStage(); projectStageProducer = newProjectStageProducer; } /** * Resolves the project-stage configured for DeltaSpike * @return the resolved {@link ProjectStage} or null if none defined. */ protected ProjectStage resolveProjectStage() { for (String configLocation : CONFIG_SETTING_KEYS) { String stageName = ConfigResolver.getPropertyValue(configLocation); if (stageName != null && !stageName.isEmpty()) { return ProjectStage.valueOf(stageName); } } return null; } protected void initProjectStage() { // switch into paranoia mode synchronized (ProjectStageProducer.class) { if (projectStage == null) { projectStage = resolveProjectStage(); if (projectStage == null) { projectStage = ProjectStage.Production; } LOG.info("Computed the following DeltaSpike ProjectStage: " + projectStage); } } } /* * Methods which might be needed for unit tests */ /** * Can be used esp. for internal tests. * Usage: *
     * new ProjectStageProducer() {
     *     @Override
     *     protected void reset() { super.reset(); }
     * }.reset();
     * 
*/ protected void reset() { resetCache(); } /** * This function exists to prevent findbugs to complain about * setting a static member from a non-static function. */ private static void resetCache() { projectStage = null; projectStageProducer = null; } /** * This function can be used to manually set the ProjectStage for the application. * This is e.g. useful in unit tests. * @param ps the ProjectStage to set */ public static void setProjectStage(ProjectStage ps) { if (projectStage == null) { LOG.info("change project-stage to " + ps); } else if (!projectStage.equals(ps)) { LOG.info("change project-stage from " + projectStage + " to " + ps); } projectStage = ps; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/PropertyFileUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URISyntaxException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.Locale; import java.util.Properties; import java.util.ResourceBundle; import java.util.Vector; @Vetoed public abstract class PropertyFileUtils { /** * Constructor which prevents the instantiation of this class */ private PropertyFileUtils() { // prevent instantiation } public static Enumeration resolvePropertyFiles(String propertyFileName) throws IOException { if (propertyFileName != null && (propertyFileName.contains("://") || propertyFileName.startsWith("file:"))) { // the given string is actually already an URL Vector propertyFileUrls = new Vector(); URL url = new URL(propertyFileName); if (propertyFileName.startsWith("file:")) { try { File file = new File(url.toURI()); if (file.exists()) { propertyFileUrls.add(url); } } catch (URISyntaxException e) { throw new IllegalStateException("Property file URL is malformed", e); } } else { propertyFileUrls.add(url); } return propertyFileUrls.elements(); } if (propertyFileName != null) { File file = new File(propertyFileName); if (file.exists()) { return Collections.enumeration(Collections.singleton(file.toURI().toURL())); } } ClassLoader cl = ClassUtils.getClassLoader(null); Enumeration propertyFileUrls = cl.getResources(propertyFileName); //fallback - see DELTASPIKE-98 if (!propertyFileUrls.hasMoreElements()) { cl = PropertyFileUtils.class.getClassLoader(); propertyFileUrls = cl.getResources(propertyFileName); } return propertyFileUrls; } public static Properties loadProperties(URL url) { Properties props = new Properties(); InputStream inputStream = null; try { inputStream = url.openStream(); if (inputStream != null) { props.load(inputStream); } } catch (IOException e) { throw new IllegalStateException(e); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { // no worries, means that the file is already closed } } return props; } /** * @return the ResourceBundle for the current default Locale */ public static ResourceBundle getResourceBundle(String bundleName) { return getResourceBundle(bundleName, Locale.getDefault()); } /** * This uses the correct ThreadContextClassLoader if deployed in an Container. * @return the ResourceBundle for the current Locale */ public static ResourceBundle getResourceBundle(String bundleName, Locale locale) { return ResourceBundle.getBundle(bundleName, locale, ClassUtils.getClassLoader(null)); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ProxyUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; /** * Helper for proxies */ @Vetoed public abstract class ProxyUtils { private ProxyUtils() { // prevent instantiation } /** * @param currentClass current class * @return class of the real implementation */ public static Class getUnproxiedClass(Class currentClass) { Class unproxiedClass = currentClass; while (isProxiedClass(unproxiedClass)) { unproxiedClass = unproxiedClass.getSuperclass(); } return unproxiedClass; } /** * Analyses if the given class is a generated proxy class * @param currentClass current class * @return true if the given class is a known proxy class, false otherwise */ public static boolean isProxiedClass(Class currentClass) { if (currentClass == null || currentClass.getSuperclass() == null) { return false; } String name = currentClass.getName(); return name.startsWith(currentClass.getSuperclass().getName()) && (name.contains("$$") // CDI || name.contains("_ClientProxy") //Quarkus || name.contains("$HibernateProxy$")); // Hibernate } public static List> getProxyAndBaseTypes(Class proxyClass) { List> result = new ArrayList>(); result.add(proxyClass); if (isInterfaceProxy(proxyClass)) { for (Class currentInterface : proxyClass.getInterfaces()) { if (proxyClass.getName().startsWith(currentInterface.getName())) { result.add(currentInterface); } } } else { Class unproxiedClass = proxyClass.getSuperclass(); result.add(unproxiedClass); while (isProxiedClass(unproxiedClass)) { unproxiedClass = unproxiedClass.getSuperclass(); result.add(unproxiedClass); } } return result; } public static boolean isInterfaceProxy(Class proxyClass) { Class[] interfaces = proxyClass.getInterfaces(); if (Proxy.class.equals(proxyClass.getSuperclass()) && interfaces != null && interfaces.length > 0) { return true; } if (proxyClass.getSuperclass() != null && !proxyClass.getSuperclass().equals(Object.class)) { return false; } if (proxyClass.getName().contains("$$")) { for (Class currentInterface : interfaces) { if (proxyClass.getName().startsWith(currentInterface.getName())) { return true; } } } return false; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ReflectionUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.util.Nonbinding; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.WildcardType; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Utilities for common reflection based actions. Some are basic Java Reflection based, others are CDI based. */ @Vetoed public abstract class ReflectionUtils { private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private ReflectionUtils() { // prevent instantiation } /** * Get all the declared fields on the class hierarchy. This will * return overridden fields. * * @param clazz The class to search * @return the set of all declared fields or an empty set if there are none */ public static Set getAllDeclaredFields(Class clazz) { HashSet fields = new HashSet(); for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { Collections.addAll(fields, c.getDeclaredFields()); } return fields; } /** * Search the class hierarchy for a field with the given name. Will return * the nearest match, starting with the class specified and searching up the * hierarchy. * * @param clazz The class to search * @param name The name of the field to search for * @return The field found, or null if no field is found */ public static Field tryToFindDeclaredField(Class clazz, String name) { for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { try { return c.getDeclaredField(name); } catch (NoSuchFieldException e) { // No-op, we continue looking up the class hierarchy } } return null; } /** * Get all the declared methods on the class hierarchy. This will * return overridden methods. * * @param clazz The class to search * @return the set of all declared methods or an empty set if there are none */ public static Set getAllDeclaredMethods(Class clazz) { HashSet methods = new HashSet(); for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { Collections.addAll(methods, c.getDeclaredMethods()); } return methods; } private static String buildInvokeMethodErrorMessage(Method method, Object obj, Object... args) { StringBuilder message = new StringBuilder(String.format( "Details: Exception invoking method [%s] on object [%s], using arguments [", method.getName(), obj)); if (args != null) { for (int i = 0; i < args.length; i++) { message.append(i > 0 ? ", " : "").append(args[i]); } } message.append("]"); return message.toString(); } /** *

* Invoke the method on the instance, with any arguments specified, casting * the result of invoking the method to the expected return type. *

*

*

* This method wraps {@link Method#invoke(Object, Object...)}, converting the * checked exceptions that {@link Method#invoke(Object, Object...)} specifies * to runtime exceptions. *

*

*

* If instructed, this method attempts to set the accessible flag of the method in a * {@link java.security.PrivilegedAction} before invoking the method. *

* * @param setAccessible flag indicating whether method should first be set as * accessible * @param method the method to invoke * @param instance the instance to invoke the method * @param args the arguments to the method * @return the result of invoking the method, or null if the method's return * type is void * @throws RuntimeException if this Method object enforces Java * language access control and the underlying method is * inaccessible or if the underlying method throws an exception or * if the initialization provoked by this method fails. * @throws IllegalArgumentException if the method is an instance method and * the specified instance argument is not an instance * of the class or interface declaring the underlying method (or * of a subclass or implementor thereof); if the number of actual * and formal parameters differ; if an unwrapping conversion for * primitive arguments fails; or if, after possible unwrapping, a * parameter value cannot be converted to the corresponding formal * parameter type by a method invocation conversion. * @throws NullPointerException if the specified instance is * null and the method is an instance method. * @throws ClassCastException if the result of invoking the method cannot be * cast to the expectedReturnType * @throws ExceptionInInitializerError if the initialization provoked by this * method fails. * @see Method#invoke(Object, Object...) */ public static T invokeMethod(Object instance, Method method, Class expectedReturnType, boolean setAccessible, Object... args) { if (setAccessible && !method.isAccessible()) { method.setAccessible(true); } try { return expectedReturnType.cast(method.invoke(instance, args)); } catch (InvocationTargetException e) { //re-visit DELTASPIKE-299 before changing this part ExceptionUtils.throwAsRuntimeException(e.getCause()); //won't happen return null; } catch (Exception e) { String customMessage = createCustomMessage(e, method, instance, args); ExceptionUtils.changeAndThrowException(e, customMessage); //won't happen return null; } } private static String createCustomMessage(Exception e, Method method, Object targetObject, Object... arguments) { return e.getMessage() + buildInvokeMethodErrorMessage(method, targetObject, arguments); } /** * Extract the raw type, given a type. * * @param the type * @param type the type to extract the raw type from * @return the raw type, or null if the raw type cannot be determined. */ @SuppressWarnings("unchecked") public static Class getRawType(Type type) { if (type instanceof Class) { return (Class) type; } else if (type instanceof ParameterizedType && ((ParameterizedType) type).getRawType() instanceof Class) { return (Class) ((ParameterizedType) type).getRawType(); } return null; } /** * Check if a class is serializable. * * @param clazz The class to check * @return true if the class implements serializable or is a primitive (needed for type {@link Void} */ public static boolean isSerializable(Class clazz) { return clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz); } /** * Checks if class is final * * @param clazz The class to check * @return True if final, false otherwise */ public static boolean isFinal(Class clazz) { return Modifier.isFinal(clazz.getModifiers()); } /** * Checks if member is final * * @param member The member to check * @return True if final, false otherwise */ public static boolean isFinal(Member member) { return Modifier.isFinal(member.getModifiers()); } /** * Checks if member is private * * @param member The member to check * @return True if final, false otherwise */ public static boolean isPrivate(Member member) { return Modifier.isPrivate(member.getModifiers()); } public static boolean isPackagePrivate(int mod) { return !(Modifier.isPrivate(mod) || Modifier.isProtected(mod) || Modifier.isPublic(mod)); } /** * Checks if type is static * * @param type Type to check * @return True if static, false otherwise */ public static boolean isStatic(Class type) { return Modifier.isStatic(type.getModifiers()); } /** * Checks if member is static * * @param member Member to check * @return True if static, false otherwise */ public static boolean isStatic(Member member) { return Modifier.isStatic(member.getModifiers()); } public static boolean isTransient(Member member) { return Modifier.isTransient(member.getModifiers()); } /** * Checks if a method is abstract */ public static boolean isAbstract(Method method) { return Modifier.isAbstract(method.getModifiers()); } /** * Gets the actual type arguments of a class * * @param clazz The class to examine * @return The type arguments */ public static Type[] getActualTypeArguments(Class clazz) { if (clazz == null) { throw new IllegalArgumentException("null isn't supported"); } return clazz.getTypeParameters(); } /** * Gets the actual type arguments of a Type * * @param type The type to examine * @return The type arguments */ public static Type[] getActualTypeArguments(Type type) { if (type instanceof Class) { return getActualTypeArguments((Class)type); } throw new IllegalArgumentException((type != null ? type.getClass().getName() : "null") + " isn't supported"); } /** * Checks if raw type is array type * * @param rawType The raw type to check * @return True if array, false otherwise */ public static boolean isArrayType(Class rawType) { return rawType.isArray(); } /** * Checks if type is parameterized type * * @param type The type to check * @return True if parameterized, false otherwise */ public static boolean isParameterizedType(Class type) { return type.getTypeParameters().length > 0; } public static boolean isParameterizedTypeWithWildcard(Class type) { if (isParameterizedType(type)) { return containsWildcards(type.getTypeParameters()); } else { return false; } } private static boolean containsWildcards(Type[] types) { for (Type type : types) { if (type instanceof WildcardType) { return true; } } return false; } public static boolean isPrimitive(Type type) { Class rawType = getRawType(type); return rawType != null && rawType.isPrimitive(); } public static int calculateHashCodeOfAnnotation(Annotation annotation, boolean skipNonbindingMembers) { Class annotationClass = annotation.annotationType(); // the hashCode of an Annotation is calculated solely via the hashCodes // of it's members. If there are no members, it is 0. // thus we first need to get the annotation-class hashCode int hashCode = calculateHashCodeOfType(annotationClass); // and now add the hashCode of all it's Nonbinding members // the following algorithm is defined by the Annotation class definition // see the JavaDoc for Annotation! // we only change it so far that we skip evaluating @Nonbinding members final Method[] members = annotationClass.getDeclaredMethods(); for (Method member : members) { if (skipNonbindingMembers && member.isAnnotationPresent(Nonbinding.class)) { // ignore the non binding continue; } // Member value final Object object = invokeMethod(annotation, member, Object.class, true, EMPTY_OBJECT_ARRAY); final int value; if (object.getClass().isArray()) { Class type = object.getClass().getComponentType(); if (type.isPrimitive()) { if (Long.TYPE == type) { value = Arrays.hashCode((long[]) object); } else if (Integer.TYPE == type) { value = Arrays.hashCode((int[])object); } else if (Short.TYPE == type) { value = Arrays.hashCode((short[])object); } else if (Double.TYPE == type) { value = Arrays.hashCode((double[])object); } else if (Float.TYPE == type) { value = Arrays.hashCode((float[])object); } else if (Boolean.TYPE == type) { value = Arrays.hashCode((boolean[])object); } else if (Byte.TYPE == type) { value = Arrays.hashCode((byte[])object); } else if (Character.TYPE == type) { value = Arrays.hashCode((char[])object); } else { value = 0; } } else { value = Arrays.hashCode((Object[])object); } } else { value = object.hashCode(); } hashCode = 29 * hashCode + value; hashCode = 29 * hashCode + member.getName().hashCode(); } return hashCode; } /** * We need this method as some weird JVMs return 0 as hashCode for classes. * In that case we return the hashCode of the String. */ public static int calculateHashCodeOfType(Type type) { int typeHash = type.hashCode(); if (typeHash == 0 && type instanceof Class) { return ((Class)type).getName().hashCode(); // the type.toString() is always the same: "java.lang.Class@" // was: return type.toString().hashCode(); } return typeHash; } public static boolean hasSameSignature(Method a, Method b) { return a.getName().equals(b.getName()) && a.getReturnType().equals(b.getReturnType()) && Arrays.equals(a.getParameterTypes(), b.getParameterTypes()); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ServiceUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import org.apache.deltaspike.core.spi.activation.Deactivatable; import jakarta.enterprise.inject.Vetoed; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import java.util.logging.Logger; /** * Allows handling the lookup (with fallbacks) in a central place. * See DELTASPIKE-97 */ @Vetoed public abstract class ServiceUtils { private static final Logger LOG = Logger.getLogger(ServiceUtils.class.getName()); private ServiceUtils() { // prevent instantiation } public static List loadServiceImplementations(Class serviceType) { return loadServiceImplementations(serviceType, false); } public static List loadServiceImplementations(Class serviceType, boolean ignoreServicesWithMissingDependencies) { return loadServiceImplementations(serviceType, ignoreServicesWithMissingDependencies, null); } public static List loadServiceImplementations(Class serviceType, boolean ignoreServicesWithMissingDependencies, ClassLoader classLoader) { List result = new ArrayList(); Iterator servicesIterator; if (classLoader != null) { servicesIterator = ServiceLoader.load(serviceType, classLoader).iterator(); } else { servicesIterator = ServiceLoader.load(serviceType).iterator(); } if (!servicesIterator.hasNext()) { ClassLoader fallbackClassLoader = ServiceUtils.class.getClassLoader(); servicesIterator = ServiceLoader.load(serviceType, fallbackClassLoader).iterator(); } while (servicesIterator.hasNext()) { try { T service = servicesIterator.next(); if (service instanceof Deactivatable && !ClassDeactivationUtils.isActivated((Class) service.getClass())) { LOG.info("deactivated service: " + service.getClass().getName()); continue; } result.add(service); } catch (Throwable t) { if (!ignoreServicesWithMissingDependencies) { throw ExceptionUtils.throwAsRuntimeException(t); } else { LOG.info("service filtered - caused by " + t.getMessage()); } } } return result; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/StringUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import jakarta.enterprise.inject.Vetoed; @Vetoed public abstract class StringUtils { /** * Constructor which prevents the instantiation of this class */ private StringUtils() { // prevent instantiation } public static boolean isEmpty(String string) { return string == null || string.trim().isEmpty(); } public static boolean isNotEmpty(String text) { return !isEmpty(text); } /** * Remove any non-numeric, non-alphanumeric Characters in the given String * @param val * @return the original string but any non-numeric, non-alphanumeric is replaced with a '_' */ public static String removeSpecialChars(String val) { if (val == null) { return null; } int len = val.length(); char[] newBuf = new char[len]; val.getChars(0, len, newBuf, 0); for (int i = 0; i < len; i++) { char c = newBuf[i]; if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '-' || c == '_') { continue; } // every other char gets replaced with '_' newBuf[i] = '_'; } return new String(newBuf); } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/AbstractContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.context; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.context.spi.Context; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.PassivationCapable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * A skeleton containing the most important parts of a custom CDI Context. * An implementing Context needs to implement the missing methods from the * {@link Context} interface and {@link #getContextualStorage(Contextual, boolean)}. */ public abstract class AbstractContext implements Context { /** * Whether the Context is for a passivating scope. */ private final boolean passivatingScope; protected AbstractContext(BeanManager beanManager) { passivatingScope = beanManager.isPassivatingScope(getScope()); } /** * An implementation has to return the underlying storage which * contains the items held in the Context. * @param createIfNotExist whether a ContextualStorage shall get created if it doesn't yet exist. * @return the underlying storage */ protected abstract ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist); protected List getActiveContextualStorages() { List result = new ArrayList(); result.add(getContextualStorage(null, false)); return result; } /** * @return whether the served scope is a passivating scope */ public boolean isPassivatingScope() { return passivatingScope; } @Override public T get(Contextual bean) { checkActive(); ContextualStorage storage = getContextualStorage(bean, false); if (storage == null) { return null; } Map> contextMap = storage.getStorage(); ContextualInstanceInfo contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean)); if (contextualInstanceInfo == null) { return null; } return (T) contextualInstanceInfo.getContextualInstance(); } @Override public T get(Contextual bean, CreationalContext creationalContext) { if (creationalContext == null) { return get(bean); } checkActive(); if (passivatingScope) { if (!(bean instanceof PassivationCapable)) { throw new IllegalStateException(bean.toString() + " doesn't implement " + PassivationCapable.class.getName()); } } ContextualStorage storage = getContextualStorage(bean, true); Map> contextMap = storage.getStorage(); ContextualInstanceInfo contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean)); if (contextualInstanceInfo != null) { @SuppressWarnings("unchecked") final T instance = (T) contextualInstanceInfo.getContextualInstance(); if (instance != null) { return instance; } } return storage.createContextualInstance(bean, creationalContext); } /** * Destroy the Contextual Instance of the given Bean. * @param bean dictates which bean shall get cleaned up * @return true if the bean was destroyed, false if there was no such bean. */ public boolean destroy(Contextual bean) { ContextualStorage storage = getContextualStorage(bean, false); if (storage == null) { return false; } ContextualInstanceInfo contextualInstanceInfo = storage.getStorage().remove(storage.getBeanKey(bean)); if (contextualInstanceInfo == null) { return false; } destroyBean(bean, contextualInstanceInfo); return true; } /** * destroys all the Contextual Instances in the Storage returned by * {@link #getContextualStorage(Contextual, boolean)}. */ public void destroyAllActive() { List storages = getActiveContextualStorages(); if (storages == null) { return; } for (ContextualStorage storage : storages) { if (storage != null) { destroyAllActive(storage); } } } /** * Destroys all the Contextual Instances in the specified ContextualStorage. * This is a static method to allow various holder objects to cleanup * properly in @PreDestroy. */ public static Map> destroyAllActive(ContextualStorage storage) { //drop all entries in the storage before starting with destroying the original entries Map> contextMap = new HashMap>(storage.getStorage()); storage.getStorage().clear(); for (Map.Entry> entry : contextMap.entrySet()) { Contextual bean = storage.getBean(entry.getKey()); ContextualInstanceInfo contextualInstanceInfo = entry.getValue(); destroyBean(bean, contextualInstanceInfo); } return contextMap; } public static void destroyBean(Contextual bean, ContextualInstanceInfo contextualInstanceInfo) { bean.destroy(contextualInstanceInfo.getContextualInstance(), contextualInstanceInfo.getCreationalContext()); } /** * Make sure that the Context is really active. * @throws ContextNotActiveException if there is no active * Context for the current Thread. */ protected void checkActive() { if (!isActive()) { throw new ContextNotActiveException("CDI context with scope annotation @" + getScope().getName() + " is not active with respect to the current thread"); } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualInstanceInfo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.context; import jakarta.enterprise.context.spi.CreationalContext; import java.io.Serializable; /** * This data holder contains all necessary data you need to * store a Contextual Instance in a CDI Context. */ public class ContextualInstanceInfo implements Serializable { private static final long serialVersionUID = 6384932199958645324L; /** * The actual Contextual Instance in the context */ private T contextualInstance; /** * We need to store the CreationalContext as we need it for * properly destroying the contextual instance via * {@link jakarta.enterprise.context.spi.Contextual#destroy(Object, jakarta.enterprise.context.spi.CreationalContext)} */ private CreationalContext creationalContext; /** * @return the CreationalContext of the bean */ public CreationalContext getCreationalContext() { return creationalContext; } /** * @param creationalContext the CreationalContext of the bean */ public void setCreationalContext(CreationalContext creationalContext) { this.creationalContext = creationalContext; } /** * @return the contextual instance itself */ public T getContextualInstance() { return contextualInstance; } /** * @param contextualInstance the contextual instance itself */ public void setContextualInstance(T contextualInstance) { this.contextualInstance = contextualInstance; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/context/ContextualStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.context; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.PassivationCapable; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; /** * This Storage holds all information needed for storing * Contextual Instances in a Context. * * It also addresses Serialisation in case of passivating scopes. */ public class ContextualStorage implements Serializable { private static final long serialVersionUID = 1L; private final Map> contextualInstances; private final BeanManager beanManager; private final boolean concurrent; private final boolean passivationCapable; /** * @param beanManager is needed for serialisation * @param concurrent whether the ContextualStorage might get accessed concurrently by different threads * @param passivationCapable whether the storage is for passivation capable Scopes */ public ContextualStorage(BeanManager beanManager, boolean concurrent, boolean passivationCapable) { this.beanManager = beanManager; this.concurrent = concurrent; this.passivationCapable = passivationCapable; if (concurrent) { contextualInstances = new ConcurrentHashMap>(); } else { contextualInstances = new HashMap>(); } } /** * @return the underlying storage map. */ public Map> getStorage() { return contextualInstances; } /** * @return whether the ContextualStorage might get accessed concurrently by different threads. */ public boolean isConcurrent() { return concurrent; } /** * * @param bean * @param creationalContext * @param * @return */ public T createContextualInstance(Contextual bean, CreationalContext creationalContext) { Object beanKey = getBeanKey(bean); if (isConcurrent()) { // locked approach ContextualInstanceInfo instanceInfo = new ContextualInstanceInfo(); ConcurrentMap> concurrentMap = (ConcurrentHashMap>) contextualInstances; ContextualInstanceInfo oldInstanceInfo = (ContextualInstanceInfo) concurrentMap.putIfAbsent(beanKey, instanceInfo); if (oldInstanceInfo != null) { instanceInfo = oldInstanceInfo; } synchronized (instanceInfo) { T instance = instanceInfo.getContextualInstance(); if (instance == null) { instance = bean.create(creationalContext); instanceInfo.setContextualInstance(instance); instanceInfo.setCreationalContext(creationalContext); } return instance; } } else { // simply create the contextual instance ContextualInstanceInfo instanceInfo = new ContextualInstanceInfo(); instanceInfo.setCreationalContext(creationalContext); instanceInfo.setContextualInstance(bean.create(creationalContext)); contextualInstances.put(beanKey, instanceInfo); return instanceInfo.getContextualInstance(); } } /** * If the context is a passivating scope then we return * the passivationId of the Bean. Otherwise we use * the Bean directly. * @return the key to use in the context map */ public Object getBeanKey(Contextual bean) { if (passivationCapable) { // if the return ((PassivationCapable) bean).getId(); } return bean; } /** * Restores the Bean from its beanKey. * @see #getBeanKey(jakarta.enterprise.context.spi.Contextual) */ public Contextual getBean(Object beanKey) { if (passivationCapable) { return beanManager.getPassivationCapableBean((String) beanKey); } else { return (Contextual) beanKey; } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/interceptor/AbstractInvocationContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.interceptor; import jakarta.enterprise.inject.Vetoed; import jakarta.interceptor.InvocationContext; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @Vetoed public abstract class AbstractInvocationContext implements InvocationContext { protected final T target; protected final Method method; protected final Object timer; protected Object[] parameters; protected Map contextData; protected AbstractInvocationContext(T target, Method method, Object[] parameters, Object timer) { this.target = target; this.method = method; this.parameters = parameters; this.timer = timer; } @Override public Object getTarget() { return target; } @Override public Method getMethod() { return method; } @Override public Object getTimer() { return timer; } @Override public Object[] getParameters() { return parameters; } @Override public void setParameters(Object[] parameters) { this.parameters = parameters; } @Override public Map getContextData() { if (contextData == null) { contextData = new HashMap(); } return contextData; } // @Override - forward compatibility to interceptors API 1.2 public Constructor getConstructor() { return null; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/AnnotationInstanceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; import java.util.Collections; import java.util.Map; /** *

A small helper class to create an Annotation instance of the given annotation class * via {@link java.lang.reflect.Proxy}. The annotation literal gets filled with the default values.

*

*

This class can be used to dynamically create Annotations which can be usd in AnnotatedTyp. * This is e.g. the case if you configure an annotation via properties or XML file. In those cases you * cannot use {@link jakarta.enterprise.util.AnnotationLiteral} because the type is not known at compile time.

*

usage:

*
 * String annotationClassName = ...;
 * Class annotationClass =
 *     (Class) ClassUtils.getClassLoader(null).loadClass(annotationClassName);
 * Annotation a = AnnotationInstanceProvider.of(annotationClass)
 * 
*/ public class AnnotationInstanceProvider implements Annotation, InvocationHandler, Serializable { private static final long serialVersionUID = -2345068201195886173L; private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; private final Class annotationClass; private final Map memberValues; /** * Required to use the result of the factory instead of a default implementation * of {@link jakarta.enterprise.util.AnnotationLiteral}. * * @param annotationClass class of the target annotation */ private AnnotationInstanceProvider(Class annotationClass, Map memberValues) { this.annotationClass = annotationClass; this.memberValues = memberValues; } /** * Creates an annotation instance for the given annotation class * * @param annotationClass type of the target annotation * @param values A non-null map of the member values, keys being the name of the members * @param current type * @return annotation instance for the given type */ @SuppressWarnings("unchecked") public static T of(Class annotationClass, Map values) { if (values == null) { throw new IllegalArgumentException("Map of values must not be null"); } String key = annotationClass.getName() + "_" + values.hashCode(); return (T) initAnnotation(key, annotationClass, values); } /** * Creates an annotation instance for the given annotation class * * @param annotationClass type of the target annotation * @param current type * @return annotation instance for the given type */ @SuppressWarnings("unchecked") public static T of(Class annotationClass) { return (T) of(annotationClass, Collections.EMPTY_MAP); } private static synchronized Annotation initAnnotation(String key, Class annotationClass, Map values) { return (Annotation) Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[]{annotationClass}, new AnnotationInstanceProvider(annotationClass, values)); } /** * {@inheritDoc} */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Exception { if ("hashCode".equals(method.getName())) { return hashCode(); } else if ("equals".equals(method.getName())) { if (Proxy.isProxyClass(args[0].getClass())) { if (Proxy.getInvocationHandler(args[0]) instanceof AnnotationInstanceProvider) { return equals(Proxy.getInvocationHandler(args[0])); } } return equals(args[0]); } else if ("annotationType".equals(method.getName())) { return annotationType(); } else if ("toString".equals(method.getName())) { return toString(); } else { if (memberValues.containsKey(method.getName())) { return memberValues.get(method.getName()); } else // Default cause, probably won't ever happen, unless annotations get actual methods { return method.getDefaultValue(); } } } /** * {@inheritDoc} */ @Override public Class annotationType() { return annotationClass; } /** * Copied from Apache OWB (jakarta.enterprise.util.AnnotationLiteral#toString()) * with minor changes. * * @return the current state of the annotation as string */ @Override public String toString() { Method[] methods = annotationClass.getDeclaredMethods(); StringBuilder sb = new StringBuilder("@" + annotationType().getName() + "("); int length = methods.length; for (int i = 0; i < length; i++) { // Member name sb.append(methods[i].getName()).append("="); // Member value Object memberValue; try { memberValue = invoke(this, methods[i], EMPTY_OBJECT_ARRAY); } catch (Exception e) { memberValue = ""; } sb.append(memberValue); if (i < length - 1) { sb.append(","); } } sb.append(")"); return sb.toString(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof AnnotationInstanceProvider)) { if (annotationClass.isInstance(o)) { for (Map.Entry entry : memberValues.entrySet()) { try { Object oValue = annotationClass.getMethod(entry.getKey(), EMPTY_CLASS_ARRAY) .invoke(o, EMPTY_OBJECT_ARRAY); if (oValue != null && entry.getValue() != null) { if (!oValue.equals(entry.getValue())) { return false; } } else // This may not actually ever happen, unless null is a default for a member { return false; } } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } return true; } return false; } AnnotationInstanceProvider that = (AnnotationInstanceProvider) o; if (!annotationClass.equals(that.annotationClass)) { return false; } return memberValues.equals(that.memberValues); } @Override public int hashCode() { int result = 0; Class type = annotationClass; for (Method m : type.getDeclaredMethods()) { try { Object value = invoke(this, m, EMPTY_OBJECT_ARRAY); if (value == null) { throw new IllegalStateException(String.format("Annotation method %s returned null", m)); } result += hashMember(m.getName(), value); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } return result; } //besides modularity, this has the advantage of autoboxing primitives: /** * Helper method for generating a hash code for a member of an annotation. * * @param name the name of the member * @param value the value of the member * @return a hash code for this member */ private int hashMember(String name, Object value) { int part1 = name.hashCode() * 127; if (value.getClass().isArray()) { return part1 ^ arrayMemberHash(value.getClass().getComponentType(), value); } if (value instanceof Annotation) { return part1 ^ hashCode((Annotation) value); } return part1 ^ value.hashCode(); } /** * Helper method for generating a hash code for an array. * * @param componentType the component type of the array * @param o the array * @return a hash code for the specified array */ private static int arrayMemberHash(Class componentType, Object o) { if (componentType.equals(Byte.TYPE)) { return Arrays.hashCode((byte[]) o); } if (componentType.equals(Short.TYPE)) { return Arrays.hashCode((short[]) o); } if (componentType.equals(Integer.TYPE)) { return Arrays.hashCode((int[]) o); } if (componentType.equals(Character.TYPE)) { return Arrays.hashCode((char[]) o); } if (componentType.equals(Long.TYPE)) { return Arrays.hashCode((long[]) o); } if (componentType.equals(Float.TYPE)) { return Arrays.hashCode((float[]) o); } if (componentType.equals(Double.TYPE)) { return Arrays.hashCode((double[]) o); } if (componentType.equals(Boolean.TYPE)) { return Arrays.hashCode((boolean[]) o); } return Arrays.hashCode((Object[]) o); } /** *

Generate a hash code for the given annotation using the algorithm * presented in the {@link Annotation#hashCode()} API docs.

* * @param a the Annotation for a hash code calculation is desired, not * {@code null} * @return the calculated hash code * @throws RuntimeException if an {@code Exception} is encountered during * annotation member access * @throws IllegalStateException if an annotation method invocation returns * {@code null} */ private int hashCode(Annotation a) { int result = 0; Class type = a.annotationType(); for (Method m : type.getDeclaredMethods()) { try { Object value = m.invoke(a); if (value == null) { throw new IllegalStateException(String.format("Annotation method %s returned null", m)); } result += hashMember(m.getName(), value); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } return result; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/ImmutableInjectionPoint.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import org.apache.deltaspike.core.util.BeanUtils; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Member; import java.lang.reflect.Type; import java.util.HashSet; import java.util.Set; import static java.util.Collections.unmodifiableSet; /** *

* A base class for implementing {@link InjectionPoint}. The attributes are * immutable, and collections are defensively copied on instantiation. *

*/ public class ImmutableInjectionPoint implements InjectionPoint { private final Annotated annotated; private final Member member; private final Bean declaringBean; private final Set qualifiers; private final Type type; private final boolean isTransient; private final boolean delegate; /** * Instantiate a new {@link InjectionPoint} based upon an * {@link AnnotatedField}. * * @param field the field for which to create the injection point * @param qualifiers the qualifiers on the injection point * @param declaringBean the declaringBean declaring the injection point * @param isTransient true if the injection point is transient * @param delegate true if the injection point is a delegate * injection point on a decorator */ public ImmutableInjectionPoint(AnnotatedField field, Set qualifiers, Bean declaringBean, boolean isTransient, boolean delegate) { annotated = field; member = field.getJavaMember(); this.qualifiers = new HashSet(qualifiers); type = field.getJavaMember().getGenericType(); this.isTransient = isTransient; this.delegate = delegate; this.declaringBean = declaringBean; } /** * Instantiate a new {@link InjectionPoint} based upon an * {@link AnnotatedField}, reading the qualifiers from the annotations * declared on the field. * * @param field the field for which to create the injection point * @param declaringBean the declaringBean declaring the injection point * @param isTransient true if the injection point is transient * @param delegate true if the injection point is a delegate * injection point on a decorator */ public ImmutableInjectionPoint(AnnotatedField field, BeanManager beanManager, Bean declaringBean, boolean isTransient, boolean delegate) { annotated = field; member = field.getJavaMember(); qualifiers = BeanUtils.getQualifiers(beanManager, field.getAnnotations()); type = field.getJavaMember().getGenericType(); this.isTransient = isTransient; this.delegate = delegate; this.declaringBean = declaringBean; } /** * Instantiate a new {@link InjectionPoint} based upon an * {@link AnnotatedParameter}. * * @param parameter the parameter for which to create the injection point * @param qualifiers the qualifiers on the injection point * @param declaringBean the declaringBean declaring the injection point * @param isTransient true if the injection point is transient * @param delegate true if the injection point is a delegate * injection point on a decorator */ public ImmutableInjectionPoint(AnnotatedParameter parameter, Set qualifiers, Bean declaringBean, boolean isTransient, boolean delegate) { annotated = parameter; member = parameter.getDeclaringCallable().getJavaMember(); this.qualifiers = new HashSet(qualifiers); this.isTransient = isTransient; this.delegate = delegate; this.declaringBean = declaringBean; type = parameter.getBaseType(); } /** * Instantiate a new {@link InjectionPoint} based upon an * {@link AnnotatedParameter}, reading the qualifiers from the annotations * declared on the parameter. * * @param parameter the parameter for which to create the injection point * @param declaringBean the declaringBean declaring the injection point * @param isTransient true if the injection point is transient * @param delegate true if the injection point is a delegate * injection point on a decorator */ public ImmutableInjectionPoint(AnnotatedParameter parameter, BeanManager beanManager, Bean declaringBean, boolean isTransient, boolean delegate) { annotated = parameter; member = parameter.getDeclaringCallable().getJavaMember(); qualifiers = BeanUtils.getQualifiers(beanManager, parameter.getAnnotations()); this.isTransient = isTransient; this.delegate = delegate; this.declaringBean = declaringBean; type = parameter.getBaseType(); } public Annotated getAnnotated() { return annotated; } public Bean getBean() { return declaringBean; } public Member getMember() { return member; } public Set getQualifiers() { return unmodifiableSet(qualifiers); } public Type getType() { return type; } public boolean isDelegate() { return delegate; } public boolean isTransient() { return isTransient; } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/InjectableMethod.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import org.apache.deltaspike.core.util.metadata.builder.ParameterValueRedefiner.ParameterValue; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import java.util.ArrayList; import java.util.Collection; import java.util.List; import static org.apache.deltaspike.core.util.BeanUtils.createInjectionPoints; import static org.apache.deltaspike.core.util.ReflectionUtils.invokeMethod; /** *

* Allows an {@link AnnotatedMethod} to be injected using the CDI type safe * resolution rules. *

*

*

* {@link ParameterValueRedefiner} allows the default value to be overridden by * the caller of * {@link #invoke(Object, CreationalContext, ParameterValueRedefiner)}. *

* * @param the declaring type */ public class InjectableMethod { private final AnnotatedMethod method; private final List parameters; private final BeanManager beanManager; /** * Instantiate a new {@link InjectableMethod}. * * @param method the method which will be injected upon a call to * {@link #invoke(Object, CreationalContext)} * @param declaringBean the bean which defines the injectable method * @param beanManager the {@link BeanManager} to use to obtain the parameter values */ public InjectableMethod(AnnotatedMethod method, Bean declaringBean, BeanManager beanManager) { this(method, createInjectionPoints(method, declaringBean, beanManager), beanManager); } /** * Instantiate a new {@link InjectableMethod}. * * @param method the method which will be injected upon a call to * {@link #invoke(Object, CreationalContext)} * @param parameters a collection of injection points representing the * parameters of the method * @param beanManager the {@link BeanManager} to use to obtain the parameter * values */ public InjectableMethod(AnnotatedMethod method, Collection parameters, BeanManager beanManager) { this.method = method; this.parameters = new ArrayList(parameters); this.beanManager = beanManager; } /** * Get the bean manager used by this injectable method. * * @return the bean manager in use */ protected BeanManager getBeanManager() { return beanManager; } /** * Get the injectable parameters of this method. * * @return a collection of injection points representing the parameters of * this method */ protected List getParameters() { return parameters; } /** * Invoke the method, causing all parameters to be injected according to the * CDI type safe resolution rules.public class ParameterValueRedefiner { *

* } * * @param the return type of the method * @param receiver the instance upon which to call the method * @param creationalContext the creational context to use to obtain * injectable references for each parameter * @return the result of invoking the method or null if the method's return * type is void * @throws RuntimeException if this Method object enforces Java * language access control and the underlying method is * inaccessible or if the underlying method throws an exception or * if the initialization provoked by this method fails. * @throws IllegalArgumentException if the method is an instance method and * the specified receiver argument is not an instance * of the class or interface declaring the underlying method (or * of a subclass or implementor thereof); if an unwrapping * conversion for primitive arguments fails; or if, after possible * unwrapping, a parameter value cannot be converted to the * corresponding formal parameter type by a method invocation * conversion. * @throws NullPointerException if the specified receiver is * null and the method is an instance method. * @throws ExceptionInInitializerError if the initialization provoked by this * method fails. */ public T invoke(Object receiver, CreationalContext creationalContext) throws IllegalAccessException, IllegalArgumentException { return invoke(receiver, creationalContext, null); } /** * Invoke the method, calling the parameter redefiner for each parameter, * allowing the caller to override the default value obtained via the CDI * type safe resolver. * * @param the return type of the method * @param receiver the instance upon which to call the method * @param creationalContext the creational context to use to obtain * injectable references for each parameter * @return the result of invoking the method or null if the method's return * type is void * @throws RuntimeException if this Method object enforces Java * language access control and the underlying method is * inaccessible or if the underlying method throws an exception or * if the initialization provoked by this method fails. * @throws IllegalArgumentException if the method is an instance method and * the specified receiver argument is not an instance * of the class or interface declaring the underlying method (or * of a subclass or implementor thereof); if an unwrapping * conversion for primitive arguments fails; or if, after possible * unwrapping, a parameter value cannot be converted to the * corresponding formal parameter type by a method invocation * conversion. * @throws NullPointerException if the specified receiver is * null and the method is an instance method. * @throws ExceptionInInitializerError if the initialization provoked by this * method fails. */ public T invoke(Object receiver, CreationalContext creationalContext, ParameterValueRedefiner redefinition) throws IllegalAccessException, IllegalArgumentException { List parameterValues = new ArrayList(); for (int i = 0; i < getParameters().size(); i++) { if (redefinition != null) { ParameterValue value = new ParameterValue(i, getParameters().get(i), getBeanManager()); parameterValues.add(redefinition.redefineParameterValue(value)); } else { parameterValues.add(getBeanManager().getInjectableReference(getParameters().get(i), creationalContext)); } } try { @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" }) T result = (T) invokeMethod(receiver, method.getJavaMember(), Object.class, true, parameterValues.toArray()); return result; } catch (RuntimeException e) { //X TODO check if it is compatible with Weld //workaround for OWB which wraps InvocationTargetException the original exception //see ReflectionUtils#invokeMethod if (RuntimeException.class.getName().equals(e.getClass().getName()) && e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } throw e; } } } ================================================ FILE: deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/metadata/builder/ParameterValueRedefiner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util.metadata.builder; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; /** * Provides the ability to redefine the value of a parameter on an * {@link InjectableMethod} via the * {@link #redefineParameterValue(ParameterValue)} callback. * * @see InjectableMethod */ public interface ParameterValueRedefiner { /** * Callback allowing the default parameter value (that which would be * injected according to the CDI type safe resolution rules) to be * overridden. * * @param value the default value * @return the overridden value */ Object redefineParameterValue(ParameterValue value); /** * Provides the default parameter's value, along with metadata about the * parameter to a parameter redefinition. * * @see ParameterValueRedefiner * @see InjectableMethod */ class ParameterValue { private final int position; private final InjectionPoint injectionPoint; private final BeanManager beanManager; ParameterValue(int position, InjectionPoint injectionPoint, BeanManager beanManager) { this.position = position; this.injectionPoint = injectionPoint; this.beanManager = beanManager; } /** * Get the position of the parameter in the member's parameter list. * * @return the position of the parameter */ public int getPosition() { return position; } /** * Get the {@link InjectionPoint} for the parameter. * * @return the injection point */ public InjectionPoint getInjectionPoint() { return injectionPoint; } /** * Get the default value of the parameter. The default value is that which * would be injected according to the CDI type safe resolution rules. * * @param creationalContext the creationalContext to use to obtain the * injectable reference. * @return the default value */ public Object getDefaultValue(CreationalContext creationalContext) { return beanManager.getInjectableReference(injectionPoint, creationalContext); } } } ================================================ FILE: deltaspike/core/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/core/api/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # DeltaSpike BeanManager provider org.apache.deltaspike.core.api.provider.BeanManagerProvider ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ClassUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import junit.framework.Assert; import org.junit.Test; import java.lang.reflect.Method; import java.util.Collection; import java.util.List; public class ClassUtilsTest { @Test public void shouldNotRetrieveMethodBasedOnSameReturnType() throws Exception { Method m = InnerTwo.class.getMethod("getCollection"); Method method = ClassUtils.extractPossiblyGenericMethod(InnerOne.class, m); Assert.assertEquals(InnerOne.class.getMethod("getCollection"), method); } @Test public void shouldRetrieveMethodBasedOnCastableType() throws Exception { Method m = InnerThree.class.getMethod("getCollection"); Method method = ClassUtils.extractPossiblyGenericMethod(InnerOne.class, m); Assert.assertEquals(InnerOne.class.getMethod("getCollection"), method); } private static class InnerOne { public List getCollection() { return null; } } private static class InnerTwo { public Collection getCollection() { return null; } } private static class InnerThree { public Object getCollection() { return null; } } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/ParameterUtilTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Method; public class ParameterUtilTest { @Before public void isEnabled() { Assume.assumeTrue(ParameterUtil.isParameterSupported()); } @Test public void shouldReturnNameOrNull() throws Exception { Method method = getClass().getDeclaredMethod("someMethod", String.class); String parameterName = ParameterUtil.getName(method, 0); Assert.assertTrue(parameterName.equals("arg0") || parameterName.equals("firstParameter")); } public void someMethod(String firstParameter) {} } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/PropertyFileUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.util; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.Enumeration; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @RunWith(Parameterized.class) public class PropertyFileUtilsTest { @Parameterized.Parameters public static Iterable cases() throws MalformedURLException { return Arrays.asList( new Object[] // classpath { new Case("test.properties") { @Override public void run() { assertTrue(result.hasMoreElements()); result.nextElement(); assertFalse(result.hasMoreElements()); } } }, new Object[] // file path { new Case("src/test") { @Override public void run() { assertTrue(result.hasMoreElements()); result.nextElement(); assertFalse(result.hasMoreElements()); } } }, new Object[] // url { new Case(new File("src/test/resources/test.properties").toURI().toURL().toExternalForm()) { @Override public void run() { assertTrue(result.hasMoreElements()); result.nextElement(); assertFalse(result.hasMoreElements()); } } }, new Object[] // url not existent { new Case(new File("src/test/resources/test_not_existent.properties").toURI().toURL().toExternalForm()) { @Override public void run() { assertFalse(result.hasMoreElements()); } } }); } private final Case test; public PropertyFileUtilsTest(Case test) { this.test = test; } @Test public void run() throws IOException, URISyntaxException { test.result = PropertyFileUtils.resolvePropertyFiles(test.file); test.run(); } private static abstract class Case implements Runnable { private String file; protected Enumeration result; private Case(final String file) { this.file = file; } } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/PropertyLoaderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.config; import org.apache.deltaspike.core.api.config.PropertyLoader; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.Properties; public class PropertyLoaderTest { @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void testNotExistingPropertyLoading() throws Exception { Assert.assertNull(PropertyLoader.getProperties("notexistingProperty")); Assert.assertNull(PropertyLoader.getProperties("notexistingProperty.properties")); } @Test public void testStandardPropertyLoading() throws Exception { checkProperties("test", "1"); checkProperties("test.properties", "1"); } @Test public void testProjectStagedPropertyLoading() throws Exception { checkProperties("test2", "2"); checkProperties("test2.properties", "2"); } private void checkProperties(String propertyFile, String expectedValue) { Properties p = PropertyLoader.getProperties(propertyFile); Assert.assertNotNull(p); Assert.assertEquals(1, p.size()); Assert.assertEquals(expectedValue, p.get("test.value")); } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/CustomException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util; class CustomException extends Exception { private static final long serialVersionUID = 6197126259870336328L; CustomException(String message) { super(message); } CustomException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/ExceptionUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util; import org.apache.deltaspike.core.util.ExceptionUtils; import org.junit.Assert; import org.junit.Test; public class ExceptionUtilsTest { private static final String FIELD_DOES_NOT_EXIST = "field does not exist - custom message"; @Test public void changeMessageOfCustomException() { try { ExceptionUtils.changeAndThrowException( new CustomException("old", new Exception("original")), "new"); } catch (RuntimeException e) { Assert.fail(); } catch (Exception e) { Assert.assertEquals("original", e.getCause().getMessage()); Assert.assertEquals("new", e.getMessage()); Assert.assertEquals(CustomException.class, e.getClass()); return; } Assert.fail(); } @Test public void changeMessageOfInvalidCustomException() { try { ExceptionUtils.changeAndThrowException( new IncompatibleCustomException("old", new Exception("original"), 1), "new"); } catch (RuntimeException e) { Assert.fail(); } catch (Exception e) { Assert.assertEquals("original", e.getCause().getMessage()); Assert.assertEquals("old", e.getMessage()); Assert.assertEquals(IncompatibleCustomException.class, e.getClass()); Assert.assertEquals(1, ((IncompatibleCustomException) e).getCustomParameter()); return; } Assert.fail(); } @Test public void rethrowCheckedException() { try { invalidOperation(); } catch (NoSuchFieldException e) { Assert.assertEquals(FIELD_DOES_NOT_EXIST, e.getMessage()); Assert.assertEquals(null, e.getCause()); return; } Assert.fail(); } @Test public void rethrowUncheckedException() { try { ExceptionUtils.changeAndThrowException(new ClassCastException(), "custom"); } catch (ClassCastException e) { Assert.assertEquals("custom", e.getMessage()); Assert.assertEquals(null, e.getCause()); return; } Assert.fail(); } private void invalidOperation() throws NoSuchFieldException { try { getClass().getDeclaredField("virtualField"); } catch (NoSuchFieldException e) { ExceptionUtils.changeAndThrowException(e, FIELD_DOES_NOT_EXIST); } } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/IncompatibleCustomException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util; import java.io.Serializable; class IncompatibleCustomException extends Exception { private static final long serialVersionUID = 6197126259870336328L; private Serializable customParameter; IncompatibleCustomException(String message, Throwable cause, Serializable customParameter) { super(message, cause); this.customParameter = customParameter; } Object getCustomParameter() { return customParameter; } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/StringUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util; import org.apache.deltaspike.core.util.StringUtils; import org.junit.Assert; import org.junit.Test; public class StringUtilsTest { @Test public void emptyStringDetection() { Assert.assertTrue(StringUtils.isEmpty(null)); Assert.assertTrue(StringUtils.isEmpty("")); Assert.assertTrue(StringUtils.isEmpty(" ")); Assert.assertFalse(StringUtils.isEmpty(" a ")); } @Test public void testRemoveSpecialChars() { Assert.assertNull(StringUtils.removeSpecialChars(null)); Assert.assertEquals("abc_def", StringUtils.removeSpecialChars("abc def")); Assert.assertEquals("a_c_def", StringUtils.removeSpecialChars("a_c def")); // not replace _ Assert.assertEquals("a-c_dex", StringUtils.removeSpecialChars("a-c dex")); // not replace - Assert.assertEquals("a_c_def", StringUtils.removeSpecialChars("a\'c def")); Assert.assertEquals("A_c_deX", StringUtils.removeSpecialChars("A#c deX")); } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/metadata/AnnotationInstanceProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util.metadata; import jakarta.enterprise.inject.literal.NamedLiteral; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.junit.Test; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashMap; import java.util.Map; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.sameInstance; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** * */ public class AnnotationInstanceProviderTest { @Test public void assertBasicCreation() { Annotation a = AnnotationInstanceProvider.of(RequestScoped.class); assertThat(a, is(notNullValue())); } @Test public void assertCreationWithMemberValue() { Map memberValues = new HashMap(); memberValues.put("value", "test"); Annotation a = AnnotationInstanceProvider.of(Named.class, memberValues); assertThat(a, is(notNullValue())); } @Test public void assertCorrectAnnotationType() { assertThat(AnnotationInstanceProvider.of(RequestScoped.class).annotationType(), is(RequestScoped.class)); } @Test public void assertAnnotationTypeWorks() { assertEquals(AnnotationInstanceProvider.of(RequestScoped.class).annotationType(), RequestScoped.class); } @Test public void assertDifferentInstanceWithDifferentMembers() { Map memberValues = new HashMap(); memberValues.put("value", "test"); Map memberValues2 = new HashMap(); memberValues2.put("value", "test2"); Annotation a1 = AnnotationInstanceProvider.of(Named.class, memberValues); Annotation a2 = AnnotationInstanceProvider.of(Named.class, memberValues2); assertFalse(a2 == a1); } @Test public void assertSameUsingEquals() { Annotation a1 = AnnotationInstanceProvider.of(RequestScoped.class); Annotation a2 = AnnotationInstanceProvider.of(RequestScoped.class); assertTrue(a2.equals(a1)); } @Test public void assertDifferentInstanceWithMembersUsingEquals() { Map memberValues = new HashMap(); memberValues.put("value", "test"); Annotation a1 = AnnotationInstanceProvider.of(Named.class, memberValues); Annotation a2 = AnnotationInstanceProvider.of(Named.class); assertThat(a2, not(sameInstance(a1))); assertFalse(a2.equals(a1)); } @Test public void assertMemberAccessIsCorrect() { Map memberValues = new HashMap(); memberValues.put("value", "test"); Named a1 = AnnotationInstanceProvider.of(Named.class, memberValues); assertThat(a1.value(), is("test")); } @Test public void assertBasicHashCode() { assertThat(AnnotationInstanceProvider.of(RequestScoped.class).hashCode(), is(0)); } @Test public void assertSimpleMemberHashCode() { Map memberValues = new HashMap(); memberValues.put("value", "test"); assertThat(AnnotationInstanceProvider.of(Named.class, memberValues).hashCode(), is(not(0))); } @Test public void assertBasicToString() { assertThat(AnnotationInstanceProvider.of(RequestScoped.class).toString(), is("@jakarta.enterprise.context.RequestScoped()")); } @Test public void assertComplexCreation() { Map memberValues = new HashMap(); memberValues.put("booleanValue", false); memberValues.put("booleanValues", new boolean[]{false}); memberValues.put("byteValue", (byte) 0); memberValues.put("byteValues", new byte[]{(byte) 0}); memberValues.put("charValue", (char) 0); memberValues.put("charValues", new char[]{(char) 0}); memberValues.put("doubleValue", 0.0); memberValues.put("doubleValues", new double[]{0.0}); memberValues.put("floatValue", (float) 0); memberValues.put("floatValues", new float[]{(float) 0}); memberValues.put("intValue", 0); memberValues.put("intValues", new int[]{0}); memberValues.put("longValue", 0L); memberValues.put("longValues", new long[]{0L}); memberValues.put("shortValue", 0); memberValues.put("shortValues", new int[]{0}); memberValues.put("stooge", Stooge.SHEMP); memberValues.put("stooges", new Stooge[]{Stooge.MOE, Stooge.LARRY, Stooge.CURLY}); memberValues.put("string", ""); memberValues.put("strings", new String[]{""}); memberValues.put("type", Object.class); memberValues.put("types", new Class[]{Object.class}); memberValues.put("nest", AnnotationInstanceProvider.of(NestAnnotation.class, Collections.unmodifiableMap(memberValues))); assertThat(AnnotationInstanceProvider.of(TestAnnotation.class, memberValues), is(notNullValue())); } @Test public void assertComplexHashCode() { Map memberValues = new HashMap(); memberValues.put("booleanValue", false); memberValues.put("booleanValues", new boolean[]{false}); memberValues.put("byteValue", (byte) 0); memberValues.put("byteValues", new byte[]{(byte) 0}); memberValues.put("charValue", (char) 0); memberValues.put("charValues", new char[]{(char) 0}); memberValues.put("doubleValue", 0.0); memberValues.put("doubleValues", new double[]{0.0}); memberValues.put("floatValue", (float) 0); memberValues.put("floatValues", new float[]{(float) 0}); memberValues.put("intValue", 0); memberValues.put("intValues", new int[]{0}); memberValues.put("longValue", 0L); memberValues.put("longValues", new long[]{0L}); memberValues.put("shortValue", (short) 0); memberValues.put("shortValues", new short[]{(short) 0}); memberValues.put("stooge", Stooge.SHEMP); memberValues.put("stooges", new Stooge[]{Stooge.MOE, Stooge.LARRY, Stooge.CURLY}); memberValues.put("string", ""); memberValues.put("strings", new String[]{""}); memberValues.put("type", Object.class); memberValues.put("types", new Class[]{Object.class}); Map nestMemberValues = new HashMap(memberValues); memberValues.put("nest", AnnotationInstanceProvider.of(NestAnnotation.class, nestMemberValues)); memberValues.put("nests", new NestAnnotation[]{AnnotationInstanceProvider.of(NestAnnotation.class, nestMemberValues)}); assertThat(AnnotationInstanceProvider.of(TestAnnotation.class, memberValues).hashCode(), is(not(0))); } @Test public void assertComplexToString() { Map memberValues = new HashMap(); memberValues.put("booleanValue", false); memberValues.put("booleanValues", new boolean[]{false}); memberValues.put("byteValue", (byte) 0); memberValues.put("byteValues", new byte[]{(byte) 0}); memberValues.put("charValue", (char) 0); memberValues.put("charValues", new char[]{(char) 0}); memberValues.put("doubleValue", 0.0); memberValues.put("doubleValues", new double[]{0.0}); memberValues.put("floatValue", (float) 0); memberValues.put("floatValues", new float[]{(float) 0}); memberValues.put("intValue", 0); memberValues.put("intValues", new int[] { 0 } ); memberValues.put("longValue", 0L); memberValues.put("longValues", new long[] { 0L } ) ; memberValues.put("shortValue", (short) 0); memberValues.put("shortValues", new short[] { (short) 0 } ); memberValues.put("stooge", Stooge.SHEMP); memberValues.put("stooges", new Stooge[] { Stooge.MOE, Stooge.LARRY, Stooge.CURLY } ); memberValues.put("string", ""); memberValues.put("strings", new String[] { "" } ); memberValues.put("type", Object.class); memberValues.put("types", new Class[]{Object.class}); Map nestMemberValues = new HashMap(memberValues); memberValues.put("nest", AnnotationInstanceProvider.of(NestAnnotation.class, nestMemberValues)); memberValues.put("nests", new NestAnnotation[] { AnnotationInstanceProvider.of(NestAnnotation.class, nestMemberValues) } ); TestAnnotation testAnnotation = AnnotationInstanceProvider.of(TestAnnotation.class, memberValues); String testAnnotationToString = testAnnotation.toString(); assertTrue(testAnnotationToString.startsWith("@org.apache.deltaspike.test.api.util.metadata.TestAnnotation(")); //assertTrue(testAnnotationToString.contains("type=class java.lang.Object,booleanValue=false,byteValue=0")); // Order depends on the JVM (Sun, Oracle JRockit, ...) for (String key : memberValues.keySet()) { assertTrue(testAnnotationToString.contains(key+"=")); } assertTrue(testAnnotationToString.contains("type=class java.lang.Object")); assertTrue(testAnnotationToString.contains("booleanValue=false")); assertTrue(testAnnotationToString.contains("byteValue=0")); // End changed test assertTrue(testAnnotationToString.contains("nest=@org.apache.deltaspike.test.api.util.metadata.NestAnnotation")); assertTrue(testAnnotationToString.endsWith(")")); } @Test public void assertDifferentAnnotationsNotEqual() { RequestScoped annotation1 = AnnotationInstanceProvider.of(RequestScoped.class); Named annotation2 = AnnotationInstanceProvider.of(Named.class); assertFalse(annotation1.equals(annotation2)); assertFalse(annotation2.equals(annotation1)); } @Test public void assertCreatedAnnotationEqualToLiteral() { Map memberValue = new HashMap(); memberValue.put("value", "test"); Named named1 = AnnotationInstanceProvider.of(Named.class, memberValue); Named named2 = NamedLiteral.of("test"); assertTrue(named2.equals(named1)); assertTrue(named1.equals(named2)); } @Test public void assertCreatedAnnotationNotEqualToLiteralWithDifferentMemberValues() { Map memberValue = new HashMap(); memberValue.put("value", "test1"); Named named1 = AnnotationInstanceProvider.of(Named.class, memberValue); Named named2 = NamedLiteral.of("test"); assertFalse(named1.equals(named2)); } @Test public void assertNotEqualToOtherObjects() { assertFalse(AnnotationInstanceProvider.of(Named.class).equals("")); } @Test public void assertHashCodeSameAsLiteral() { Named a1 = AnnotationInstanceProvider.of(Named.class); Named a2 = NamedLiteral.INSTANCE; assertThat(a2.hashCode(), is(a1.hashCode())); } } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/metadata/NestAnnotation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util.metadata; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Pulled from Apache Commons Lang 3. */ @Retention(RetentionPolicy.RUNTIME) public @interface NestAnnotation { String string(); String[] strings(); Class type(); Class[] types(); byte byteValue(); byte[] byteValues(); short shortValue(); short[] shortValues(); int intValue(); int[] intValues(); char charValue(); char[] charValues(); long longValue(); long[] longValues(); float floatValue(); float[] floatValues(); double doubleValue(); double[] doubleValues(); boolean booleanValue(); boolean[] booleanValues(); Stooge stooge(); Stooge[] stooges(); } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/metadata/Stooge.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util.metadata; /** * Pulled from Apache Commons Lang 3. */ public enum Stooge { MOE, LARRY, CURLY, JOE, SHEMP } ================================================ FILE: deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/util/metadata/TestAnnotation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.api.util.metadata; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Pulled from Apache Commons Lang 3. */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { String string(); String[] strings(); Class type(); Class[] types(); byte byteValue(); byte[] byteValues(); short shortValue(); short[] shortValues(); int intValue(); int[] intValues(); char charValue(); char[] charValues(); long longValue(); long[] longValues(); float floatValue(); float[] floatValues(); double doubleValue(); double[] doubleValues(); boolean booleanValue(); boolean[] booleanValues(); Stooge stooge(); Stooge[] stooges(); NestAnnotation nest(); NestAnnotation[] nests(); } ================================================ FILE: deltaspike/core/api/src/test/resources/test.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # test.value=1 ================================================ FILE: deltaspike/core/api/src/test/resources/test2-UnitTest.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # deltaspike_ordinal=120 test.value=2 ================================================ FILE: deltaspike/core/api/src/test/resources/test2.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # test.value=1 ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/DefaultExceptionEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.ExceptionHandlingFlow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent; import org.apache.deltaspike.core.spi.exception.control.event.IntrospectiveExceptionEvent; import jakarta.enterprise.inject.Vetoed; /** * Payload for an exception to be handled. This object is not immutable as small pieces of the state may be set by the * handler. * * @param Exception type this event represents */ @Vetoed public class DefaultExceptionEvent implements IntrospectiveExceptionEvent { private final T exception; private boolean unmute; private ExceptionHandlingFlow flow; private Throwable throwNewException; private final boolean beforeTraversal; private final boolean markedHandled; /** * Initial state constructor. * * @param stackEvent Information about the current exception and cause chain. * @param beforeTraversal flag indicating the direction of the cause chain traversal * @param handled flag indicating the exception has already been handled by a previous handler * @throws IllegalArgumentException if stackEvent is null */ public DefaultExceptionEvent(final ExceptionStackEvent stackEvent, final boolean beforeTraversal, final boolean handled) { if (stackEvent == null) { throw new IllegalArgumentException("null is not valid for stackEvent"); } exception = (T) stackEvent.getCurrent(); this.beforeTraversal = beforeTraversal; markedHandled = handled; flow = ExceptionHandlingFlow.HANDLED_AND_CONTINUE; } @Override public T getException() { return exception; } @Override public void abort() { flow = ExceptionHandlingFlow.ABORT; } @Override public void throwOriginal() { flow = ExceptionHandlingFlow.THROW_ORIGINAL; } @Override public void handled() { flow = ExceptionHandlingFlow.HANDLED; } @Override public void handledAndContinue() { flow = ExceptionHandlingFlow.HANDLED_AND_CONTINUE; } @Override public void skipCause() { flow = ExceptionHandlingFlow.SKIP_CAUSE; } @Override public void unmute() { unmute = true; } @Override public boolean isUnmute() { return unmute; } /* Later public ExceptionStackEvent getExceptionStack() { } */ @Override public ExceptionHandlingFlow getCurrentExceptionHandlingFlow() { return flow; } @Override public boolean isMarkedHandled() { return markedHandled; } @Override public boolean isBeforeTraversal() { return beforeTraversal; } @Override public void rethrow(Throwable t) { throwNewException = t; flow = ExceptionHandlingFlow.THROW; } @Override public Throwable getThrowNewException() { return throwNewException; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/ExceptionHandlerBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.spi.BeanManager; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.api.exception.control.event.ExceptionStackEvent; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.core.api.provider.BeanProvider; /** * Observer of {@link org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent} events and handler * dispatcher. All handlers are invoked from this class. This class is immutable. */ @ApplicationScoped public class ExceptionHandlerBroadcaster { private static final Logger LOG = Logger.getLogger(ExceptionHandlerBroadcaster.class.getName()); /** * Observes the event, finds the correct exception handler(s) and invokes them. * * @param exceptionEventEvent * exception to be invoked * @param beanManager * active bean manager * @throws Throwable * If a handler requests the exception to be re-thrown. */ public void executeHandlers(@Observes @Any ExceptionToCatchEvent exceptionEventEvent, final BeanManager beanManager) throws Throwable { LOG.entering( ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", exceptionEventEvent.getException()); CreationalContext creationalContext = null; Throwable throwException = null; final HandlerMethodStorage handlerMethodStorage = BeanProvider.getContextualReference(HandlerMethodStorage.class); try { creationalContext = beanManager.createCreationalContext(null); final Set> processedHandlers = new HashSet>(); final ExceptionStackEvent stack = new ExceptionStackEvent(exceptionEventEvent.getException()); beanManager.fireEvent(stack); // Allow for modifying the exception stack // indentation with 8 for label needed by the current checkstyle rules inbound_cause: while (stack.getCurrent() != null) { final List> callbackExceptionEvent = new ArrayList>( handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), beanManager, exceptionEventEvent.getQualifiers(), true)); for (HandlerMethod handler : callbackExceptionEvent) { if (!processedHandlers.contains(handler)) { LOG.fine(String.format("Notifying handler %s", handler)); @SuppressWarnings("rawtypes") final DefaultExceptionEvent callbackEvent = new DefaultExceptionEvent(stack, true, exceptionEventEvent.isHandled()); handler.notify(callbackEvent, beanManager); LOG.fine(String.format("Handler %s returned status %s", handler, callbackEvent.getCurrentExceptionHandlingFlow().name())); if (!callbackEvent.isUnmute()) { processedHandlers.add(handler); } switch (callbackEvent.getCurrentExceptionHandlingFlow()) { case HANDLED: exceptionEventEvent.setHandled(true); return; case HANDLED_AND_CONTINUE: exceptionEventEvent.setHandled(true); break; case ABORT: return; case SKIP_CAUSE: exceptionEventEvent.setHandled(true); stack.skipCause(); continue inbound_cause; case THROW_ORIGINAL: throw exceptionEventEvent.getException(); case THROW: throw callbackEvent.getThrowNewException(); default: throw new IllegalStateException( "Unexpected enum type " + callbackEvent.getCurrentExceptionHandlingFlow()); } } } final Collection> handlersForException = handlerMethodStorage.getHandlersForException(stack.getCurrent().getClass(), beanManager, exceptionEventEvent.getQualifiers(), false); final List> handlerMethods = new ArrayList>(handlersForException); // Reverse these so category handlers are last Collections.reverse(handlerMethods); for (HandlerMethod handler : handlerMethods) { if (!processedHandlers.contains(handler)) { LOG.fine(String.format("Notifying handler %s", handler)); @SuppressWarnings("rawtypes") final DefaultExceptionEvent depthFirstEvent = new DefaultExceptionEvent(stack, false, exceptionEventEvent.isHandled()); handler.notify(depthFirstEvent, beanManager); LOG.fine(String.format("Handler %s returned status %s", handler, depthFirstEvent.getCurrentExceptionHandlingFlow().name())); if (!depthFirstEvent.isUnmute()) { processedHandlers.add(handler); } switch (depthFirstEvent.getCurrentExceptionHandlingFlow()) { case HANDLED: exceptionEventEvent.setHandled(true); return; case HANDLED_AND_CONTINUE: exceptionEventEvent.setHandled(true); break; case ABORT: return; case SKIP_CAUSE: exceptionEventEvent.setHandled(true); stack.skipCause(); continue inbound_cause; case THROW_ORIGINAL: throwException = exceptionEventEvent.getException(); break; case THROW: throwException = depthFirstEvent.getThrowNewException(); break; default: throw new IllegalStateException( "Unexpected enum type " + depthFirstEvent.getCurrentExceptionHandlingFlow()); } } } stack.skipCause(); } if (!exceptionEventEvent.isHandled() && throwException == null && !exceptionEventEvent.isOptional()) { LOG.warning(String.format("No handlers found for exception %s", exceptionEventEvent.getException())); throw exceptionEventEvent.getException(); } if (throwException != null) { throw throwException; } } finally { if (creationalContext != null) { creationalContext.release(); } LOG.exiting(ExceptionHandlerBroadcaster.class.getName(), "executeHandlers", exceptionEventEvent.getException()); } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/ExceptionHandlerComparator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.util.HierarchyDiscovery; import jakarta.enterprise.inject.Vetoed; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Comparator; import java.util.Set; /** * Comparator to sort exception handlers according qualifier * ({@link org.apache.deltaspike.core.api.exception.control.BeforeHandles} first), ordinal * (highest to lowest) and finally hierarchy (least to most specific). */ @SuppressWarnings({ "MethodWithMoreThanThreeNegations" }) @Vetoed public final class ExceptionHandlerComparator implements Comparator> { /** * {@inheritDoc} */ @Override public int compare(HandlerMethod lhs, HandlerMethod rhs) { if (lhs.equals(rhs)) { return 0; } // Really this is so all handlers are returned in the TreeSet (even if they're of the same type, but one is // before, the other is not // Make sure both handlers are handling the same type, and also have the same qualifiers, if both of those are // true, then precedence comes into play if (lhs.getExceptionType().equals(rhs.getExceptionType()) && lhs.getQualifiers().equals(rhs.getQualifiers())) { final int precedenceReturnValue = comparePrecedence(lhs.getOrdinal(), rhs.getOrdinal(), lhs.isBeforeHandler()); // We really shouldn't be running into this case where everything is the same up until now, // but just in case, return both so both handlers are run. if (precedenceReturnValue == 0) { return -1; } // Precedence is different return precedenceReturnValue; } else { // Different qualifiers if (lhs.getExceptionType().equals(rhs.getExceptionType()) && !lhs.getQualifiers().equals(rhs.getQualifiers())) { if (lhs.getQualifiers().contains(new AnyLiteral())) { return -1; // Make sure @Any is first, as it's less specific } return 1; } return compareHierarchies(lhs.getExceptionType(), rhs.getExceptionType()); } // Currently we're only looking at one type of traversal mode, if this changes, we'll need // to re-add lines to check for this. } private int compareHierarchies(Type lhsExceptionType, Type rhsExceptionType) { HierarchyDiscovery lhsHierarchy = new HierarchyDiscovery(lhsExceptionType); Set lhsTypeclosure = lhsHierarchy.getTypeClosure(); if (lhsTypeclosure.contains(rhsExceptionType)) { final int indexOfLhsType = new ArrayList(lhsTypeclosure).indexOf(lhsExceptionType); final int indexOfRhsType = new ArrayList(lhsTypeclosure).indexOf(rhsExceptionType); if (indexOfLhsType > indexOfRhsType) { return 1; } } return -1; } private int comparePrecedence(final int lhs, final int rhs, final boolean isLhsBefore) { if (!isLhsBefore) { return (lhs - rhs); } else { return (lhs - rhs) * -1; } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/HandlerMethodImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.BeanUtils; import org.apache.deltaspike.core.util.metadata.builder.ImmutableInjectionPoint; import org.apache.deltaspike.core.util.metadata.builder.InjectableMethod; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Implementation of {@link HandlerMethod}. * * @param Type of the exception this handler handles. */ @Vetoed public class HandlerMethodImpl implements HandlerMethod { private final Class declaringBeanClass; private final Bean declaringBean; private final Set qualifiers; private final Type exceptionType; private final AnnotatedMethod handler; private final boolean before; private final int ordinal; private final Method javaMethod; private final AnnotatedParameter handlerParameter; private Set injectionPoints; /** * Sole Constructor. * * @param method found handler * @param bm active BeanManager * @throws IllegalArgumentException if method is null, has no params or first param is not annotated with * {@link Handles} or {@link BeforeHandles} */ public HandlerMethodImpl(final Bean handlerDeclaringBean, final AnnotatedMethod method, final BeanManager bm) { //validation is done by the extension final Set tmpQualifiers = new HashSet(); declaringBean = handlerDeclaringBean; handler = method; javaMethod = method.getJavaMember(); handlerParameter = findHandlerParameter(method); if (!handlerParameter.isAnnotationPresent(Handles.class) && !handlerParameter.isAnnotationPresent(BeforeHandles.class)) { throw new IllegalArgumentException("Method is not annotated with @Handles or @BeforeHandles"); } before = handlerParameter.getAnnotation(BeforeHandles.class) != null; if (before) { ordinal = handlerParameter.getAnnotation(BeforeHandles.class).ordinal(); } else { ordinal = handlerParameter.getAnnotation(Handles.class).ordinal(); } tmpQualifiers.addAll(BeanUtils.getQualifiers(bm, handlerParameter.getAnnotations())); if (tmpQualifiers.isEmpty()) { tmpQualifiers.add(new AnyLiteral()); } qualifiers = tmpQualifiers; declaringBeanClass = method.getJavaMember().getDeclaringClass(); exceptionType = ((ParameterizedType) handlerParameter.getBaseType()).getActualTypeArguments()[0]; } /** * Determines if the given method is a handler by looking for the {@link Handles} annotation on a parameter. * * @param method method to search * @return true if {@link Handles} is found, false otherwise */ public static boolean isHandler(final AnnotatedMethod method) { if (method == null) { throw new IllegalArgumentException("Method must not be null"); } for (AnnotatedParameter param : method.getParameters()) { if (param.isAnnotationPresent(Handles.class) || param.isAnnotationPresent(BeforeHandles.class)) { return true; } } return false; } public static AnnotatedParameter findHandlerParameter(final AnnotatedMethod method) { if (!isHandler(method)) { throw new IllegalArgumentException("Method is not a valid handler"); } AnnotatedParameter returnParam = null; for (AnnotatedParameter param : method.getParameters()) { if (param.isAnnotationPresent(Handles.class) || param.isAnnotationPresent(BeforeHandles.class)) { returnParam = param; break; } } return returnParam; } public Bean getDeclaringBean() { return declaringBean; } /** * {@inheritDoc} */ @Override public Set getQualifiers() { return Collections.unmodifiableSet(qualifiers); } /** * {@inheritDoc} */ @Override public Type getExceptionType() { return exceptionType; } /** * {@inheritDoc} */ @Override public void notify(final ExceptionEvent event, BeanManager beanManager) throws Exception { CreationalContext ctx = null; try { ctx = beanManager.createCreationalContext(null); @SuppressWarnings("unchecked") Object handlerInstance = BeanProvider.getContextualReference(declaringBeanClass); InjectableMethod im = createInjectableMethod(handler, getDeclaringBean(), beanManager); im.invoke(handlerInstance, ctx, new OutboundParameterValueRedefiner(event, this)); } finally { if (ctx != null) { ctx.release(); } } } private InjectableMethod createInjectableMethod(AnnotatedMethod handlerMethod, Bean bean, BeanManager bm) { return new InjectableMethod(handlerMethod, bean, bm); } /** * {@inheritDoc} */ @Override public boolean isBeforeHandler() { return before; } /** * {@inheritDoc} */ @Override public int getOrdinal() { return ordinal; } public AnnotatedParameter getHandlerParameter() { return handlerParameter; } public Method getJavaMethod() { return handler.getJavaMember(); } /** * Obtain all the injection points for the handler * * @param bm a BeanManager to use to obtain the beans */ public Set getInjectionPoints(final BeanManager bm) { if (injectionPoints == null) { injectionPoints = new HashSet(handler.getParameters().size() - 1); for (AnnotatedParameter param : handler.getParameters()) { if (!param.equals(handlerParameter)) { injectionPoints.add( new ImmutableInjectionPoint(param, bm, getDeclaringBean(), false, false)); } } } return new HashSet(injectionPoints); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || !HandlerMethod.class.isAssignableFrom(o.getClass())) { return false; } HandlerMethod that = (HandlerMethod) o; if (!qualifiers.equals(that.getQualifiers())) { return false; } if (isBeforeHandler() != that.isBeforeHandler()) { return false; } //noinspection SimplifiableIfStatement if (!exceptionType.equals(that.getExceptionType())) { return false; } return ordinal == that.getOrdinal(); } @Override public int hashCode() { int result = declaringBeanClass.hashCode(); result = 5 * result + qualifiers.hashCode(); result = 5 * result + exceptionType.hashCode(); result = 5 * result + ordinal; result = 5 * result + javaMethod.hashCode(); result = 5 * result + handlerParameter.hashCode(); return result; } @Override public String toString() { return "{Qualifiers: " + qualifiers + ", " + "Handles Type: " + exceptionType + ", " + "Before: " + before + ", " + "Precedence: " + ordinal + ", Method: " + handler.getJavaMember().getName() + "}"; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/HandlerMethodStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import java.util.Set; /** * Injectable storage to support programmatic registration and lookup of * {@link org.apache.deltaspike.core.api.exception.control.HandlerMethod} instances. */ //X TODO move it to the spi package - otherwise there is no need for an interface public interface HandlerMethodStorage { /** * Registers the given handlerMethod to the storage. * * @param handlerMethod HandlerMethod implementation to register with the storage */ void registerHandlerMethod(HandlerMethod handlerMethod); /** * Obtains the applicable handlers for the given type or super type of the given type to order the handlers. * * @param exceptionClass Type of exception to narrow handler list * @param bm active BeanManager * @param handlerQualifiers additional handlerQualifiers to limit handlers * @param isBefore traversal limiter * @return An order collection of handlers for the given type. */ Collection> getHandlersForException(Type exceptionClass, BeanManager bm, Set handlerQualifiers, boolean isBefore); } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/HandlerMethodStorageImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.api.literal.AnyLiteral; import org.apache.deltaspike.core.util.HierarchyDiscovery; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.logging.Logger; /** * Basic implementation for {@link HandlerMethodStorage}. */ @SuppressWarnings("CdiManagedBeanInconsistencyInspection") @Vetoed class HandlerMethodStorageImpl implements HandlerMethodStorage { private final Map>> allHandlers; private Logger log = Logger.getLogger(HandlerMethodStorageImpl.class.getName()); HandlerMethodStorageImpl(Map>> allHandlers) { this.allHandlers = allHandlers; } @Override public void registerHandlerMethod(HandlerMethod handlerMethod) { log.fine(String.format("Adding handler %s to known handlers", handlerMethod)); if (allHandlers.containsKey(handlerMethod.getExceptionType())) { allHandlers.get(handlerMethod.getExceptionType()).add(handlerMethod); } else { allHandlers.put(handlerMethod.getExceptionType(), new HashSet>(Collections.singleton(handlerMethod))); } } @Override public Collection> getHandlersForException(Type exceptionClass, BeanManager bm, Set handlerQualifiers, boolean isBefore) { final Collection> returningHandlers = new TreeSet>(new ExceptionHandlerComparator()); final HierarchyDiscovery h = new HierarchyDiscovery(exceptionClass); final Set closure = h.getTypeClosure(); for (Type hierarchyType : closure) { if (allHandlers.get(hierarchyType) != null) { for (HandlerMethod handler : allHandlers.get(hierarchyType)) { if (handler.isBeforeHandler() && isBefore) { if (handler.getQualifiers().contains(new AnyLiteral())) { returningHandlers.add(handler); } else { if (!handlerQualifiers.isEmpty() && handlerQualifiers.equals(handler.getQualifiers())) { returningHandlers.add(handler); } } } else if (!handler.isBeforeHandler() && !isBefore) { if (handler.getQualifiers().contains(new AnyLiteral())) { returningHandlers.add(handler); } else { if (!handlerQualifiers.isEmpty() && handlerQualifiers.equals(handler.getQualifiers())) { returningHandlers.add(handler); } } } } } } log.fine(String.format("Found handlers %s for exception type %s, qualifiers %s", returningHandlers, exceptionClass, handlerQualifiers)); return Collections.unmodifiableCollection(returningHandlers); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/HandlerMethodStorageProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.impl.exception.control.extension.ExceptionControlExtension; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; @ApplicationScoped public class HandlerMethodStorageProducer { @Inject private ExceptionControlExtension exceptionControlExtension; @Produces @ApplicationScoped protected HandlerMethodStorage createHandlerMethodStorage() { return new HandlerMethodStorageImpl(exceptionControlExtension.getAllExceptionHandlers()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/OutboundParameterValueRedefiner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.util.metadata.builder.ParameterValueRedefiner; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; /** * Redefiner allowing to inject a non contextual instance of {@link DefaultExceptionEvent} into the first parameter. * This class is immutable. */ class OutboundParameterValueRedefiner implements ParameterValueRedefiner { private final ExceptionEvent event; private final Bean declaringBean; private final HandlerMethodImpl handlerMethod; /** * Sole constructor. * * @param event instance of DefaultExceptionEvent to inject. * @param handlerMethod Handler method this redefiner is for */ OutboundParameterValueRedefiner(final ExceptionEvent event, final HandlerMethodImpl handlerMethod) { this.event = event; declaringBean = handlerMethod.getDeclaringBean(); this.handlerMethod = handlerMethod; } /** * {@inheritDoc} */ @Override public Object redefineParameterValue(ParameterValue value) { CreationalContext ctx = BeanManagerProvider.getInstance().getBeanManager() .createCreationalContext(declaringBean); try { if (value.getPosition() == handlerMethod.getHandlerParameter().getPosition()) { return event; } return value.getDefaultValue(ctx); } finally { if (ctx != null) { ctx.release(); } } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/control/extension/ExceptionControlExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exception.control.extension; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.impl.exception.control.HandlerMethodImpl; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.InjectionException; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Decorator; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.Interceptor; import jakarta.enterprise.inject.spi.ProcessBean; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.logging.Logger; /** * CDI extension to find handlers at startup. */ @SuppressWarnings({ "unchecked", "CdiManagedBeanInconsistencyInspection" }) public class ExceptionControlExtension implements Extension, Deactivatable { private static final Logger LOG = Logger.getLogger(ExceptionControlExtension.class.getName()); //this map is application scoped by the def. of the cdi spec. //if it needs to be static a classloader key is needed + a cleanup in a BeforeShutdown observer private Map>> allHandlers = new HashMap>>(); private Boolean isActivated = true; @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } /** * Listener to ProcessBean event to locate handlers. * * @param processBean current {@link AnnotatedType} * @param beanManager Activated Bean Manager * @throws TypeNotPresentException if any of the actual type arguments refers to a non-existent type declaration * when trying to obtain the actual type arguments from a * {@link java.lang.reflect.ParameterizedType} * @throws java.lang.reflect.MalformedParameterizedTypeException * if any of the actual type parameters refer to a parameterized type that cannot * be instantiated for any reason when trying to obtain the actual type arguments * from a {@link java.lang.reflect.ParameterizedType} */ @SuppressWarnings("UnusedDeclaration") public void findHandlers(@Observes final ProcessBean processBean, final BeanManager beanManager) { if (!isActivated) { return; } if (processBean.getBean() instanceof Interceptor || processBean.getBean() instanceof Decorator || !(processBean.getAnnotated() instanceof AnnotatedType)) { return; } AnnotatedType annotatedType = (AnnotatedType)processBean.getAnnotated(); if (annotatedType.getJavaClass().isAnnotationPresent(ExceptionHandler.class)) { final Set> methods = annotatedType.getMethods(); for (AnnotatedMethod method : methods) { if (HandlerMethodImpl.isHandler(method)) { if (method.getJavaMember().getExceptionTypes().length != 0) { processBean.addDefinitionError(new IllegalArgumentException( String.format("Handler method %s must not throw exceptions", method.getJavaMember()))); } //beanManager won't be stored in the instance -> no issue with wls12c registerHandlerMethod(new HandlerMethodImpl(processBean.getBean(), method, beanManager)); } } } } /** * Verifies all injection points for every handler are valid. * * @param afterDeploymentValidation Lifecycle event * @param bm BeanManager instance */ @SuppressWarnings("UnusedDeclaration") public void verifyInjectionPoints(@Observes final AfterDeploymentValidation afterDeploymentValidation, final BeanManager bm) { if (!isActivated) { return; } for (Map.Entry>> entry : allHandlers.entrySet()) { for (HandlerMethod handler : entry.getValue()) { for (InjectionPoint ip : ((HandlerMethodImpl) handler).getInjectionPoints(bm)) { try { bm.validate(ip); } catch (InjectionException e) { afterDeploymentValidation.addDeploymentProblem(e); } } } } } public Map>> getAllExceptionHandlers() { return Collections.unmodifiableMap(allHandlers); } private void registerHandlerMethod(HandlerMethod handlerMethod) { LOG.fine(String.format("Adding handler %s to known handlers", handlerMethod)); if (allHandlers.containsKey(handlerMethod.getExceptionType())) { allHandlers.get(handlerMethod.getExceptionType()).add(handlerMethod); } else { allHandlers.put(handlerMethod.getExceptionType(), new HashSet>(Arrays.asList(handlerMethod))); } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/interceptor/GlobalInterceptorExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.interceptor; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import jakarta.interceptor.Interceptor; import java.lang.annotation.Annotation; import java.util.logging.Logger; // promotes deltaspike interceptors to global interceptors in case of cdi 1.1+ public class GlobalInterceptorExtension implements Deactivatable, Extension { private static final Logger LOG = Logger.getLogger(GlobalInterceptorExtension.class.getName()); private static final String DS_PACKAGE_NAME = "org.apache.deltaspike."; private Annotation priorityAnnotationInstance; private BeanManager beanManager; @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) { if (!ClassDeactivationUtils.isActivated(getClass())) { return; } this.beanManager = beanManager; int priorityValue = CoreBaseConfig.InterceptorCustomization.PRIORITY; priorityAnnotationInstance = AnnotationInstanceUtils.getPriorityAnnotationInstance(priorityValue); } protected void promoteInterceptors(@Observes ProcessAnnotatedType pat) { if (priorityAnnotationInstance == null) //not CDI 1.1 or the extension is deactivated { return; } String beanClassName = pat.getAnnotatedType().getJavaClass().getName(); if (beanClassName.startsWith(DS_PACKAGE_NAME)) { if (pat.getAnnotatedType().isAnnotationPresent(Interceptor.class)) { //noinspection unchecked pat.setAnnotatedType(new GlobalInterceptorWrapper(pat.getAnnotatedType(), priorityAnnotationInstance)); } //currently not needed, because we don't use our interceptors internally -> check for the future else if (!beanClassName.contains(".test.")) { for (Annotation annotation : pat.getAnnotatedType().getAnnotations()) { if (beanManager.isInterceptorBinding(annotation.annotationType())) { //once we see this warning we need to introduce double-call prevention logic due to WELD-1780 LOG.warning(beanClassName + " is an bean from DeltaSpike which is intercepted."); } } } } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/resourceloader/InjectableResourceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.resourceloader; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.resourceloader.InjectableResource; import org.apache.deltaspike.core.api.resourceloader.InjectableResourceProvider; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.lang.annotation.Annotation; import java.util.List; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; /** * Handles the creation/loading of external resources. * */ @ApplicationScoped public class InjectableResourceProducer { private static final Logger logger = Logger.getLogger(InjectableResourceProducer.class.getName()); @Inject @Any private Instance resourceProviders; @Produces @InjectableResource(resourceProvider = InjectableResourceProvider.class,location = "") public InputStream getInputStream(final InjectionPoint injectionPoint) { InjectableResource injectableResource = getAnnotation(injectionPoint); InjectableResourceProvider provider = BeanProvider.getContextualReference(injectableResource.resourceProvider()); final InputStream is = provider.readStream(injectableResource); return is; } @Produces @InjectableResource(resourceProvider = InjectableResourceProvider.class,location = "") public List getInputStreams(final InjectionPoint injectionPoint) { InjectableResource injectableResource = getAnnotation(injectionPoint); InjectableResourceProvider provider = BeanProvider.getContextualReference(injectableResource.resourceProvider()); return provider.readStreams(injectableResource); } @Produces @InjectableResource(resourceProvider = InjectableResourceProvider.class,location = "") public Properties getProperties(final InjectionPoint injectionPoint) throws IOException { InjectableResource injectableResource = getAnnotation(injectionPoint); InjectableResourceProvider provider = BeanProvider.getContextualReference(injectableResource.resourceProvider()); final Properties properties = provider.readProperties(injectableResource); return properties; } public void closeInputStream(@Disposes @InjectableResource(resourceProvider = InjectableResourceProvider.class, location = "") InputStream inputStream) { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE,"Unable to close input stream ",e); } } } } private InjectableResource getAnnotation(final InjectionPoint injectionPoint) { for (Annotation annotation : injectionPoint.getQualifiers()) { if (annotation instanceof InjectableResource) { return (InjectableResource)annotation; } } return null; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/main/java/org/apache/deltaspike/core/impl/resourceloader/ResourceLoaderExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.resourceloader; import org.apache.deltaspike.core.api.resourceloader.ClasspathResourceProvider; import org.apache.deltaspike.core.api.resourceloader.FileResourceProvider; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; /** * This is needed for certain class loading cases (EARs, external modules). * Simply registers additional resource loader classes to the context. */ //TODO re-visit it based on DELTASPIKE-472 public class ResourceLoaderExtension implements Extension { public void addResourceLoaders(final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager beanManager) { beforeBeanDiscovery.addAnnotatedType(this.createAnnotatedType(ClasspathResourceProvider.class,beanManager)); beforeBeanDiscovery.addAnnotatedType(this.createAnnotatedType(InjectableResourceProducer.class,beanManager)); beforeBeanDiscovery.addAnnotatedType(this.createAnnotatedType(FileResourceProvider.class,beanManager)); } private AnnotatedType createAnnotatedType(final Class clazz, final BeanManager beanManager) { return beanManager.createAnnotatedType(clazz); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseBean1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; import jakarta.enterprise.context.Dependent; /** * Simple base bean which gets overruled by an global alternative */ @Dependent public class BaseBean1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; /** * Simple interface - at runtime the global alternative gets activated */ public interface BaseInterface1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1AlternativeImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; /** * Global alternative */ @Alternative @Dependent public class BaseInterface1AlternativeImplementation implements BaseInterface1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/BaseInterface1DefaultImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; import jakarta.enterprise.context.Dependent; /** * Default implementation which gets overruled by the alternative */ @Dependent public class BaseInterface1DefaultImplementation implements BaseInterface1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; @Alternative @Dependent public class SubBaseBean1 extends BaseBean1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/SubBaseBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; @Alternative @Dependent public class SubBaseBean2 extends SubBaseBean1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/AlternativeBaseBeanB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; /** * */ @Dependent @Alternative @QualifierB(value = QualifierValue1.class, hint = "non-binding hint") public class AlternativeBaseBeanB implements BaseInterface { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanA.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.enterprise.context.Dependent; /** * */ @Dependent @QualifierA(QualifierValue1.class) public class BaseBeanA implements BaseInterface { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.enterprise.context.Dependent; /** * */ @Dependent @QualifierB(QualifierValue1.class) public class BaseBeanB implements BaseInterface { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseBeanB2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.enterprise.context.Dependent; /** * */ @Dependent @QualifierB(QualifierValue2.class) public class BaseBeanB2 implements BaseInterface { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/BaseInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; /** */ public interface BaseInterface { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierA.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * */ @Qualifier @Target({FIELD, METHOD, TYPE}) @Retention(RUNTIME) public @interface QualifierA { Class value(); } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * */ @Qualifier @Target({FIELD, METHOD, TYPE}) @Retention(RUNTIME) public @interface QualifierB { Class value(); @Nonbinding String hint() default "default hint"; } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; /** */ public interface QualifierValue1 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/global/qualifier/QualifierValue2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.global.qualifier; /** */ public interface QualifierValue2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; import jakarta.enterprise.context.Dependent; /** * Simple base bean which doesn't get overruled by an global alternative */ //Workaround until different config files for unit tests work correctly @Dependent public class BaseBean2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; /** * Simple interface - at runtime the default implementation gets activated */ //Workaround until different config files for unit tests work correctly public interface BaseInterface2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2AlternativeImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; /** * Alternative which isn't configured as global alternative. * * (A normal alternative usually it would be in a different BDA - here we have the same BDA but no config in * beans.xml which simulates the behaviour - compared to {@link org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1AlternativeImplementation} which is also * not configured in the beans.xml, but as global alternative (via DeltaSpike). Since we don't test the CDI * implementation itself, it's ok to simulate it. * Otherwise it will break with CDI 1.1 or at least with the default behaviour of OWB.) */ @Alternative @Dependent //Workaround until different config files for unit tests work correctly public class BaseInterface2AlternativeImplementation implements BaseInterface2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BaseInterface2DefaultImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; import jakarta.enterprise.context.Dependent; /** * Default implementation which doesn't get overruled by the alternative */ @Dependent //Workaround until different config files for unit tests work correctly public class BaseInterface2DefaultImplementation implements BaseInterface2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/BdaAlternativeTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.junit.Assert; import org.junit.Test; import jakarta.inject.Inject; import java.util.List; /** * Keep in sync with {@link org.apache.deltaspike.test.core.api.alternative.global.GlobalAlternativeTest} - * but without configuring the alternatives and check for the default implementations. * * Tests which checks the behaviour with deactivated global alternates. */ public abstract class BdaAlternativeTest { @Inject private BaseInterface2 bean; /* * The default implementation should be found */ @Test public void alternativeImplementationWithClassAsBaseType() { BaseBean2 baseBean2 = BeanProvider.getContextualReference(BaseBean2.class); Assert.assertNotNull(baseBean2); } /* * The default implementation should be found */ @Test public void alternativeImplementationWithInterfaceAsBaseType() { Assert.assertEquals(BaseInterface2DefaultImplementation.class.getName(), bean.getClass().getName()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/alternative/local/SubBaseBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.alternative.local; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; /** * Alternative which isn't configured as global alternative. * * (A normal alternative usually it would be in a different BDA - here we have the same BDA but no config in * beans.xml which simulates the behaviour - compared to {@link org.apache.deltaspike.test.core.api.alternative.global.SubBaseBean1} which is also not configured * in the beans.xml, but as global alternative (via DeltaSpike). Since we don't test the CDI implementation itself, * it's ok to simulate it. Otherwise it will break with CDI 1.1 or at least with the default behaviour of OWB.) */ @Alternative @Dependent //Workaround until different config files for unit tests work correctly public class SubBaseBean2 extends BaseBean2 { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import java.io.IOException; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.core.api.exclude.ExcludeWarFileTest.getConfigContent; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class ExcludeEarFileTest extends ExcludeTest { @Deployment public static EnterpriseArchive deployEar() throws IOException { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = ExcludeWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); // we needs to package the config into the EAR, as Weld3 based app servers boot the whole container // with just the EAR classloader. No WAR file packaged config is reachable for BeforeBeanDiscovery JavaArchive excludeConfigJar = ShrinkWrap.create(JavaArchive.class, "excludeConfig.jar") .addAsManifestResource(new StringAsset(getConfigContent()), "apache-deltaspike.properties"); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsLibrary(excludeConfigJar) .addAsModule(ExcludeWarFileTest.deploy()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/provider/BeanManagerProviderEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class BeanManagerProviderEarFileTest extends BeanManagerProviderTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = BeanManagerProviderWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(BeanManagerProviderWarFileTest.deploy()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/util/bean/BeanBuilderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.bean; import org.apache.deltaspike.core.util.bean.BeanBuilder; import org.apache.deltaspike.core.util.metadata.builder.ImmutableInjectionPoint; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; import java.util.HashSet; import java.util.Set; /** * */ @RunWith(Arquillian.class) public class BeanBuilderTest { @Deployment public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "beanBuilderTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(SimpleClass.class, WithInjectionPoint.class); } @Inject private BeanManager beanManager; @Test public void assertNonNullInjectionPointsFromBeanBuilder() { final BeanBuilder beanBuilder = new BeanBuilder(beanManager); final AnnotatedType at = beanManager.createAnnotatedType(WithInjectionPoint.class); final Bean newInjectionBean = beanBuilder.readFromType(at).create(); for (final InjectionPoint ip : newInjectionBean.getInjectionPoints()) { Assert.assertNotNull(ip); } } @Test public void assertNonNullInjectionPointsWhenOverriding() { final BeanBuilder beanBuilder = new BeanBuilder(beanManager); final AnnotatedType at = beanManager.createAnnotatedType(WithInjectionPoint.class); beanBuilder.readFromType(at); // It's not easy to actually create these in the state we need, so we have to get the InjectionPonits, // create new ones with the correct info, null out the bean, set them as the new injection points // then move on. final Set origInjectionPoints = beanBuilder.getInjectionPoints(); beanBuilder.injectionPoints(beanBuilder.getInjectionPoints()); final Set newInjectionPoints = new HashSet(); for (InjectionPoint ip : origInjectionPoints) { newInjectionPoints.add(new ImmutableInjectionPoint((AnnotatedField) ip.getAnnotated(), ip.getQualifiers(), null, ip.isTransient(), ip.isDelegate())); } beanBuilder.injectionPoints(newInjectionPoints); final Bean newInjectionBean = beanBuilder.create(); for (final InjectionPoint ip : newInjectionBean.getInjectionPoints()) { Assert.assertNotNull(ip); } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/util/bean/SimpleClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.bean; /** * */ public class SimpleClass { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/api/util/bean/WithInjectionPoint.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.inject.Named; /** * */ @Named("ipoint") public class WithInjectionPoint { @Inject private BeanManager beanManager; } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/activation/ClassDeactivationEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class ClassDeactivationEarFileTest extends ClassDeactivationTest { // fixes Wildfly9 CNFE private final static String CONFIG = "# InterDynTest\n" + "deltaspike_ordinal=110\n" + "deltaspike.interdyn.enabled=false\n"; @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = ClassDeactivationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(ClassDeactivationWarFileTest.deploy() .addAsManifestResource(new StringAsset(CONFIG), "apache-deltaspike.properties")); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/custom/spi/PartialBeanAsInterfaceEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.custom.spi; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class PartialBeanAsInterfaceEarFileTest extends ServiceUtilsTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = ServiceUtilsWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(ServiceUtilsWarFileTest.deploy()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventQualifier.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.event; import jakarta.inject.Qualifier; @Qualifier public @interface EventQualifier { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/EventTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.event; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.core.spi.exception.control.event.IntrospectiveExceptionEvent; import org.apache.deltaspike.test.core.impl.exception.control.event.literal.EventQualifierLiteral; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) @ExceptionHandler public class EventTest { @Deployment(name = "EventTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "eventTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(EventTest.class, EventQualifier.class, EventQualifierLiteral.class); } @Inject private BeanManager bm; private int qualiferCalledCount = 0; @Test public void assertEventIsCreatedCorrectly() { bm.fireEvent(new ExceptionToCatchEvent(new NullPointerException())); } @Test public void assertEventWithQualifiersIsCreatedCorrectly() { bm.fireEvent(new ExceptionToCatchEvent(new NullPointerException(), new EventQualifierLiteral())); } public void verifyDescEvent(@BeforeHandles IntrospectiveExceptionEvent event) { qualiferCalledCount++; assertTrue(event.isBeforeTraversal()); } public void verifyAscEvent(@Handles IntrospectiveExceptionEvent event) { qualiferCalledCount++; assertFalse(event.isBeforeTraversal()); } public void verifyQualifierEvent(@Handles @EventQualifier ExceptionEvent event) { qualiferCalledCount++; assertThat(qualiferCalledCount, is(1)); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/event/literal/EventQualifierLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.event.literal; import org.apache.deltaspike.test.core.impl.exception.control.event.EventQualifier; import jakarta.enterprise.util.AnnotationLiteral; public class EventQualifierLiteral extends AnnotationLiteral implements EventQualifier { private static final long serialVersionUID = -7287578336564561662L; } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/extension/Account.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.extension; /** * */ public class Account { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/extension/Arquillian.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.extension; import jakarta.inject.Qualifier; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Arquillian { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/extension/CatchQualifier.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.extension; import jakarta.inject.Qualifier; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Qualifier @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface CatchQualifier { } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/extension/literal/CatchQualifierLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.extension.literal; import org.apache.deltaspike.test.core.impl.exception.control.extension.CatchQualifier; import jakarta.enterprise.util.AnnotationLiteral; /** * */ public class CatchQualifierLiteral extends AnnotationLiteral implements CatchQualifier { private static final long serialVersionUID = -5784558882329045733L; } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/AbortingBreadthFirstHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) @ApplicationScoped @ExceptionHandler public class AbortingBreadthFirstHandler { private boolean abortCalled = false; private boolean proceedCalled = false; public void abortHandler(@BeforeHandles ExceptionEvent event) { abortCalled = true; event.abort(); } public void proceedHandler(@Handles ExceptionEvent event) { proceedCalled = true; event.handledAndContinue(); } public boolean isAbortCalled() { return abortCalled; } public boolean isProceedCalled() { return proceedCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/AbortingDepthHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; @SuppressWarnings({"AssignmentToStaticFieldFromInstanceMethod"}) @ApplicationScoped @ExceptionHandler public class AbortingDepthHandler { private boolean abortCalled = false; private boolean proceedCalled = false; protected AbortingDepthHandler() { } public void abortHandler(@Handles ExceptionEvent event) { abortCalled = true; event.abort(); } public void proceedHandler(@Handles ExceptionEvent event) { proceedCalled = true; event.handledAndContinue(); } public boolean isAbortCalled() { return abortCalled; } public boolean isProceedCalled() { return proceedCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/BreadthFirstAbortControlTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class BreadthFirstAbortControlTest { @Inject private AbortingBreadthFirstHandler abortingBreadthFirstHandler; @Deployment(name = "BreadthFirstAbortControlTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "breadthFirstAbortControl.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(AbortingBreadthFirstHandler.class); } @Inject private BeanManager bm; @Test public void assertNoOtherHandlersCalledAfterAbort() { bm.fireEvent(new ExceptionToCatchEvent(new NullPointerException())); assertTrue(abortingBreadthFirstHandler.isAbortCalled()); assertFalse(abortingBreadthFirstHandler.isProceedCalled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/DepthAbortControlTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class DepthAbortControlTest { @Inject private BeanManager bm; @Inject private AbortingDepthHandler abortingDepthHandler; @Deployment(name = "DepthAbortControlTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "depthAbortControl.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClass(AbortingDepthHandler.class); } @Test public void assertNoOtherHandlersCalledAfterAbort() { bm.fireEvent(new ExceptionToCatchEvent(new NullPointerException())); assertTrue(abortingDepthHandler.isAbortCalled()); assertFalse(abortingDepthHandler.isProceedCalled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/ExceptionHandledHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @ExceptionHandler public class ExceptionHandledHandler { private boolean exAscCalled = false; private boolean iaeAscCalled = false; private boolean npeDescCalled = false; public void exHandler(@Handles ExceptionEvent event) { exAscCalled = true; } public void npeHandler(@Handles ExceptionEvent event) { iaeAscCalled = true; event.handled(); } public void npeDescHandler(@BeforeHandles ExceptionEvent event) { npeDescCalled = true; event.handled(); } public boolean isExAscCalled() { return exAscCalled; } public boolean isIaeAscCalled() { return iaeAscCalled; } public boolean isNpeDescCalled() { return npeDescCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/HandledExceptionHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class HandledExceptionHandlerTest { @Inject private ExceptionHandledHandler exceptionHandledHandler; @Deployment(name = "HandledExceptionHandlerTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "handledExceptionHandler.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(ExceptionHandledHandler.class); } @Inject private BeanManager bm; @Test public void assertNoHandlersAfterHandledAreCalled() { final ExceptionToCatchEvent entryEvent = new ExceptionToCatchEvent(new Exception( new NullPointerException())); bm.fireEvent(entryEvent); assertTrue(exceptionHandledHandler.isNpeDescCalled()); assertFalse(exceptionHandledHandler.isExAscCalled()); assertTrue(entryEvent.isHandled()); } @Test public void assertNoHandlersAfterHandledAreCalledDesc() { final ExceptionToCatchEvent event = new ExceptionToCatchEvent(new Exception(new IllegalArgumentException())); bm.fireEvent(event); assertTrue(exceptionHandledHandler.isIaeAscCalled()); assertFalse(exceptionHandledHandler.isExAscCalled()); assertTrue(event.isHandled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/ProceedCauseHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @ExceptionHandler public class ProceedCauseHandler { private int breadthFirstNpeCalled = 0; private int breadthFirstNpeLowerPrecedenceCalled = 0; private int depthFirstNpeCalled = 0; private int depthFirstNpeHigherPrecedenceCalled = 0; public void npeInboundHandler(@BeforeHandles ExceptionEvent event) { breadthFirstNpeCalled++; event.skipCause(); } public void npeLowerPrecedenceInboundHandler( @BeforeHandles(ordinal = -50) ExceptionEvent event) { breadthFirstNpeLowerPrecedenceCalled++; event.handledAndContinue(); } public void npeOutboundHandler(@Handles ExceptionEvent event) { depthFirstNpeCalled++; event.skipCause(); } public void npeHigherPrecedenceOutboundHandler(@Handles(ordinal = -10) ExceptionEvent event) { depthFirstNpeHigherPrecedenceCalled++; event.handledAndContinue(); } public int getBreadthFirstNpeCalled() { return breadthFirstNpeCalled; } public int getBreadthFirstNpeLowerPrecedenceCalled() { return breadthFirstNpeLowerPrecedenceCalled; } public int getDepthFirstNpeCalled() { return depthFirstNpeCalled; } public int getDepthFirstNpeHigherPrecedenceCalled() { return depthFirstNpeHigherPrecedenceCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/ProceedCauseHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static junit.framework.Assert.assertEquals; @RunWith(Arquillian.class) public class ProceedCauseHandlerTest { @Inject private ProceedCauseHandler proceedCauseHandler; @Deployment(name = "ProceedCauseHandlerTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "proceedCauseHandler.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(ProceedCauseHandler.class); } @Inject private BeanManager bm; @Test public void assertCorrectNumberOfHandlerCallsForProceedCause() { bm.fireEvent(new ExceptionToCatchEvent(new Exception(new IllegalArgumentException(new NullPointerException())))); assertEquals(0, proceedCauseHandler.getBreadthFirstNpeLowerPrecedenceCalled()); assertEquals(1, proceedCauseHandler.getBreadthFirstNpeCalled()); assertEquals(0, proceedCauseHandler.getDepthFirstNpeHigherPrecedenceCalled()); assertEquals(0, proceedCauseHandler.getDepthFirstNpeCalled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/RethrowHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; @ExceptionHandler public class RethrowHandler { static boolean iaeHandlerCalled = false; public void rethrow(@Handles ExceptionEvent event) { event.throwOriginal(); } public void rethrowInbound( @BeforeHandles ExceptionEvent event) { event.throwOriginal(); } public void handleInbound(@Handles ExceptionEvent event) { iaeHandlerCalled = true; } public static boolean isIaeHandlerCalled() { return iaeHandlerCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/RethrowTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.junit.Assert.assertFalse; @RunWith(Arquillian.class) public class RethrowTest { @Deployment(name = "RethrowTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "rethrow.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(RethrowHandler.class); } @Inject private BeanManager bm; @Test(expected = NullPointerException.class) public void assertOutboundRethrow() { final ExceptionToCatchEvent event = new ExceptionToCatchEvent(new NullPointerException()); try { bm.fireEvent(event); } catch (NullPointerException e) { assertFalse(event.isHandled()); throw e; } } @Test(expected = IllegalArgumentException.class) public void assertInboundRethrow() { final ExceptionToCatchEvent event = new ExceptionToCatchEvent(new IllegalArgumentException()); try { bm.fireEvent(event); } catch (IllegalArgumentException e) { assertFalse(event.isHandled()); assertFalse(RethrowHandler.isIaeHandlerCalled()); throw e; } } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/ThrowingNewExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; @RunWith(Arquillian.class) public class ThrowingNewExceptionTest { @Deployment(name = "ThrowingNewExceptionTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "throwingNew.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(ThrowingNewHandler.class); } @Inject private BeanManager bm; @Test(expected = UnsupportedOperationException.class) public void assertOutboundRethrow() { bm.fireEvent(new ExceptionToCatchEvent(new NullPointerException())); } @Test(expected = UnsupportedOperationException.class) public void assertInboundRethrow() { bm.fireEvent(new ExceptionToCatchEvent(new IllegalArgumentException())); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/flow/ThrowingNewHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.flow; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; @ExceptionHandler public class ThrowingNewHandler { public void rethrow(@Handles ExceptionEvent event) { event.rethrow(new UnsupportedOperationException()); } public void rethrowInbound( @BeforeHandles ExceptionEvent event) { event.rethrow(new UnsupportedOperationException()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/BadInjectionPointHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; /** * This handler is not valid as the injection point firstParam is not valid. */ @ExceptionHandler public class BadInjectionPointHandler { void handleException(int firstParam, @Handles ExceptionEvent event) { } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/CalledExceptionHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.BeanManager; import java.sql.SQLException; @ApplicationScoped @ExceptionHandler public class CalledExceptionHandler { private boolean outboundHandlerCalled = false; private int outboundHandlerTimesCalled = 0; private boolean protectedHandlerCalled = false; private int inboundHandlerTimesCalled = 0; private boolean beanmanagerInjected = false; private boolean locationDifferBeanmanagerInjected = false; public void basicHandler(@Handles ExceptionEvent event) { outboundHandlerCalled = true; outboundHandlerTimesCalled++; } public void basicInboundHandler(@BeforeHandles ExceptionEvent event) { inboundHandlerTimesCalled++; event.handledAndContinue(); } public void extraInjections(@Handles ExceptionEvent event, BeanManager bm) { if (bm != null) { beanmanagerInjected = true; } } void protectedHandler(@Handles ExceptionEvent event) { protectedHandlerCalled = true; if (!event.isMarkedHandled()) { event.handledAndContinue(); } } @SuppressWarnings("unused") private void handlerLocationInjections(BeanManager bm, @Handles ExceptionEvent event) { if (bm != null) { locationDifferBeanmanagerInjected = true; } } public boolean isOutboundHandlerCalled() { return outboundHandlerCalled; } public int getOutboundHandlerTimesCalled() { return outboundHandlerTimesCalled; } public boolean isProtectedHandlerCalled() { return protectedHandlerCalled; } public void setOutboundHandlerTimesCalled(int outboundHandlerTimesCalled) { this.outboundHandlerTimesCalled = outboundHandlerTimesCalled; } public void setInboundHandlerTimesCalled(int inboundHandlerTimesCalled) { this.inboundHandlerTimesCalled = inboundHandlerTimesCalled; } public int getInboundHandlerTimesCalled() { return inboundHandlerTimesCalled; } public boolean isBeanmanagerInjected() { return beanmanagerInjected; } public boolean isLocationDifferBeanmanagerInjected() { return locationDifferBeanmanagerInjected; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/CallingHandlersTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import java.sql.SQLException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class CallingHandlersTest { @Inject private CalledExceptionHandler calledExceptionHandler; @Deployment(name = "CallingHandlersTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "callingHandlers.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addClasses(CalledExceptionHandler.class) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject private BeanManager bm; @Test public void assertOutboundHanldersAreCalled() { bm.fireEvent(new ExceptionToCatchEvent(new IllegalArgumentException())); assertTrue(calledExceptionHandler.isOutboundHandlerCalled()); } @Test public void assertOutboundHanldersAreCalledOnce() { calledExceptionHandler.setOutboundHandlerTimesCalled(0); bm.fireEvent(new ExceptionToCatchEvent(new IllegalArgumentException())); assertEquals(1, calledExceptionHandler.getOutboundHandlerTimesCalled()); } @Test public void assertInboundHanldersAreCalledOnce() { calledExceptionHandler.setInboundHandlerTimesCalled(0); bm.fireEvent(new ExceptionToCatchEvent(new IllegalArgumentException())); assertEquals(1, calledExceptionHandler.getInboundHandlerTimesCalled()); } @Test public void assertAdditionalParamsAreInjected() { bm.fireEvent(new ExceptionToCatchEvent(new RuntimeException(new IllegalArgumentException()))); assertTrue(calledExceptionHandler.isBeanmanagerInjected()); } //@Test //TODO discuss this test public void assertAdditionalParamsAreInjectedWithDifferentHandlerLocation() { bm.fireEvent(new ExceptionToCatchEvent(new SQLException())); assertTrue(calledExceptionHandler.isLocationDifferBeanmanagerInjected()); } @Test public void assertProtectedHandlersAreCalled() { bm.fireEvent(new ExceptionToCatchEvent(new IllegalStateException())); assertTrue(calledExceptionHandler.isProtectedHandlerCalled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/ExtensionExceptionHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import org.apache.deltaspike.test.core.impl.exception.control.extension.Account; import org.apache.deltaspike.test.core.impl.exception.control.extension.Arquillian; import org.apache.deltaspike.test.core.impl.exception.control.extension.CatchQualifier; import jakarta.enterprise.inject.spi.BeanManager; import java.sql.SQLException; @ExceptionHandler public class ExtensionExceptionHandler { public void catchDescException(@BeforeHandles ExceptionEvent event) { // Nothing to do currently } public void catchFrameworkDescException(@BeforeHandles(ordinal = -50) ExceptionEvent event) { // Nothing to do here } public void catchRuntime(@Handles ExceptionEvent event) { // Nothing to do currently } public void catchThrowableBreadthFirst( @BeforeHandles(ordinal = 10) ExceptionEvent event) { // Nothing to do currently } public void catchThrowableP20BreadthFirst( @BeforeHandles(ordinal = 20) ExceptionEvent event) { // Nothing to do currently } public void catchThrowable( @Handles(ordinal = 10) ExceptionEvent event) { // Nothing to do currently } public void catchThrowableP20( @Handles(ordinal = 20) ExceptionEvent event) { // Nothing to do currently } public void catchIAE(@Handles ExceptionEvent event) { // Nothing to do currently } public void qualifiedHandler(@Handles @CatchQualifier ExceptionEvent event) { // Method to verify the qualifiers are working correctly for handlers } public void arqHandler(@Handles @Arquillian ExceptionEvent event) { // Method to verify the qualifiers are working correctly for handlers } public void arqTestingHandler(@Handles @Arquillian @CatchQualifier ExceptionEvent event) { // Method to verify the qualifiers are working correctly for handlers } public void differentParamHandlerLocationHandler(Account act, BeanManager bm, @Handles ExceptionEvent event) { // Nothing here, just need to make sure this handler is picked up } public void npeHandlerNoDefQualifier(@Handles ExceptionEvent event) { } public void npeHandlerDefQualifier(@Handles @CatchQualifier ExceptionEvent event) { } public void doNothingMethod() { // Method to make sure only @Handles methods are found } public void doNothingTwo(String p1, String p2, int p3) { // Same as above } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/HandlerComparatorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.HandlerMethod; import org.apache.deltaspike.core.impl.exception.control.HandlerMethodImpl; import org.apache.deltaspike.core.impl.exception.control.HandlerMethodStorage; import org.apache.deltaspike.test.core.impl.exception.control.extension.literal.CatchQualifierLiteral; import org.apache.deltaspike.test.core.impl.exception.control.extension.Account; import org.apache.deltaspike.test.core.impl.exception.control.extension.CatchQualifier; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @RunWith(Arquillian.class) public class HandlerComparatorTest { @Deployment(name = "HandlerComparatorTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "handlerComparator.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(ExtensionExceptionHandler.class, Account.class, org.apache.deltaspike.test.core.impl.exception.control.extension.Arquillian.class, CatchQualifier.class, CatchQualifierLiteral.class); } @Inject private BeanManager bm; @Inject private HandlerMethodStorage storage; @Test public void assertOrderIsCorrectDepthFirst() { List> handlers = new ArrayList>( storage.getHandlersForException(IllegalArgumentException.class, bm, Collections.emptySet(), false)); // System.out.println(handlers); assertThat(((HandlerMethodImpl) handlers.get(0)).getJavaMethod().getName(), is("catchThrowable")); assertThat(((HandlerMethodImpl) handlers.get(1)).getJavaMethod().getName(), is("catchThrowableP20")); assertThat(((HandlerMethodImpl) handlers.get(2)).getJavaMethod().getName(), is("catchRuntime")); assertThat(((HandlerMethodImpl) handlers.get(3)).getJavaMethod().getName(), is("catchIAE")); } @Test public void assertOrderIsCorrectWithQualifiers() { Set qualifiers = new HashSet(); qualifiers.add(new CatchQualifierLiteral()); List> handlers = new ArrayList>( storage.getHandlersForException(NullPointerException.class, bm, qualifiers, false)); assertThat(handlers.size(), is(6)); assertThat(((HandlerMethodImpl) handlers.get(0)).getJavaMethod().getName(), is("catchThrowable")); assertThat(((HandlerMethodImpl) handlers.get(1)).getJavaMethod().getName(), is("catchThrowableP20")); assertThat(((HandlerMethodImpl) handlers.get(2)).getJavaMethod().getName(), is("qualifiedHandler")); assertThat(((HandlerMethodImpl) handlers.get(3)).getJavaMethod().getName(), is("catchRuntime")); assertThat(((HandlerMethodImpl) handlers.get(4)).getJavaMethod().getName(), is("npeHandlerNoDefQualifier")); assertThat(((HandlerMethodImpl) handlers.get(5)).getJavaMethod().getName(), is("npeHandlerDefQualifier")); } @Test public void assertOrderIsCorrectBreadthFirst() { List> handlers = new ArrayList>( storage.getHandlersForException(Exception.class, bm, Collections.emptySet(), true)); assertThat(handlers.size(), is(4)); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/HandlerWhichThrowsExceptions.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; /** * ExceptionHandler which is not valid. */ @ExceptionHandler public class HandlerWhichThrowsExceptions { public void throwsAnException(@Handles ExceptionEvent evt) throws Exception { } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/UnMuteHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @ExceptionHandler public class UnMuteHandler { private int depthFirstNumberCalled = 0; private int breadthFirstNumberCalled = 0; public void unMuteHandlerAsc(@Handles ExceptionEvent event) { depthFirstNumberCalled++; event.unmute(); } public void unMuteHandlerDesc(@BeforeHandles ExceptionEvent event) { breadthFirstNumberCalled++; event.unmute(); } public int getDepthFirstNumberCalled() { return depthFirstNumberCalled; } public int getBreadthFirstNumberCalled() { return breadthFirstNumberCalled; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/handler/UnMuteHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.handler; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static junit.framework.Assert.assertEquals; @RunWith(Arquillian.class) public class UnMuteHandlerTest { @Inject private UnMuteHandler unMuteHandler; @Deployment(name = "UnMuteHandlerTest") public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "unMuteHandler.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addClasses(UnMuteHandler.class); } @Inject private BeanManager bm; @Test public void assertCorrectNumberOfCallsForUnMute() { bm.fireEvent(new ExceptionToCatchEvent(new Exception(new NullPointerException()))); assertEquals(2, unMuteHandler.getDepthFirstNumberCalled()); assertEquals(2, unMuteHandler.getBreadthFirstNumberCalled()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/traversal/ExceptionHandlerMethods.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.traversal; import org.apache.deltaspike.core.api.exception.control.BeforeHandles; import org.apache.deltaspike.core.api.exception.control.ExceptionHandler; import org.apache.deltaspike.core.api.exception.control.Handles; import org.apache.deltaspike.core.api.exception.control.event.ExceptionEvent; import java.util.ArrayList; import java.util.List; @ExceptionHandler public class ExceptionHandlerMethods { private static final List executionOrder = new ArrayList(); public void handleException1BF(@BeforeHandles ExceptionEvent event) { executionOrder.add(7); } public void handleException2BF(@BeforeHandles ExceptionEvent event) { executionOrder.add(5); } public void handleException3DF(@Handles ExceptionEvent event) { executionOrder.add(3); } public void handleException3BF(@BeforeHandles ExceptionEvent event) { executionOrder.add(2); } public void handleException3SuperclassBF(@BeforeHandles ExceptionEvent event) { executionOrder.add(1); } public void handleException3SuperclassDF(@Handles ExceptionEvent event) { executionOrder.add(4); } public void handleException2DF(@Handles ExceptionEvent event) { executionOrder.add(6); } public void handleException1DF(@Handles ExceptionEvent event) { executionOrder.add(8); } public static List getExecutionorder() { return executionOrder; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/traversal/Exceptions.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.traversal; public class Exceptions { public static class Exception1 extends Exception { private static final long serialVersionUID = 3748419159086636984L; public Exception1(Throwable cause) { super(cause); } } public static class Exception2 extends Exception { private static final long serialVersionUID = 7151417049655860515L; public Exception2(Throwable cause) { super(cause); } } public static class Exception3Super extends Exception { private static final long serialVersionUID = 1886009541068471679L; } public static class Exception3 extends Exception3Super { private static final long serialVersionUID = -7924704072611802705L; } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/exception/control/traversal/TraversalPathTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.exception.control.traversal; import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import static org.junit.Assert.assertArrayEquals; @RunWith(Arquillian.class) public class TraversalPathTest { @Inject private BeanManager manager; @Deployment public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "traversalPath.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addPackage(TraversalPathTest.class.getPackage()); } /** * Tests SEAMCATCH-32, see JIRA for more information about this test. https://issues.jboss.org/browse/SEAMCATCH-32 */ @Test public void testTraversalPathOrder() { // create an exception stack E1 -> E2 -> E3 Exceptions.Exception1 exception = new Exceptions.Exception1(new Exceptions.Exception2(new Exceptions.Exception3())); manager.fireEvent(new ExceptionToCatchEvent(exception)); /* handleException3SuperclassBF handleException3BF handleException3DF handleException3SuperclassDF handleException2BF handleException2DF handleException1BF handleException1DF */ Object[] expectedOrder = {1, 2, 3, 4, 5, 6, 7, 8}; assertArrayEquals(expectedOrder, ExceptionHandlerMethods.getExecutionorder().toArray()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class SimpleRegistrationEarFileTest extends SimpleRegistrationTest { public static final String CONFIG = "deltaspike.bean-manager.delegate_lookup=false\n"; // Weld3 bug :( @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = SimpleRegistrationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive configJar = ShrinkWrap.create(JavaArchive.class, "registrationConfig.jar") .addAsManifestResource(new StringAsset(CONFIG), "apache-deltaspike.properties"); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsLibrary(configJar) .addAsModule(SimpleRegistrationWarFileTest.deploy()); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/resourceloader/ClasspathResourceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.resourceloader; import org.apache.deltaspike.core.api.resourceloader.InjectableResource; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Properties; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ClasspathResourceTest { @Deployment public static Archive createResourceLoaderArchive() { Archive arch = ShrinkWrap.create(WebArchive.class, ClasspathResourceTest.class.getSimpleName() + ".war") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()); return arch; } @Inject @InjectableResource(location="myconfig.properties") private InputStream inputStream; @Inject @InjectableResource(location="myconfig.properties") private Properties properties; @Test public void testInputStream() throws IOException { Assert.assertNotNull(inputStream); Properties p = new Properties(); p.load(inputStream); Assert.assertEquals("somevalue", p.getProperty("some.propertykey", "wrong answer")); } @Test public void testProperties() { Assert.assertEquals("somevalue", properties.getProperty("some.propertykey", "wrong answer")); } @Test public void testAmbiguousFileLookup(@InjectableResource(location="META-INF/beans.xml") InputStream inputStream) { // for some reason, this works Assert.assertNull(inputStream); } @Test public void testSuccessfulAmbiguousLookup(@InjectableResource(location="META-INF/beans.xml") List inputStreams) { Assert.assertTrue(inputStreams.size() > 1); //the count is different on as7 compared to the standalone setup } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/resourceloader/ClasspathWebProfileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.resourceloader; import org.apache.deltaspike.core.api.resourceloader.InjectableResource; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; 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.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Properties; /** * web profile will run in a separate JVM, as a result need to manually add the properties to the archive. */ @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ClasspathWebProfileTest { @Deployment public static Archive createResourceLoaderArchive() { Archive arch = ShrinkWrap.create(WebArchive.class, ClasspathWebProfileTest.class.getSimpleName() + ".war") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsResource(new StringAsset("some.propertykey = somevalue"), "myconfig.properties") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()); return arch; } @Inject @InjectableResource(location="myconfig.properties") private InputStream inputStream; @Inject @InjectableResource(location="myconfig.properties") private Properties properties; @Test public void testInputStream() throws IOException { Assert.assertNotNull(inputStream); Properties p = new Properties(); p.load(inputStream); Assert.assertEquals("somevalue", p.getProperty("some.propertykey", "wrong answer")); } @Test public void testProperties() { Assert.assertEquals("somevalue", properties.getProperty("some.propertykey", "wrong answer")); } @Test public void testAmbiguousFileLookup(@InjectableResource(location="META-INF/beans.xml") InputStream inputStream) { Assert.assertNull(inputStream); // for some reason, this works, exception no longer thrown. } @Test public void testSuccessfulAmbiguousLookup(@InjectableResource(location="META-INF/beans.xml") List inputStreams) { Assert.assertTrue(inputStreams.size() > 1); //the count is different on as7 compared to the standalone setup } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/resourceloader/FileResourceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.resourceloader; import org.apache.deltaspike.core.api.resourceloader.InjectableResource; import org.apache.deltaspike.core.api.resourceloader.FileResourceProvider; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.util.Properties; @RunWith(Arquillian.class) @Category(SeCategory.class) public class FileResourceTest { private boolean created = false; @Before public void createTempFile() { if (!created) { File tmpDir = new File("target"); try { File dest = new File(tmpDir,"/propsdsfileresource.properties"); FileWriter fw = new FileWriter(dest); fw.write("some.propertykey=somevalue"); fw.close(); dest.deleteOnExit(); } catch (IOException e) { throw ExceptionUtils.throwAsRuntimeException(e); } finally { created = true; } } } @Deployment public static Archive createResourceLoaderArchive() { Archive arch = ShrinkWrap.create(WebArchive.class, FileResourceTest.class.getSimpleName() + ".war") .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()); return arch; } @Test public void testInputStream(@InjectableResource(resourceProvider = FileResourceProvider.class, location="target/propsdsfileresource.properties") InputStream inputStream) throws IOException { Assert.assertNotNull(inputStream); Properties p = new Properties(); p.load(inputStream); Assert.assertEquals("somevalue", p.getProperty("some.propertykey", "wrong answer")); } @Test public void testProperties(@InjectableResource(resourceProvider = FileResourceProvider.class, location="target/propsdsfileresource.properties") Properties properties) { Assert.assertEquals("somevalue", properties.getProperty("some.propertykey", "wrong answer")); } } ================================================ FILE: deltaspike/core/impl/obsolete/src/test/java/org/apache/deltaspike/test/core/impl/util/JndiUtilsEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.util; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class JndiUtilsEarFileTest extends JndiUtilsTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = JndiUtilsWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(JndiUtilsWarFileTest.deploy()); } } ================================================ FILE: deltaspike/core/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.core core-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.core deltaspike-core-impl jar Apache DeltaSpike Core-Implementation org.apache.deltaspike.core.impl.* !org.apache.deltaspike.core.impl.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)", org.ops4j.pax.cdi.extension; filter:="(extension=deltaspike-core-api)" org.ops4j.pax.cdi.extension; extension=deltaspike-core-impl org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.test test-utils ${project.version} provided org.jboss.shrinkwrap.descriptors shrinkwrap-descriptors-impl-javaee test org.apache.maven.plugins maven-jar-plugin src/main/resources/META-INF/MANIFEST.MF ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/activation/DefaultClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.activation; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import java.util.logging.Level; import java.util.logging.Logger; /** * This is a default implementation of ClassDeactivator which uses {@see ConfigSource} to resolve configuration options * for whether a class is active or not. * * By design, this is not a well performant implementation. It is a useful utility to avoid implementing the interface * manually and may be an easy way to spin up test archives with some classes purposefully disabled. */ public class DefaultClassDeactivator implements ClassDeactivator { public static final String KEY_PREFIX = "deactivate."; private static final Logger LOG = Logger.getLogger(DefaultClassDeactivator.class.getName()); @Override public Boolean isActivated(Class targetClass) { final String key = KEY_PREFIX + targetClass.getName(); final String value = ConfigResolver.getPropertyValue(key); if (value == null) { return null; } else { if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Deactivation setting for {0} found to be {1} based on configuration.", new Object[]{key, value}); } return !Boolean.valueOf(value); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/BaseConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.deltaspike.core.spi.config.ConfigSource; /** * Base class for all our ConfigSources */ public abstract class BaseConfigSource implements ConfigSource { protected Logger log = Logger.getLogger(getClass().getName()); private int ordinal = 1000; // default /** * {@inheritDoc} */ @Override public int getOrdinal() { return ordinal; } /** * Init method e.g. for initializing the ordinal. * This method can be used from a subclass to determine * the ordinal value * @param defaultOrdinal the default value for the ordinal if not set via configuration */ protected void initOrdinal(int defaultOrdinal) { ordinal = defaultOrdinal; String configuredOrdinalString = getPropertyValue(ConfigSource.DELTASPIKE_ORDINAL); try { if (configuredOrdinalString != null) { ordinal = Integer.parseInt(configuredOrdinalString.trim()); } } catch (NumberFormatException e) { log.log(Level.WARNING, "The configured config-ordinal isn't a valid integer. Invalid value: " + configuredOrdinalString); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigHelperImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.ConfigResolver; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; public class ConfigHelperImpl implements ConfigResolver.ConfigHelper { @Override public Set diffConfig(Map oldValues, Map newValues) { if (oldValues == null) { oldValues = Collections.emptyMap(); } if (newValues == null) { newValues = Collections.emptyMap(); } Set changedAttribs = new HashSet<>(); Set oldKeys = new HashSet<>(oldValues.keySet()); for (Map.Entry newPropEntry : newValues.entrySet()) { String key = newPropEntry.getKey(); if (oldValues.containsKey(key)) { if (compare(oldValues.get(key), newPropEntry.getValue()) != 0) { changedAttribs.add(key); } oldKeys.remove(key); } else { changedAttribs.add(key); } } changedAttribs.addAll(oldKeys); return changedAttribs; } private int compare(String a, String b) { if (a == null && b == null) { return 0; } if (a != null) { return a.compareTo(b); } return 1; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.ConfigSnapshot; import org.apache.deltaspike.core.impl.config.converter.BeanConverterFactory; import org.apache.deltaspike.core.spi.config.ConfigFilter; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.ConfigSourceProvider; import org.apache.deltaspike.core.util.ServiceUtils; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; /** * The internal implementation of the Config interface */ public class ConfigImpl implements Config { /** * How many times should we at max retry to get multiple attributes in an atomic way. */ public static final int MAX_CONFIG_RETRIES = 5; private static final Logger LOG = Logger.getLogger(ConfigImpl.class.getName()); private final ClassLoader classLoader; private ConfigSource[] configSources; private List configFilters; // volatile to a.) make the read/write behave atomic and b.) guarantee multi-thread safety private volatile long lastChanged = 0; private BeanConverterFactory beanConverter; public ConfigImpl(ClassLoader classLoader) { this.classLoader = classLoader; this.beanConverter = new BeanConverterFactory(); } /** * Performs all the initialisation of the default * ConfigSources, ConfigFilters, etc */ void init() { List appConfigSources = ServiceUtils.loadServiceImplementations(ConfigSource.class, false, classLoader); List configSourceProviderServiceLoader = ServiceUtils.loadServiceImplementations(ConfigSourceProvider.class, false, classLoader); for (ConfigSourceProvider configSourceProvider : configSourceProviderServiceLoader) { appConfigSources.addAll(configSourceProvider.getConfigSources()); } addConfigSources(appConfigSources); if (LOG.isLoggable(Level.FINE)) { for (ConfigSource cs : appConfigSources) { LOG.log(Level.FINE, "Adding ordinal {0} ConfigSource {1}", new Object[]{cs.getOrdinal(), cs.getConfigName()}); } } List configFilters = ServiceUtils.loadServiceImplementations(ConfigFilter.class, false, classLoader); this.configFilters = new CopyOnWriteArrayList<>(configFilters); } /** * Shuts down the Config. * This will also close all ConfigSources and ConfigFilters which * implment the {@link java.lang.AutoCloseable} interface. */ void release() { for (ConfigSource configSource : configSources) { close(configSource); } for (ConfigFilter configFilter : configFilters) { close(configFilter); } } private void close(Object o) { if (o instanceof AutoCloseable) { try { ((AutoCloseable) o).close(); } catch (Exception e) { LOG.log(Level.INFO, "Exception while closing " + o.toString(), e); } } } @Override public ConfigSource[] getConfigSources() { return configSources; } public BeanConverterFactory getBeanConverter() { return beanConverter; } @Override public ConfigSnapshot snapshotFor(ConfigResolver.TypedResolver... typedResolvers) { // we implement kind of optimistic Locking // Means we try multiple time to resolve all the given values // until the config didn't change inbetween. for (int tries = 1; tries < MAX_CONFIG_RETRIES; tries++) { Map, Object> configValues = new HashMap<>(); long startReadLastChanged = lastChanged; for (ConfigResolver.TypedResolver typedResolver : typedResolvers) { configValues.put(typedResolver, typedResolver.getValue()); } if (startReadLastChanged == lastChanged) { return new ConfigSnapshotImpl(configValues); } } throw new IllegalStateException( "Could not resolve ConfigTransaction as underlying values are permanently changing!"); } @Override public void addConfigSources(List configSourcesToAdd) { if (configSourcesToAdd == null || configSourcesToAdd.isEmpty()) { return; } List allConfigSources = new ArrayList<>(); // start with all existing ConfigSources if (this.configSources != null) { for (ConfigSource configSource : this.configSources) { allConfigSources.add(configSource); } } for (ConfigSource configSourceToAdd : configSourcesToAdd) { configSourceToAdd.setOnAttributeChange(this::onAttributeChange); allConfigSources.add(configSourceToAdd); } this.configSources = sortDescending(allConfigSources); } @Override public List getConfigFilters() { return Collections.unmodifiableList(configFilters); } @Override public void addConfigFilter(ConfigFilter configFilter) { configFilters.add(configFilter); } @Override public String filterConfigValue(String key, String value, boolean forLog) { String filteredValue = value; for (ConfigFilter filter : configFilters) { filteredValue = forLog ? filter.filterValueForLog(key, filteredValue) : filter.filterValue(key, filteredValue); } return filteredValue; } @Override public ConfigResolver.UntypedResolver resolve(String name) { return new TypedResolverImpl(this, name); } private ConfigSource[] sortDescending(List configSources) { Collections.sort(configSources, new Comparator() { /** * {@inheritDoc} */ @Override public int compare(ConfigSource configSource1, ConfigSource configSource2) { int o1 = configSource1.getOrdinal(); int o2 = configSource2.getOrdinal(); if (o1 == o2) { return configSource1.getConfigName().compareTo(configSource2.getConfigName()); } return (o1 > o2) ? -1 : 1; } }); return configSources.toArray(new ConfigSource[configSources.size()]); } public void onAttributeChange(Set attributesChanged) { // this is to force an incremented lastChanged even on time glitches and fast updates long newLastChanged = System.nanoTime(); lastChanged = lastChanged >= newLastChanged ? lastChanged++ : newLastChanged; } /** * @return the nanoTime when the last change got reported by a ConfigSource */ public long getLastChanged() { return lastChanged; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigProviderImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.util.ClassUtils; import java.util.Iterator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** */ public class ConfigProviderImpl implements ConfigResolver.ConfigProvider { /** * The content of this map will get lazily initiated and will hold the * Configs for each WebApp/EAR, etc (thus the ClassLoader). */ private static Map configs = new ConcurrentHashMap<>(); @Override public Config getConfig() { ClassLoader cl = ClassUtils.getClassLoader(null); return getConfig(cl); } @Override public Config getConfig(ClassLoader cl) { ConfigImpl config = configs.get(cl); if (config == null) { config = new ConfigImpl(cl); config.init(); ConfigImpl oldConfig = configs.put(cl, config); if (oldConfig != null) { config = oldConfig; } } return config; } @Override public void releaseConfig(ClassLoader cl) { ConfigImpl oldConfig = configs.remove(cl); if (oldConfig != null) { oldConfig.release(); } // And remove all the children as well. // This will e.g happen in EAR scenarios Iterator> it = configs.entrySet().iterator(); while (it.hasNext()) { Map.Entry cfgEntry = it.next(); if (isChildClassLoader(cl, cfgEntry.getKey())) { cfgEntry.getValue().release(); it.remove(); } } } @Override public ConfigResolver.ConfigHelper getHelper() { return new ConfigHelperImpl(); } private boolean isChildClassLoader(ClassLoader configClassLoader, ClassLoader suspect) { ClassLoader suspectParentCl = suspect.getParent(); if (suspectParentCl == null) { return false; } if (suspectParentCl == configClassLoader) { return true; } return isChildClassLoader(configClassLoader, suspectParentCl); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigResolverContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; class ConfigResolverContext { static final ConfigResolverContext NONE = new ConfigResolverContext(); static final ConfigResolverContext EVAL_VARIABLES = new ConfigResolverContext().setEvaluateVariables(true); static final ConfigResolverContext PROJECTSTAGE = new ConfigResolverContext().setProjectStageAware(true); static final ConfigResolverContext PROJECTSTAGE_EVAL_VARIABLES = new ConfigResolverContext() .setProjectStageAware(true) .setEvaluateVariables(true); private boolean projectStageAware; private boolean evaluateVariables; private boolean propertyAware; ConfigResolverContext() { } ConfigResolverContext setEvaluateVariables(final boolean evaluateVariables) { this.evaluateVariables = evaluateVariables; return this; } boolean isEvaluateVariables() { return evaluateVariables; } ConfigResolverContext setProjectStageAware(final boolean projectStageAware) { this.projectStageAware = projectStageAware; return this; } boolean isProjectStageAware() { return projectStageAware; } ConfigResolverContext setPropertyAware(final boolean propertyAware) { this.propertyAware = propertyAware; return this; } boolean isPropertyAware() { return propertyAware; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigSnapshotImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.ConfigSnapshot; import java.util.Map; public class ConfigSnapshotImpl implements ConfigSnapshot { private final Map, Object> configValues; public ConfigSnapshotImpl(Map, Object> configValues) { this.configValues = configValues; } public Map, Object> getConfigValues() { return configValues; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigurationExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Typed; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.BeforeShutdown; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import jakarta.enterprise.inject.spi.ProcessBean; import jakarta.enterprise.inject.spi.ProcessProducerMethod; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.annotation.Annotation; import java.lang.management.ManagementFactory; import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.Configuration; import org.apache.deltaspike.core.api.config.Filter; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.core.api.config.Source; import org.apache.deltaspike.core.api.exclude.Exclude; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; import org.apache.deltaspike.core.spi.config.ConfigFilter; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.ConfigValidator; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.core.util.StringUtils; /** * This extension handles {@link org.apache.deltaspike.core.api.config.PropertyFileConfig}s * provided by users. */ public class ConfigurationExtension implements Extension, Deactivatable { private static final Logger LOG = Logger.getLogger(ConfigurationExtension.class.getName()); private static final String CANNOT_CREATE_CONFIG_SOURCE_FOR_CUSTOM_PROPERTY_FILE_CONFIG = "Cannot create ConfigSource for custom property-file config "; /** * This is a trick for EAR scenarios in some containers. * They e.g. boot up the shared EAR lib with the ear ClassLoader. * Thus any {@link org.apache.deltaspike.core.api.config.PropertyFileConfig} configuration will just get * activated for this very single EAR ClassLoader but not for all the webapps. * But if I have a property file in a jar in the shared EAR lib then I most likely also like to get it * if I call this from my webapp (TCCL). * So we also automatically register all the PropertyFileConfigs we found in the 'parent BeanManager' * as well. */ private static Map>> detectedParentPropertyFileConfigs = new ConcurrentHashMap>>(); private boolean isActivated = true; private List> propertyFileConfigClasses = new ArrayList>(); private final Set dynamicConfigTypes = new HashSet(); private Bean dynamicProducer; private final List> cdiSources = new ArrayList>(); private final List> cdiFilters = new ArrayList>(); private final List> dynamicConfigurationBeanClasses = new ArrayList>(); @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } public static void registerConfigMBean() { String appName = ConfigResolver.getPropertyValue(ConfigResolver.DELTASPIKE_APP_NAME_CONFIG); if (appName != null && appName.length() > 0) { try { MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); ClassLoader tccl = ClassUtils.getClassLoader(ConfigurationExtension.class); DeltaSpikeConfigInfo cfgMBean = new DeltaSpikeConfigInfo(tccl); ObjectName name = new ObjectName("deltaspike.config." + appName + ":type=DeltaSpikeConfig"); mBeanServer.registerMBean(cfgMBean, name); } catch (InstanceAlreadyExistsException iae) { // all fine, the CfgBean got already registered. // Most probably by the ServletConfigListener } catch (Exception e) { throw new RuntimeException(e); } } } public static void unRegisterConfigMBean(String appName) { if (appName != null && appName.length() > 0) { try { MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("deltaspike.config." + appName + ":type=DeltaSpikeConfig"); mBeanServer.unregisterMBean(name); } catch (InstanceNotFoundException infe) { // all ok, nothing to de-register it seems } catch (Exception e) { throw new RuntimeException(e); } } } @SuppressWarnings("UnusedDeclaration") public void collectUserConfigSources(@Observes ProcessAnnotatedType pat) { if (!isActivated) { return; } Class pcsClass = pat.getAnnotatedType().getJavaClass(); if (pcsClass.isAnnotation() || pcsClass.isInterface() || pcsClass.isSynthetic() || pcsClass.isArray() || pcsClass.isEnum() ) { // we only like to add real classes return; } if (pat.getAnnotatedType().isAnnotationPresent(Exclude.class)) { // We only pick up PropertyFileConfigs if they are not excluded // This can be the case for PropertyFileConfigs which are registered via java.util.ServiceLoader return; } propertyFileConfigClasses.add(pcsClass); } public void findDynamicConfigurationBeans(@Observes ProcessAnnotatedType pat) { if (!pat.getAnnotatedType().isAnnotationPresent(Configuration.class)) { return; } final Class javaClass = pat.getAnnotatedType().getJavaClass(); if (!javaClass.isInterface()) { return; } dynamicConfigurationBeanClasses.add(javaClass); } public void findSources(@Observes ProcessBean source) { if (!source.getAnnotated().isAnnotationPresent(Source.class)) { return; } cdiSources.add(source.getBean()); } public void findFilters(@Observes ProcessBean filter) { if (!filter.getAnnotated().isAnnotationPresent(Filter.class)) { return; } cdiFilters.add(filter.getBean()); } public void findDynamicProducer(@Observes ProcessProducerMethod processBean) { dynamicProducer = processBean.getBean(); } public void collectDynamicTypes(@Observes ProcessBean processBean) { for (final InjectionPoint ip : processBean.getBean().getInjectionPoints()) { final ConfigProperty annotation = ip.getAnnotated().getAnnotation(ConfigProperty.class); if (annotation == null || annotation.converter() == ConfigResolver.Converter.class) { continue; } dynamicConfigTypes.add(ip.getType()); } } public void addDynamicBeans(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager bm) { if (dynamicProducer != null && !dynamicConfigTypes.isEmpty()) { afterBeanDiscovery.addBean(new DynamicBean(dynamicProducer, dynamicConfigTypes)); } for (final Class proxyType : dynamicConfigurationBeanClasses) { afterBeanDiscovery.addBean() .types(proxyType, Object.class) .qualifiers(Default.Literal.INSTANCE, Any.Literal.INSTANCE) .scope(ApplicationScoped.class) .id("DeltaSpikeConfiguration#" + proxyType.getName()) .createWith(cc -> { // TODO: support partialbean binding? can make sense for virtual properties + // would integrate with jcache // we'd need to add @PartialBeanBinding on a bean created from ConfigurationHandler // detection can just be a loadClass of this API // for now: waiting for user request for it final Class[] api = new Class[]{proxyType}; final Configuration configuration = api[0].getAnnotation(Configuration.class); final long cacheFor = configuration.cacheFor(); return Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), api, new ProxyConfigurationLifecycle.ConfigurationHandler( cacheFor <= 0 ? -1 : configuration.cacheUnit().toMillis(cacheFor), configuration.prefix()) ); }) .beanClass(proxyType); } } @SuppressWarnings("UnusedDeclaration") public void registerUserConfigSources(@Observes AfterBeanDiscovery abd) { if (!isActivated) { return; } // create a local copy with all the collected PropertyFileConfig Set> allPropertyFileConfigClasses = new HashSet>(this.propertyFileConfigClasses); // now add any PropertyFileConfigs from a 'parent BeanManager' // we start with the current TCCL ClassLoader currentClassLoader = ClassUtils.getClassLoader(null); addParentPropertyFileConfigs(currentClassLoader, allPropertyFileConfigClasses); // now let's add our own PropertyFileConfigs to the detected ones. // because maybe WE are a parent BeanManager ourselves! if (!this.propertyFileConfigClasses.isEmpty()) { detectedParentPropertyFileConfigs.put(currentClassLoader, this.propertyFileConfigClasses); } // collect all the ConfigSources from our PropertyFileConfigs List configSources = new ArrayList(); for (Class propertyFileConfigClass : allPropertyFileConfigClasses) { configSources.addAll(createPropertyConfigSource(propertyFileConfigClass)); } ConfigResolver.addConfigSources(configSources); registerConfigMBean(); logConfiguration(); } public void validateConfiguration(@Observes AfterDeploymentValidation adv) { List configSources = new ArrayList(cdiSources.size()); for (final Bean bean : cdiSources) { configSources.add(BeanProvider.getContextualReference(ConfigSource.class, bean)); } ConfigResolver.addConfigSources(configSources); for (final Bean bean : cdiFilters) { ConfigResolver.addConfigFilter(BeanProvider.getContextualReference(ConfigFilter.class, bean)); } processConfigurationValidation(adv); } private void logConfiguration() { Boolean logConfig = ConfigResolver.resolve(ConfigResolver.DELTASPIKE_LOG_CONFIG).as(Boolean.class).getValue(); if (logConfig != null && logConfig && LOG.isLoggable(Level.INFO)) { StringBuilder sb = new StringBuilder(1 << 16); // first log out the config sources in descendent ordinal order sb.append("ConfigSources: "); ConfigSource[] configSources = ConfigResolver.getConfigSources(); for (int i = 0; i < configSources.length; i++) { ConfigSource configSource = configSources[i]; sb.append("\n\t").append(configSource.getOrdinal()).append(" - ").append(configSource.getConfigName()) .append(" (CS_").append(i + 1).append(")"); } // and all the entries in no guaranteed order Map allProperties = ConfigResolver.getAllProperties(); sb.append("\n\nConfigured Values:"); for (Map.Entry entry : allProperties.entrySet()) { int fromConfigSource; sb.append("\n\t") .append(entry.getKey()) .append(" = ") .append(ConfigResolver.filterConfigValueForLog(entry.getKey(), entry.getValue())) .append(" (") .append(configuredIn(configSources, entry.getKey())) .append(")"); } LOG.info(sb.toString()); } } private static String configuredIn(ConfigSource[] configSources, String key) { int foundInOrdinal = -1; int foundInConfigSource = -1; for (int i = 0; i < configSources.length; i++) { ConfigSource configSource = configSources[i]; if ((configSource.isScannable() && configSource.getProperties().containsKey(key) || !configSource.isScannable() && StringUtils.isNotEmpty(configSource.getPropertyValue(key))) && configSource.getOrdinal() > foundInOrdinal) { foundInConfigSource = i; foundInOrdinal = configSource.getOrdinal(); } } return "CS_" + (foundInConfigSource + 1); } /** * Add all registered PropertyFileConfigs which got picked up in a parent ClassLoader already */ private void addParentPropertyFileConfigs(ClassLoader currentClassLoader, Set> propertyFileConfigClasses) { if (currentClassLoader.getParent() == null) { return; } for (Map.Entry>> classLoaderListEntry : detectedParentPropertyFileConfigs.entrySet()) { if (currentClassLoader.getParent().equals(classLoaderListEntry.getKey())) { // if this is the direct parent ClassLoader then lets add those PropertyFileConfigs. propertyFileConfigClasses.addAll(classLoaderListEntry.getValue()); // even check further parents addParentPropertyFileConfigs(classLoaderListEntry.getKey(), propertyFileConfigClasses); // and be done. There can only be a single parent CL... return; } } } /** * This method triggers freeing of the ConfigSources. */ @SuppressWarnings("UnusedDeclaration") public void freeConfigSources(@Observes BeforeShutdown bs) { String appName = ConfigResolver.getPropertyValue(ConfigResolver.DELTASPIKE_APP_NAME_CONFIG); unRegisterConfigMBean(appName); ConfigResolver.freeConfigSources(); detectedParentPropertyFileConfigs.remove(ClassUtils.getClassLoader(null)); // we also free the ClassDeactivationUtils cache ClassDeactivationUtils.clearCache(); } /** * @return create an instance of the given {@link PropertyFileConfig} and return all it's ConfigSources. */ private List createPropertyConfigSource(Class propertyFileConfigClass) { String fileName = ""; try { PropertyFileConfig propertyFileConfig = propertyFileConfigClass.newInstance(); fileName = propertyFileConfig.getPropertyFileName(); EnvironmentPropertyConfigSourceProvider environmentPropertyConfigSourceProvider = new EnvironmentPropertyConfigSourceProvider(fileName, propertyFileConfig.isOptional()); return environmentPropertyConfigSourceProvider.getConfigSources(); } catch (InstantiationException e) { throw new RuntimeException(CANNOT_CREATE_CONFIG_SOURCE_FOR_CUSTOM_PROPERTY_FILE_CONFIG + propertyFileConfigClass.getName(), e); } catch (IllegalAccessException e) { throw new RuntimeException(CANNOT_CREATE_CONFIG_SOURCE_FOR_CUSTOM_PROPERTY_FILE_CONFIG + propertyFileConfigClass.getName(), e); } catch (IllegalStateException e) { throw new IllegalStateException( propertyFileConfigClass.getName() + " points to an invalid file: '" + fileName + "'", e); } } protected void processConfigurationValidation(AfterDeploymentValidation adv) { for (ConfigValidator configValidator : ServiceUtils.loadServiceImplementations(ConfigValidator.class)) { Set violations = configValidator.processValidation(); if (violations == null) { continue; } for (String violation : violations) { adv.addDeploymentProblem(new IllegalStateException(violation)); } } } @ApplicationScoped @Typed(DynamicBeanProducer.class) // used as an internal bean static class DynamicBeanProducer extends BaseConfigPropertyProducer { @Produces @ConfigProperty(name = "ignored") public Object create(final InjectionPoint ip) { return super.getUntypedPropertyValue(ip, ip.getType()); } } @Vetoed private static final class DynamicBean implements Bean { private final Bean producer; private final Set types; private DynamicBean(final Bean producer, final Set types) { this.producer = producer; this.types = types; } @Override public Set getTypes() { return types; } /** * this method got dumped in EE10, but still exists in EE9 */ public boolean isNullable() { return true; } @Override public Set getQualifiers() { return producer.getQualifiers(); } @Override public Class getScope() { return producer.getScope(); } @Override public String getName() { return producer.getName(); } @Override public Set getInjectionPoints() { return producer.getInjectionPoints(); } @Override public Class getBeanClass() { return producer.getBeanClass(); } @Override public Set> getStereotypes() { return producer.getStereotypes(); } @Override public boolean isAlternative() { return producer.isAlternative(); } @Override public T create(final CreationalContext creationalContext) { return producer.create(creationalContext); } @Override public void destroy(final T t, final CreationalContext creationalContext) { producer.destroy(t, creationalContext); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigPropertyProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; import org.apache.deltaspike.core.api.config.ConfigProperty; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.function.Supplier; /** * This class contains producer methods for injecting * configuration provided with the {@link ConfigProperty} * annotation. */ @ApplicationScoped @SuppressWarnings("UnusedDeclaration") public class DefaultConfigPropertyProducer extends BaseConfigPropertyProducer { @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public String produceStringConfiguration(InjectionPoint injectionPoint) { return getStringPropertyValue(injectionPoint); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Class produceClassConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Class.class); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Boolean produceBooleanConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Boolean.class); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Integer produceIntegerConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Integer.class); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Long produceLongConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Long.class); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Float produceFloatConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Float.class); } @Produces @Dependent @ConfigProperty(name = "ignored") // we actually don't need the name public Double produceDoubleConfiguration(InjectionPoint injectionPoint) { return getPropertyWithException(injectionPoint, Double.class); } @Produces @Dependent @ConfigProperty(name = "ignore") public Supplier produceConfigSupplier(InjectionPoint injectionPoint) { ConfigProperty configProperty = getAnnotation(injectionPoint, ConfigProperty.class); if (configProperty == null) { throw new IllegalStateException("producer method called without @ConfigProperty being present!"); } final Type injectionPointType = injectionPoint.getType(); Type ipClass = null; if (injectionPointType instanceof ParameterizedType && ((ParameterizedType) injectionPointType).getActualTypeArguments().length == 1) { ipClass = ((ParameterizedType) injectionPointType).getActualTypeArguments()[0]; } else { throw new IllegalStateException("Supplier for Configuration must be a Parameterized Type"); } ConfigResolver.TypedResolver resolver = asResolver(configProperty.name(), configProperty.defaultValue(), ipClass, configProperty.converter(), configProperty.parameterizedBy(), configProperty.projectStageAware(), configProperty.evaluateVariables()); if (configProperty.cacheFor() > 0) { resolver.cacheFor(configProperty.cacheUnit(), configProperty.cacheFor()); } return () -> resolver.getValue(); } private T getPropertyWithException(InjectionPoint ip, Type ipCls) { try { return getUntypedPropertyValue(ip, ipCls); } catch (RuntimeException rte) { ConfigProperty configProperty = getAnnotation(ip, ConfigProperty.class); throw new RuntimeException("Error while converting property '" + configProperty.name() + "' happening in bean " + ip.getBean(), rte); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DefaultConfigSourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.ConfigSourceProvider; import org.apache.deltaspike.core.util.ServiceUtils; import java.io.File; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Default implementation which uses: *
    *
  1. SystemPropertyConfigSource
  2. *
  3. EnvironmentPropertyConfigSource
  4. *
  5. LocalJndiConfigSource
  6. *
  7. PropertyFileConfigSource
  8. *
*/ public class DefaultConfigSourceProvider implements ConfigSourceProvider { private static final Logger LOG = Logger.getLogger(DefaultConfigSourceProvider.class.getName()); private static final String PROPERTY_FILE_NAME = "apache-deltaspike.properties"; private static final String PROPERTY_FILE_RESOURCE = "META-INF/" + PROPERTY_FILE_NAME; private static final String PROPERTY_FILE_HOME_NAME = "/.deltaspike/" + PROPERTY_FILE_NAME; private List configSources = new ArrayList(); /** * Default constructor which adds the {@link ConfigSource} implementations which are supported by default */ public DefaultConfigSourceProvider() { configSources.add(new SystemPropertyConfigSource()); configSources.add(new EnvironmentPropertyConfigSource()); configSources.add(new LocalJndiConfigSource()); addUserHomeConfigSource(); EnvironmentPropertyConfigSourceProvider epcsp = new EnvironmentPropertyConfigSourceProvider(PROPERTY_FILE_RESOURCE, true); configSources.addAll(epcsp.getConfigSources()); registerPropertyFileConfigs(); } /** * Add a ConfigSource for files in the user home folder IF it exists! * The location is ~/.deltaspike/apache-deltaspike.properties */ private void addUserHomeConfigSource() { String userHome = System.getProperty("user.home"); if (userHome != null && !userHome.isEmpty()) { File dsHome = new File(userHome, PROPERTY_FILE_HOME_NAME); try { if (dsHome.exists()) { try { ConfigSource dsHomeConfigSource = new PropertyFileConfigSource(dsHome.toURI().toURL()); configSources.add(dsHomeConfigSource); LOG.log(Level.INFO, "Reading configuration from {0}", dsHome.getAbsolutePath()); } catch (MalformedURLException e) { LOG.log(Level.WARNING, "Could not read configuration from " + dsHome.getAbsolutePath(), e); } } } catch (SecurityException se) { LOG.log(Level.INFO, "Not allowed to check if directory {0} exists", dsHome.getPath()); } } } /** * Load all {@link PropertyFileConfig}s which are registered via * {@code java.util.ServiceLoader}. */ private void registerPropertyFileConfigs() { List propertyFileConfigs = ServiceUtils.loadServiceImplementations(PropertyFileConfig.class); for (PropertyFileConfig propertyFileConfig : propertyFileConfigs) { EnvironmentPropertyConfigSourceProvider environmentPropertyConfigSourceProvider = new EnvironmentPropertyConfigSourceProvider(propertyFileConfig.getPropertyFileName(), propertyFileConfig.isOptional()); configSources.addAll(environmentPropertyConfigSourceProvider.getConfigSources()); } } /** * {@inheritDoc} */ @Override public List getConfigSources() { return configSources; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DeltaSpikeConfigInfo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.config.ConfigSource; /** * JMX MBean for DeltaSpike */ public class DeltaSpikeConfigInfo implements DeltaSpikeConfigInfoMBean { private final ClassLoader appConfigClassLoader; public DeltaSpikeConfigInfo(ClassLoader appConfigClassLoader) { this.appConfigClassLoader = appConfigClassLoader; } @Override public String[] getConfigSourcesAsString() { ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(appConfigClassLoader); ConfigSource[] configSources = ConfigResolver.getConfigSources(); List configSourceInfo = new ArrayList(); for (ConfigSource configSource : configSources) { configSourceInfo.add(Integer.toString(configSource.getOrdinal()) + " - " + configSource.getConfigName()); } return configSourceInfo.toArray(new String[configSourceInfo.size()]); } finally { // set back the original TCCL Thread.currentThread().setContextClassLoader(originalCl); } } @Override public String[] getConfigEntriesAsString() { ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(appConfigClassLoader); List configEntries = calculateConfigEntries(); String[] configArray = new String[configEntries.size()]; for (int i = 0 ; i < configEntries.size(); i++) { ConfigEntry configEntry = configEntries.get(i); configArray[i] = configEntry.getKey() + " = " + configEntry.getValue() + " - picked up from: " + configEntry.getFromConfigSource(); } return configArray; } finally { // set back the original TCCL Thread.currentThread().setContextClassLoader(originalCl); } } @Override public TabularData getConfigEntries() { ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(appConfigClassLoader); List configEntries = calculateConfigEntries(); String[] configArray = new String[configEntries.size()]; for (int i = 0 ; i < configEntries.size(); i++) { ConfigEntry configEntry = configEntries.get(i); configArray[i] = configEntry.getKey() + " = " + configEntry.getValue() + " - picked up from: " + configEntry.getFromConfigSource(); } String typeName = "ConfigEntries"; OpenType[] types = new OpenType[]{SimpleType.STRING, SimpleType.STRING, SimpleType.STRING}; String[] keys = new String[]{"Key", "Value", "fromConfigSource"}; CompositeType ct = new CompositeType(typeName, typeName, keys, keys, types); TabularType type = new TabularType(typeName, typeName, ct, keys); TabularDataSupport configEntryInfo = new TabularDataSupport(type); ConfigSource[] configSources = ConfigResolver.getConfigSources(); for (ConfigEntry configEntry : configEntries) { configEntryInfo.put( new CompositeDataSupport(ct, keys, new Object[]{configEntry.getKey(), configEntry.getValue(), configEntry.getFromConfigSource()})); } return configEntryInfo; } catch (OpenDataException e) { throw new RuntimeException(e); } finally { // set back the original TCCL Thread.currentThread().setContextClassLoader(originalCl); } } @Override public TabularData getConfigSources() { ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(appConfigClassLoader); String typeName = "ConfigSources"; OpenType[] types = new OpenType[]{SimpleType.INTEGER, SimpleType.STRING}; String[] keys = new String[]{"Ordinal", "ConfigSource"}; CompositeType ct = new CompositeType(typeName, typeName, keys, keys, types); TabularType type = new TabularType(typeName, typeName, ct, keys); TabularDataSupport configSourceInfo = new TabularDataSupport(type); ConfigSource[] configSources = ConfigResolver.getConfigSources(); for (ConfigSource configSource : configSources) { configSourceInfo.put( new CompositeDataSupport(ct, keys, new Object[]{configSource.getOrdinal(), configSource.getConfigName()})); } return configSourceInfo; } catch (OpenDataException e) { throw new RuntimeException(e); } finally { // set back the original TCCL Thread.currentThread().setContextClassLoader(originalCl); } } private List calculateConfigEntries() { Map allProperties = ConfigResolver.getAllProperties(); List configEntries = new ArrayList(allProperties.size()); ConfigSource[] configSources = ConfigResolver.getConfigSources(); for (Map.Entry configEntry : allProperties.entrySet()) { String key = configEntry.getKey(); String value = ConfigResolver.filterConfigValueForLog(key, ConfigResolver.getProjectStageAwarePropertyValue(key)); String fromConfigSource = getFromConfigSource(configSources, key); configEntries.add(new ConfigEntry(key, value, fromConfigSource)); } return configEntries; } private String getFromConfigSource(ConfigSource[] configSources, String key) { for (ConfigSource configSource : configSources) { if (configSource.getPropertyValue(key) != null) { return configSource.getConfigName(); } } return null; } private class ConfigEntry { private final String key; private final String value; private final String fromConfigSource; ConfigEntry(String key, String value, String fromConfigSource) { this.key = key; this.value = value; this.fromConfigSource = fromConfigSource; } String getKey() { return key; } String getValue() { return value; } String getFromConfigSource() { return fromConfigSource; } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/DeltaSpikeConfigInfoMBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import javax.management.openmbean.TabularData; public interface DeltaSpikeConfigInfoMBean { String[] getConfigSourcesAsString(); TabularData getConfigSources(); String[] getConfigEntriesAsString(); TabularData getConfigEntries(); } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; /** * {@link org.apache.deltaspike.core.spi.config.ConfigSource} * which uses {@link System#getenv()} * * We also allow to write underlines _ instead of dots _ in the * environment via export (unix) or SET (windows) */ class EnvironmentPropertyConfigSource extends MapConfigSource { EnvironmentPropertyConfigSource() { super(System.getenv()); initOrdinal(300); } /** * {@inheritDoc} */ @Override public String getConfigName() { return "environment-properties"; } @Override public String getPropertyValue(String key) { String val = super.getPropertyValue(key); if (val == null || val.isEmpty()) { val = super.getPropertyValue(key.replace('.', '_')); } return val; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/EnvironmentPropertyConfigSourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.ConfigSourceProvider; import org.apache.deltaspike.core.util.PropertyFileUtils; /** * Register all property files with the given propertyFileName * as {@link ConfigSource}. */ class EnvironmentPropertyConfigSourceProvider implements ConfigSourceProvider { private static final Logger LOG = Logger.getLogger(EnvironmentPropertyConfigSourceProvider.class.getName()); private List configSources = new ArrayList(); EnvironmentPropertyConfigSourceProvider(String propertyFileName, boolean optional) { try { Enumeration propertyFileUrls = PropertyFileUtils.resolvePropertyFiles(propertyFileName); if (!optional && !propertyFileUrls.hasMoreElements()) { throw new IllegalStateException(propertyFileName + " wasn't found."); } while (propertyFileUrls.hasMoreElements()) { URL propertyFileUrl = propertyFileUrls.nextElement(); LOG.log(Level.INFO, "Custom config found by DeltaSpike. Name: ''{0}'', URL: ''{1}''", new Object[] {propertyFileName, propertyFileUrl}); configSources.add(new PropertyFileConfigSource(propertyFileUrl)); } } catch (IOException ioe) { throw new IllegalStateException("problem while loading DeltaSpike property files", ioe); } } @Override public List getConfigSources() { return configSources; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/LocalJndiConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.util.HashMap; import java.util.Map; import jakarta.enterprise.inject.Vetoed; import org.apache.deltaspike.core.impl.util.JndiUtils; /** * {@link org.apache.deltaspike.core.spi.config.ConfigSource} * which uses JNDI for the lookup */ @Vetoed class LocalJndiConfigSource extends BaseConfigSource { private static final String BASE_NAME = "java:comp/env/deltaspike/"; LocalJndiConfigSource() { initOrdinal(200); } /** * The given key gets used for a lookup via JNDI * * @param key for the property * @return value for the given key or null if there is no configured value */ @Override public String getPropertyValue(String key) { try { return JndiUtils.lookup(getJndiKey(key), String.class); } catch (Exception e) { //do nothing it was just a try } return null; } private String getJndiKey(String key) { if (key.startsWith("java:comp/env")) { return key; } return BASE_NAME + key; } @Override public Map getProperties() { Map result = new HashMap(); result.putAll(JndiUtils.list(BASE_NAME, String.class)); result.putAll(JndiUtils.list("java:comp/env", String.class)); return result; } /** * {@inheritDoc} */ @Override public String getConfigName() { return BASE_NAME; } @Override public boolean isScannable() { return false; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/MapConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.util.Map; /** * Base class for configurations based on regular {@link Map} */ public abstract class MapConfigSource extends BaseConfigSource { private final Map map; // only needed for some old Weld versions public MapConfigSource() { map = null; } public MapConfigSource(Map map) { this.map = map; } @Override public Map getProperties() { return map; } @Override public String getPropertyValue(String key) { return map.get(key); } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertiesConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * Base class for configuration sources based on a fixed {@link Properties} object. */ public abstract class PropertiesConfigSource extends BaseConfigSource { private final Properties properties; protected PropertiesConfigSource(Properties properties) { this.properties = properties; } /** * The given key gets used for a lookup via a properties object * * @param key for the property * @return value for the given key or null if there is no configured value */ @Override public String getPropertyValue(String key) { return properties.getProperty(key); } @Override public Map getProperties() { Map result = new HashMap(properties.size()); for (String propertyName : properties.stringPropertyNames()) { result.put(propertyName, properties.getProperty(propertyName)); } return result; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/PropertyFileConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.time.Instant; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.logging.Level; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.util.PropertyFileUtils; /** * {@link org.apache.deltaspike.core.spi.config.ConfigSource} which uses * a fixed property file for the lookup. * * If the property file has a 'file://' protocol, we are able to pick up * changes during runtime when the underlying property file changes. * This does not make sense for property files in JARs, but makes perfect sense * whenever a property file URL is directly on the file system. */ public class PropertyFileConfigSource extends BaseConfigSource { /** * The name of a property which can be defined inside the property file * to define the amount of seconds after which the property file should * be tested for changes again. * Note that the test is performed by storing the lastChanged attribute of the * underlying file. * * By default the time after which we look for changes is {@link #RELOAD_PERIOD_DEFAULT}. * This can be changed by explicitly adding a property with the name defined in {@link #RELOAD_PERIOD} * which contains the number of seconds after which we try to reload again. * A zero or negative value means no dynamic reloading. *
     * # look for changes after 60 seconds
     * deltaspike_reload=60
     * 
* Whether the file got changed is determined by the lastModifiedDate of the underlying file. *

* You can disable the whole reloading with a negative reload time, e.g. *

     * deltaspike_reload=-1
     * 
*/ public static final String RELOAD_PERIOD = "deltaspike_reload"; public static final int RELOAD_PERIOD_DEFAULT = 300; private final ConfigResolver.ConfigHelper configHelper; /** * currently loaded config properties. */ private Map properties; private final URL propertyFileUrl; private String filePath; private int reloadAllSeconds = RELOAD_PERIOD_DEFAULT; private Instant fileLastModified = null; /** * Reload after that time in seconds. */ private int reloadAfterSec; private Consumer> reportAttributeChange; public PropertyFileConfigSource(URL propertyFileUrl) { this.propertyFileUrl = propertyFileUrl; filePath = propertyFileUrl.toExternalForm(); this.properties = toMap(PropertyFileUtils.loadProperties(propertyFileUrl)); if (isFile(propertyFileUrl)) { calculateReloadTime(); if (reloadAllSeconds < 0 ) { configHelper = null; } else { fileLastModified = getLastModified(); configHelper = ConfigResolver.getConfigProvider().getHelper(); reloadAfterSec = getNowSeconds() + reloadAllSeconds; } } else { configHelper = null; } initOrdinal(100); } private void calculateReloadTime() { final String reloadPeriod = properties.get(RELOAD_PERIOD); if (reloadPeriod != null) { try { int reload = Integer.parseInt(reloadPeriod); if (reload < 0) { fileLastModified = null; log.info("Disable dynamic reloading for ConfigSource " + filePath); } else { reloadAllSeconds = reload; } } catch (NumberFormatException nfe) { log.warning("Wrong value for " + RELOAD_PERIOD + " property: " + reloadPeriod + ". Must be numeric in seconds. Using default " + RELOAD_PERIOD_DEFAULT); reloadAllSeconds = RELOAD_PERIOD_DEFAULT; } } } protected Map toMap(Properties properties) { Map result = new HashMap<>(properties.size()); for (String propertyName : properties.stringPropertyNames()) { result.put(propertyName, properties.getProperty(propertyName)); } return Collections.unmodifiableMap(result); } @Override public Map getProperties() { if (needsReload()) { reloadProperties(); } return properties; } @Override public String getPropertyValue(String key) { if (needsReload()) { reloadProperties(); } return properties.get(key); } private boolean needsReload() { if (fileLastModified != null && getNowSeconds() > reloadAfterSec) { final Instant newLastModified = getLastModified(); if (newLastModified != null && newLastModified.isAfter(fileLastModified)) { return true; } } return false; } private synchronized void reloadProperties() { // another thread might have already updated the properties. if (needsReload()) { final Map newProps = toMap(PropertyFileUtils.loadProperties(propertyFileUrl)); final Set modfiedAttributes = configHelper.diffConfig(properties, newProps); if (!modfiedAttributes.isEmpty()) { reportAttributeChange.accept(modfiedAttributes); } this.properties = newProps; fileLastModified = getLastModified(); calculateReloadTime(); reloadAfterSec = getNowSeconds() + reloadAllSeconds; } } private int getNowSeconds() { // this might overrun all 100 years or so. // I think we can live with a faster reload all 100 years // if we can spare needing to deal with atomic updates ;) return (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()); } private Instant getLastModified() { try { return Files.getLastModifiedTime(Paths.get(propertyFileUrl.toURI())).toInstant(); } catch (Exception e) { log.log(Level.WARNING, "Cannot dynamically reload property file {0}. Not able to read last modified date", filePath); return null; } } private boolean isFile(URL propertyFileUrl) { return "file".equalsIgnoreCase(propertyFileUrl.getProtocol()); } /** * {@inheritDoc} */ @Override public String getConfigName() { return filePath; } @Override public void setOnAttributeChange(Consumer> reportAttributeChange) { this.reportAttributeChange = reportAttributeChange; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ProxyConfigurationLifecycle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import static java.util.concurrent.TimeUnit.MILLISECONDS; class ProxyConfigurationLifecycle { static final class ConfigurationHandler implements InvocationHandler { private final BaseConfigPropertyProducer delegate = new BaseConfigPropertyProducer() { }; private final ConcurrentMap> resolvers = new ConcurrentHashMap>(); private final long cacheMs; private final String prefix; ConfigurationHandler(final long cacheMs, final String prefix) { this.cacheMs = cacheMs; this.prefix = prefix; } @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (Object.class == method.getDeclaringClass()) { try { return method.invoke(this, args); } catch (final InvocationTargetException ite) { throw ite.getCause(); } } Supplier supplier = resolvers.get(method); if (supplier == null) { final ConfigProperty annotation = method.getAnnotation(ConfigProperty.class); if (annotation == null) { throw new UnsupportedOperationException( method + " doesn't have @ConfigProperty and therefore is illegal"); } // handle primitive bridge there (cdi doesnt support primitives but no reason our proxies don't) final Class converter = annotation.converter(); final Type genericReturnType = method.getGenericReturnType(); Class returnType = method.getReturnType(); final boolean list; final boolean set; if (converter == ConfigResolver.Converter.class && ParameterizedType.class.isInstance(genericReturnType)) { ParameterizedType pt = ParameterizedType.class.cast(genericReturnType); if (List.class == pt.getRawType() && pt.getActualTypeArguments().length == 1) { list = true; set = false; final Type arg = pt.getActualTypeArguments()[0]; if (Class.class.isInstance(arg)) { returnType = Class.class.cast(arg); } } else if (Set.class == pt.getRawType() && pt.getActualTypeArguments().length == 1) { list = false; set = true; final Type arg = pt.getActualTypeArguments()[0]; if (Class.class.isInstance(arg)) { returnType = Class.class.cast(arg); } } else { list = false; set = false; } } else { list = false; set = false; if (int.class == returnType) { returnType = Integer.class; } else if (long.class == returnType) { returnType = Long.class; } else if (boolean.class == returnType) { returnType = Boolean.class; } else if (short.class == returnType) { returnType = Short.class; } else if (byte.class == returnType) { returnType = Byte.class; } else if (float.class == returnType) { returnType = Float.class; } else if (double.class == returnType) { returnType = Double.class; } } final String defaultValue = annotation.defaultValue(); ConfigResolver.TypedResolver typedResolver = delegate.asResolver( prefix + annotation.name(), list || set ? ConfigProperty.NULL : defaultValue, returnType, converter, annotation.parameterizedBy(), annotation.projectStageAware(), annotation.evaluateVariables()); if (cacheMs > 0) { typedResolver.cacheFor(MILLISECONDS, cacheMs); } if (list || set) { ConfigResolver.TypedResolver> listTypedResolver = typedResolver.asList(); final ConfigResolver.TypedResolver> resolver; if (!ConfigProperty.NULL.equals(defaultValue)) { resolver = listTypedResolver.withStringDefault(defaultValue); } else { resolver = listTypedResolver; } if (list) { supplier = new DefaultSupplier(resolver); } else { supplier = new Supplier>() { @Override public Set get() { return new HashSet(resolver.getValue()); } }; } } else { supplier = new DefaultSupplier(typedResolver); } final Supplier existing = resolvers.putIfAbsent(method, supplier); if (existing != null) { supplier = existing; } } return supplier.get(); } } private interface Supplier { T get(); } private static class DefaultSupplier implements Supplier { private final ConfigResolver.TypedResolver delegate; private DefaultSupplier(final ConfigResolver.TypedResolver delegate) { this.delegate = delegate; } @Override public T get() { return delegate.getValue(); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/SystemPropertyConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; /** * {@link org.apache.deltaspike.core.spi.config.ConfigSource} * which uses {@link System#getProperties()} */ class SystemPropertyConfigSource extends PropertiesConfigSource { SystemPropertyConfigSource() { super(System.getProperties()); initOrdinal(400); } /** * {@inheritDoc} */ @Override public String getConfigName() { return "system-properties"; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.ConfigSnapshot; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.BiFunction; import java.util.logging.Level; import java.util.logging.Logger; public class TypedResolverImpl implements ConfigResolver.UntypedResolver { private static final Logger LOG = Logger.getLogger(TypedResolverImpl.class.getName()); private final ConfigImpl config; private String keyOriginal; private String keyResolved; private Type configEntryType = String.class; private boolean withDefault = false; private T defaultValue; private boolean projectStageAware = true; private String propertyParameter; private String parameterValue; private boolean strictly = false; private boolean isList = false; private ConfigResolver.Converter converter; private boolean evaluateVariables = false; private boolean logChanges = false; private ConfigResolver.ConfigChanged valueChangedCallback = null; private long cacheTimeMs = -1; private volatile long reloadAfter = -1; private long lastReloadedAt = -1; private T lastValue = null; private BiFunction beanConverter = null; TypedResolverImpl(ConfigImpl config, String propertyName) { this.config = config; this.keyOriginal = propertyName; } @Override @SuppressWarnings("unchecked") public ConfigResolver.TypedResolver as(Class clazz) { configEntryType = clazz; return (ConfigResolver.TypedResolver) this; } @Override @SuppressWarnings("unchecked") public ConfigResolver.TypedResolver> asList() { isList = true; ConfigResolver.TypedResolver> listTypedResolver = (ConfigResolver.TypedResolver>) this; if (defaultValue == null) { // the default for lists is an empty list instead of null return listTypedResolver.withDefault(Collections.emptyList()); } return listTypedResolver; } @Override @SuppressWarnings("unchecked") public ConfigResolver.TypedResolver as(Class clazz, ConfigResolver.Converter converter) { configEntryType = clazz; this.converter = converter; return (ConfigResolver.TypedResolver) this; } @Override @SuppressWarnings("unchecked") public ConfigResolver.TypedResolver as(Type clazz, ConfigResolver.Converter converter) { configEntryType = clazz; this.converter = converter; return (ConfigResolver.TypedResolver) this; } @Override public ConfigResolver.TypedResolver asBean(Class clazz) { return asBean(clazz, config.getBeanConverter().detectConverter(clazz)); } @Override public ConfigResolver.TypedResolver asBean(Class clazz, BiFunction beanConverter) { configEntryType = clazz; this.beanConverter = beanConverter; return (ConfigResolver.TypedResolver) this; } @Override public ConfigResolver.TypedResolver withDefault(T value) { defaultValue = value; withDefault = true; return this; } @Override public ConfigResolver.TypedResolver withStringDefault(String value) { if (value == null || value.isEmpty()) { throw new RuntimeException("Empty String or null supplied as string-default value for property " + keyOriginal); } if (isList) { defaultValue = splitAndConvertListValue(value); } else { defaultValue = convert(value); } withDefault = true; return this; } @Override public ConfigResolver.TypedResolver cacheFor(TimeUnit timeUnit, long value) { this.cacheTimeMs = timeUnit.toMillis(value); return this; } @Override public ConfigResolver.TypedResolver parameterizedBy(String propertyName) { this.propertyParameter = propertyName; if (propertyParameter != null && !propertyParameter.isEmpty()) { String parameterValue = ConfigResolver .resolve(propertyParameter) .withCurrentProjectStage(projectStageAware) .getValue(); if (parameterValue != null && !parameterValue.isEmpty()) { this.parameterValue = parameterValue; } } return this; } @Override public ConfigResolver.TypedResolver withCurrentProjectStage(boolean with) { this.projectStageAware = with; return this; } @Override public ConfigResolver.TypedResolver strictly(boolean strictly) { this.strictly = strictly; return this; } @Override public ConfigResolver.TypedResolver evaluateVariables(boolean evaluateVariables) { this.evaluateVariables = evaluateVariables; return this; } @Override public ConfigResolver.TypedResolver logChanges(boolean logChanges) { this.logChanges = logChanges; return this; } @Override public ConfigResolver.TypedResolver onChange(ConfigResolver.ConfigChanged valueChangedCallback) { this.valueChangedCallback = valueChangedCallback; return this; } @Override public T getValue(ConfigSnapshot snapshot) { ConfigSnapshotImpl snapshotImpl = (ConfigSnapshotImpl) snapshot; if (!snapshotImpl.getConfigValues().containsKey(this)) { throw new IllegalArgumentException("The TypedResolver for key " + getKey() + " does not belong the given ConfigSnapshot!"); } return (T) snapshotImpl.getConfigValues().get(this); } @Override public T getValue() { long now = -1; if (cacheTimeMs > 0) { now = System.nanoTime(); if (now <= reloadAfter) { // now check if anything in the underlying Config got changed long lastCfgChange = config.getLastChanged(); if (lastCfgChange < lastReloadedAt) { return lastValue; } } } T value; if (beanConverter != null) { value = getValueByBeanConverter(beanConverter); } else { String valueStr = resolveStringValue(); if (isList) { value = splitAndConvertListValue(valueStr); } else { value = convert(valueStr); } if (withDefault) { ConfigResolverContext configResolverContext = new ConfigResolverContext() .setEvaluateVariables(evaluateVariables) .setProjectStageAware(projectStageAware); value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue, configResolverContext); if (isList && String.class.isInstance(value)) { value = splitAndConvertListValue(String.class.cast(value)); } } if ((logChanges || valueChangedCallback != null) && (value != null && !value.equals(lastValue) || (value == null && lastValue != null))) { if (logChanges) { LOG.log(Level.INFO, "New value {0} for key {1}.", new Object[]{ConfigResolver.filterConfigValueForLog(keyOriginal, valueStr), keyOriginal}); } if (valueChangedCallback != null) { valueChangedCallback.onValueChange(keyOriginal, lastValue, value); } } } lastValue = value; if (cacheTimeMs > 0) { reloadAfter = now + TimeUnit.MILLISECONDS.toNanos(cacheTimeMs); lastReloadedAt = now; } return value; } private T getValueByBeanConverter(BiFunction beanConverter) { T value; for (int tries = 1; tries < ConfigImpl.MAX_CONFIG_RETRIES; tries++) { long startReadLastChanged = config.getLastChanged(); value = (T) beanConverter.apply(config, keyOriginal + "."); if (startReadLastChanged == config.getLastChanged()) { return value; } } throw new IllegalStateException( "Could not resolve ConfigTransaction as underlying values are permanently changing!"); } private T splitAndConvertListValue(String valueStr) { if (valueStr == null) { return null; } List list = new ArrayList(); StringBuilder currentValue = new StringBuilder(); int length = valueStr.length(); for (int i = 0; i < length; i++) { char c = valueStr.charAt(i); if (c == '\\') { if (i < length - 1) { char nextC = valueStr.charAt(i + 1); currentValue.append(nextC); i++; } } else if (c == ',') { String trimedVal = currentValue.toString().trim(); if (trimedVal.length() > 0) { list.add(convert(trimedVal)); } currentValue.setLength(0); } else { currentValue.append(c); } } String trimedVal = currentValue.toString().trim(); if (trimedVal.length() > 0) { list.add(convert(trimedVal)); } return (T) list; } @Override public String getKey() { return keyOriginal; } @Override public String getResolvedKey() { return keyResolved; } @Override public T getDefaultValue() { return defaultValue; } /** * Performs the resolution cascade */ private String resolveStringValue() { ProjectStage ps = null; String value = null; keyResolved = keyOriginal; int keySuffices = 0; // make the longest key // first, try appending resolved parameter if (propertyParameter != null && !propertyParameter.isEmpty()) { if (parameterValue != null && !parameterValue.isEmpty()) { keyResolved += "." + parameterValue; keySuffices++; } // if parameter value can't be resolved and strictly else if (strictly) { return null; } } // try appending projectstage if (projectStageAware) { ps = getProjectStage(); keyResolved += "." + ps; keySuffices++; } // make initial resolution of longest key value = getPropertyValue(keyResolved); // try fallbacks if not strictly if (value == null && !strictly) { // by the length of the longest resolved key already tried // breaks are left out intentionally switch (keySuffices) { case 2: // try base.param keyResolved = keyOriginal + "." + parameterValue; value = getPropertyValue(keyResolved); if (value != null) { return value; } // try base.ps ps = getProjectStage(); keyResolved = keyOriginal + "." + ps; value = getPropertyValue(keyResolved); if (value != null) { return value; } case 1: // try base keyResolved = keyOriginal; value = getPropertyValue(keyResolved); return value; default: // the longest key was the base, no fallback return null; } } return value; } /** * If a converter was provided for this builder, it takes precedence over the built-in converters. */ private T convert(String value) { if (value == null) { return null; } Object result = null; if (this.converter != null) { try { result = converter.convert(value); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } else if (String.class.equals(configEntryType)) { result = value; } else if (Class.class.equals(configEntryType)) { result = ClassUtils.tryToLoadClassForName(value); } else if (Boolean.class.equals(configEntryType)) { Boolean isTrue = "TRUE".equalsIgnoreCase(value); isTrue |= "1".equalsIgnoreCase(value); isTrue |= "YES".equalsIgnoreCase(value); isTrue |= "Y".equalsIgnoreCase(value); isTrue |= "JA".equalsIgnoreCase(value); isTrue |= "J".equalsIgnoreCase(value); isTrue |= "OUI".equalsIgnoreCase(value); result = isTrue; } else if (Integer.class.equals(configEntryType)) { result = Integer.parseInt(value); } else if (Long.class.equals(configEntryType)) { result = Long.parseLong(value); } else if (Float.class.equals(configEntryType)) { result = Float.parseFloat(value); } else if (Double.class.equals(configEntryType)) { result = Double.parseDouble(value); } return (T) result; } private T fallbackToDefaultIfEmpty(String key, T value, T defaultValue, ConfigResolverContext configResolverContext) { if (value == null || (value instanceof String && ((String)value).isEmpty())) { if (configResolverContext != null && defaultValue instanceof String && configResolverContext.isEvaluateVariables()) { defaultValue = (T) resolveVariables((String) defaultValue); } if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "no configured value found for key {0}, using default value {1}.", new Object[]{key, defaultValue}); } return defaultValue; } return value; } /** * recursively resolve any ${varName} in the value */ private String resolveVariables(String value) { int startVar = 0; while ((startVar = value.indexOf("${", startVar)) >= 0) { int endVar = value.indexOf("}", startVar); if (endVar <= 0) { break; } String varName = value.substring(startVar + 2, endVar); if (varName.isEmpty()) { break; } try { String variableValue = new TypedResolverImpl(this.config, varName) .withCurrentProjectStage(this.projectStageAware) .evaluateVariables(true) .getValue(); if (variableValue != null) { value = value.replace("${" + varName + "}", variableValue); } } catch (StackOverflowError soe) { // just log out LOG.severe("Recursive variable resolution detected for " + varName); throw soe; } startVar++; } return value; } private ProjectStage getProjectStage() { return ProjectStageProducer.getInstance().getProjectStage(); } private String getPropertyValue(String key) { String value; for (ConfigSource configSource : config.getConfigSources()) { value = configSource.getPropertyValue(key); if (value != null) { if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.", new Object[]{config.filterConfigValue(key, value, true), key, configSource.getConfigName()}); } if (this.evaluateVariables) { value = resolveVariables(value); } return config.filterConfigValue(key, value, false); } if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.", new Object[]{key, configSource.getConfigName()}); } } return null; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/BeanConverterFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config.converter; import java.lang.reflect.Constructor; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.function.BiFunction; import java.util.stream.Collectors; import org.apache.deltaspike.core.api.config.Config; /** * A factory for bean converters. */ public final class BeanConverterFactory { private final ConcurrentMap, BiFunction> beanConverters = new ConcurrentHashMap<>(); /** * Determine the bean converter function to be used according to the rules defined in * {@link org.apache.deltaspike.core.api.config.ConfigResolver.UntypedResolver#asBean(Class)} */ public BiFunction detectConverter(Class clazz) { BiFunction beanConverter = (BiFunction) beanConverters.get(clazz); if (beanConverter == null) { // class with public param ct final List> paramConstructors = Arrays.stream(clazz.getConstructors()) .filter(ct -> ct.getParameterTypes().length > 0) .collect(Collectors.toList()); if (paramConstructors.size() > 1) { throw new IllegalStateException("Cannot handle beans with multiple non-default ct"); } if (paramConstructors.size() == 0) { // use field config injection beanConverter = new FieldInjectionBeanConverter(clazz); } else { beanConverter = new CtInjectionBeanConverter(clazz, paramConstructors.get(0)); } beanConverters.putIfAbsent(clazz, beanConverter); } return beanConverter; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/CtInjectionBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config.converter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.List; import java.util.function.BiFunction; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.util.ExceptionUtils; /** * @author Mark Struberg */ public class CtInjectionBeanConverter implements BiFunction { private final Constructor constructor; public CtInjectionBeanConverter(Class clazz, Constructor constructor) { this.constructor = constructor; } @Override public N apply(Config config, String path) { List params = new ArrayList<>(); for (int i = 0; i < constructor.getParameters().length; i++) { Parameter p = constructor.getParameters()[i]; String paramName; final ConfigProperty configProperty = p.getAnnotation(ConfigProperty.class); if (configProperty != null) { paramName = configProperty.name(); } else { paramName = p.getName(); if (paramName.equals("arg" + i)) { throw new IllegalStateException("Config POJO constructor pareameters must be annotated with @ConfigProperty if the " + "class is not compiled with the javac -parameters option!"); } } params.add(config.resolve(path + paramName) .as(p.getType()) .getValue()); } if (params.stream().allMatch(p -> p == null)) { return null; } try { return (N) constructor.newInstance(params.toArray(new Object[params.size()])); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/converter/FieldInjectionBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.config.converter; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.BiFunction; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.util.ExceptionUtils; /** * @author Mark Struberg */ public class FieldInjectionBeanConverter implements BiFunction { private final Class clazz; private final List fields; public FieldInjectionBeanConverter(Class clazz) { this.clazz = clazz; this.fields = collectFields(clazz); } private List collectFields(Class clazz) { List fields = new ArrayList<>(); fields.addAll(Arrays.asList(clazz.getDeclaredFields())); if (clazz.getSuperclass() != Object.class) { fields.addAll(collectFields(clazz.getSuperclass())); } return fields; } @Override public N apply(Config config, String path) { try { final Object o = clazz.getDeclaredConstructor().newInstance(); for (Field field : fields) { final ConfigProperty configProperty = field.getAnnotation(ConfigProperty.class); String name = configProperty != null ? configProperty.name() : field.getName(); final ConfigResolver.UntypedResolver resolver = config.resolve(path + name); if (field.getType() != String.class) { resolver.as(field.getType()); } resolver.evaluateVariables(configProperty != null ? configProperty.evaluateVariables() : true); resolver.withCurrentProjectStage(configProperty != null ? configProperty.projectStageAware() : true); if (!field.isAccessible()) { field.setAccessible(true); } field.set(o, resolver.getValue()); } return (N) o; } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/crypto/CdiCipherService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.crypto; import jakarta.enterprise.context.ApplicationScoped; import java.io.IOException; import org.apache.deltaspike.core.api.crypto.CipherService; @ApplicationScoped public class CdiCipherService implements CipherService { private DefaultCipherService cipherService = new DefaultCipherService(); @Override public void setMasterHash(String masterPassword, String masterSalt, boolean overwrite) throws IOException { cipherService.setMasterHash(masterPassword, masterSalt, overwrite); } @Override public String encrypt(String cleartext, String masterSalt) { return cipherService.encrypt(cleartext, masterSalt); } @Override public String decrypt(String encryptedValue, String masterSalt) { return cipherService.decrypt(encryptedValue, masterSalt); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/crypto/CipherCli.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.crypto; /** * Command Line Interface for CipherService */ public class CipherCli { private CipherCli() { // private ct. } public static void main(String[] args) throws Exception { // not using any other libs like commons-cli to save dependencies if (args.length < 5) { printHelp(); System.exit(-1); } if (!"encode".equals(args[0])) { printHelp(); System.exit(-1); } String masterPwd = null; String plaintext = null; String masterSalt = null; boolean overwrite = false; for (int i = 1; i < args.length; i++) { String arg = args[i]; if ("-masterPassword".equals(arg) && i < args.length - 1) { masterPwd = args[++i]; } else if ("-masterSalt".equals(arg) && i < args.length - 1) { masterSalt = args[++i]; } else if ("-plaintext".equals(arg) && i < args.length - 1) { plaintext = args[++i]; } else if ("-overwrite".equals(arg)) { overwrite = true; } } DefaultCipherService defaultCipherService = new DefaultCipherService(); if (masterPwd != null && masterSalt != null) { String masterSaltHash = defaultCipherService.setMasterHash(masterPwd, masterSalt, overwrite); System.out.println("A new master password got set. Hash key is " + masterSaltHash); } else if (plaintext != null && masterSalt != null) { String encrypted = defaultCipherService.encrypt(plaintext, masterSalt); System.out.println("Encrypted value: " + encrypted); } else { printHelp(); System.exit(-1); } } private static void printHelp() { StringBuilder usage = new StringBuilder(1024); usage.append("To create a master password use:"); usage.append("\n$> java -jar deltaspike-core-impl.jar encode -masterPassword " + "yourMasterPassword -masterSalt someSecretOnlyKnownToYouAndTheApplication"); usage.append("\n you can also specify -overwrite to replace an existing masterpassword."); usage.append("\n\nFor encrypting a secret with a previously stored masterPassword use:"); usage.append("\n$> java -jar deltaspike-core-impl.jar encode -plaintext plaintextToEncrypt " + "-masterSalt someSecretOnlyKnownToYouAndTheApplication"); usage.append("\n\nVisit https://deltaspike.apache.org for more information.\n"); System.out.print(usage.toString()); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/crypto/DefaultCipherService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.crypto; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Properties; /** * handle Encryption */ public class DefaultCipherService { private static final Charset UTF_8 = Charset.forName("UTF-8"); private static final String HASH_ALGORITHM = "SHA-256"; private static final String CIPHER_ALGORITHM = "AES"; public String setMasterHash(String masterPassword, String masterSalt, boolean overwrite) throws IOException { File masterFile = getMasterFile(); if (!masterFile.getParentFile().exists()) { if (!masterFile.getParentFile().mkdirs()) { throw new IOException("Can not create directory " + masterFile.getParent()); } } String saltHash = byteToHex(secureHash(masterSalt)); String saltKey = byteToHex(secureHash(saltHash)); String encrypted = byteToHex(aesEncrypt(byteToHex(secureHash(masterPassword)), saltHash)); Properties keys = new Properties(); if (masterFile.exists()) { keys = loadProperties(masterFile.toURI().toURL()); } if (keys.get(saltKey) != null && !overwrite) { throw new IllegalStateException("MasterKey for hash " + saltKey + " already exists. Forced overwrite option needed"); } keys.put(saltKey, encrypted); keys.store(new FileOutputStream(masterFile), null); return saltKey; } protected String getMasterKey(String masterSalt) { File masterFile = getMasterFile(); if (!masterFile.exists()) { throw new IllegalStateException("Could not find master.hash file. Create a master password first!"); } try { String saltHash = byteToHex(secureHash(masterSalt)); String saltKey = byteToHex(secureHash(saltHash)); Properties keys = loadProperties(masterFile.toURI().toURL()); String encryptedMasterKey = (String) keys.get(saltKey); if (encryptedMasterKey == null) { throw new IllegalStateException("Could not find master key for hash " + saltKey + ". Create a master password first!"); } return aesDecrypt(hexToByte(encryptedMasterKey), saltHash); } catch (MalformedURLException e) { throw new RuntimeException(e); } } public String encrypt(String cleartext, String masterSalt) { return byteToHex(aesEncrypt(cleartext, getMasterKey(masterSalt))); } public String decrypt(String encryptedValue, String masterSalt) { return aesDecrypt(hexToByte(encryptedValue), getMasterKey(masterSalt)); } protected File getMasterFile() { String userHome = System.getProperty("user.home"); if (userHome == null || userHome.isEmpty()) { throw new IllegalStateException("Can not determine user home directory"); } return new File(userHome, ".deltaspike/master.hash"); } protected byte[] secureHash(String value) { try { MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM); return md.digest(value.getBytes(UTF_8)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } /** * performs an AES encryption of the given text with the given password key */ public byte[] aesEncrypt(String valueToEncrypt, String key) { try { SecretKeySpec secretKeySpec = getSecretKeySpec(key); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); return cipher.doFinal(valueToEncrypt.getBytes(UTF_8)); } catch (Exception e) { throw new RuntimeException(e); } } /** * performs an AES decryption of the given text with the given key key */ public String aesDecrypt(byte[] encryptedValue, String key) { try { SecretKeySpec secretKeySpec = getSecretKeySpec(key); Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); return new String(cipher.doFinal(encryptedValue), UTF_8); } catch (Exception e) { throw new RuntimeException(e); } } private SecretKeySpec getSecretKeySpec(String password) { byte[] pwdHash = secureHash(password); byte[] key = Arrays.copyOf(pwdHash, 16); // use only first 128 bit // Note: using 128 bit AES avoids requirement for "Unlimited Crypto" patch return new SecretKeySpec(key, "AES"); } protected String byteToHex(final byte[] hash) { StringBuilder sb = new StringBuilder(hash.length * 2); for (byte b : hash) { sb.append(Character.forDigit(b >> 4 & 0x0f, 16)); sb.append(Character.forDigit(b & 0x0f, 16)); } return sb.toString(); } protected byte[] hexToByte(String hexString) { if (hexString == null || hexString.length() == 0) { return new byte[0]; } hexString = hexString.trim(); if (hexString.length() % 2 != 0) { throw new IllegalArgumentException("not a valid hex string " + hexString); } byte[] bytes = new byte[hexString.length() / 2]; for (int i = 0; i < hexString.length() / 2; i++) { int val = (Character.digit(hexString.charAt(i * 2), 16) << 4) + (Character.digit(hexString.charAt( (i * 2) + 1), 16)); bytes[i] = (byte) val; } return bytes; } /** * Copied over from PropertyFileUtils to avoid the need for having the api * on the classpath when using the password encode CLI */ private Properties loadProperties(URL url) { Properties props = new Properties(); InputStream inputStream = null; try { inputStream = url.openStream(); if (inputStream != null) { props.load(inputStream); } } catch (IOException e) { throw new IllegalStateException(e); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { // no worries, means that the file is already closed } } return props; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/CustomProjectStageBeanFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exclude; import org.apache.deltaspike.core.spi.activation.Deactivatable; /** * Allows to deactivate the autom. filtering of custom project-stages -> @Typed() needs to be used manually */ public interface CustomProjectStageBeanFilter extends Deactivatable { } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/exclude/extension/ExcludeExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.exclude.extension; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.exclude.Exclude; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.api.interpreter.ExpressionInterpreter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.impl.exclude.CustomProjectStageBeanFilter; import org.apache.deltaspike.core.impl.interpreter.PropertyExpressionInterpreter; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import java.lang.reflect.Modifier; import java.net.URL; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; /** *

This class implements the logic for handling * {@link org.apache.deltaspike.core.api.exclude.Exclude} annotations.

*

*

Further details see {@link org.apache.deltaspike.core.api.exclude.Exclude}

*/ public class ExcludeExtension implements Extension, Deactivatable { private static final Logger LOG = Logger.getLogger(ExcludeExtension.class.getName()); private boolean isActivated = true; private boolean isCustomProjectStageBeanFilterActivated = true; //overruling the filter is supported via config-ordinal - for now only one is supported to keep it simple //a custom filter can always delegate to multiple filters //(e.g. in combination with ServiceUtils or querying all config-sources explicitly) private ClassFilter classFilter; @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) { isActivated = ClassDeactivationUtils.isActivated(getClass()); isCustomProjectStageBeanFilterActivated = ClassDeactivationUtils.isActivated(CustomProjectStageBeanFilter.class); boolean isClassFilterActivated = ClassDeactivationUtils.isActivated(ClassFilter.class); if (isClassFilterActivated) { String classFilterClassName = ClassFilter.class.getName(); String activeClassFilterName = ConfigResolver.getProjectStageAwarePropertyValue(classFilterClassName, classFilterClassName); if (!classFilterClassName.equals(activeClassFilterName)) { classFilter = ClassUtils.tryToInstantiateClassForName(activeClassFilterName, ClassFilter.class); } } } /** * triggers initialization in any case * @param afterDeploymentValidation observed event */ @SuppressWarnings("UnusedDeclaration") protected void initProjectStage(@Observes AfterDeploymentValidation afterDeploymentValidation) { ProjectStageProducer.getInstance(); } /** * Observer which is vetoing beans based on {@link Exclude} * @param processAnnotatedType observed event */ @SuppressWarnings("UnusedDeclaration") protected void vetoBeans(@Observes ProcessAnnotatedType processAnnotatedType, BeanManager beanManager) { //we need to do it before the exclude logic to keep the @Exclude support for global alternatives if (isCustomProjectStageBeanFilterActivated) { vetoCustomProjectStageBeans(processAnnotatedType); } if (!isActivated) { return; } if (classFilter != null) { Class beanClass = processAnnotatedType.getAnnotatedType().getJavaClass(); if (classFilter.isFiltered(beanClass)) { veto(processAnnotatedType, classFilter.getClass().getName()); return; } } //TODO needs further discussions for a different feature CodiStartupBroadcaster.broadcastStartup(); //also forces deterministic project-stage initialization ProjectStage projectStage = ProjectStageProducer.getInstance().getProjectStage(); Exclude exclude = extractExcludeAnnotation(processAnnotatedType.getAnnotatedType().getJavaClass()); if (exclude == null) { return; } if (!evalExcludeWithoutCondition(processAnnotatedType, exclude)) { return; //veto called already } if (!evalExcludeInProjectStage(processAnnotatedType, exclude, projectStage)) { return; //veto called already } if (!evalExcludeNotInProjectStage(processAnnotatedType, exclude, projectStage)) { return; //veto called already } evalExcludeWithExpression(processAnnotatedType, exclude); } //only support the physical usage and inheritance if @Exclude comes from an abstract class //TODO re-visit the impact of java.lang.annotation.Inherited (for @Exclude) for the available use-cases protected Exclude extractExcludeAnnotation(Class currentClass) { Exclude result = currentClass.getAnnotation(Exclude.class); if (result != null) { return result; } currentClass = currentClass.getSuperclass(); while (!Object.class.equals(currentClass) && currentClass != null) { if (Modifier.isAbstract(currentClass.getModifiers())) { result = currentClass.getAnnotation(Exclude.class); } if (result != null) { return result; } currentClass = currentClass.getSuperclass(); } return null; } protected void vetoCustomProjectStageBeans(ProcessAnnotatedType processAnnotatedType) { //currently there is a veto for all project-stage implementations, //but we still need for the provided implementations in case of the deactivation of this behaviour if (ProjectStage.class.isAssignableFrom(processAnnotatedType.getAnnotatedType().getJavaClass())) { processAnnotatedType.veto(); } } private boolean evalExcludeWithoutCondition(ProcessAnnotatedType processAnnotatedType, Exclude exclude) { if (exclude.ifProjectStage().length == 0 && exclude.exceptIfProjectStage().length == 0 && "".equals(exclude.onExpression())) { veto(processAnnotatedType, "Stateless"); return false; } return true; } private boolean evalExcludeInProjectStage(ProcessAnnotatedType processAnnotatedType, Exclude exclude, ProjectStage currentlyConfiguredProjectStage) { Class[] activatedIn = exclude.ifProjectStage(); if (activatedIn.length == 0) { return true; } if (isInProjectStage(activatedIn, currentlyConfiguredProjectStage)) { veto(processAnnotatedType, "IfProjectState"); return false; } return true; } private boolean evalExcludeNotInProjectStage(ProcessAnnotatedType processAnnotatedType, Exclude exclude, ProjectStage currentlyConfiguredProjectStage) { Class[] notIn = exclude.exceptIfProjectStage(); if (notIn.length == 0) { return true; } if (!isInProjectStage(notIn, currentlyConfiguredProjectStage)) { veto(processAnnotatedType, "ExceptIfProjectState"); return false; } return true; } private void evalExcludeWithExpression(ProcessAnnotatedType processAnnotatedType, Exclude exclude) { if ("".equals(exclude.onExpression())) { return; } if (isDeactivated(exclude, PropertyExpressionInterpreter.class)) { veto(processAnnotatedType, "Expression"); } } private boolean isInProjectStage(Class[] activatedIn, ProjectStage currentlyConfiguredProjectStage) { if (activatedIn != null && activatedIn.length > 0) { for (Class activated : activatedIn) { if (currentlyConfiguredProjectStage.getClass().equals(activated)) { return true; } } } return false; } private boolean isDeactivated(Exclude exclude, Class defaultExpressionInterpreterClass) { String expressions = exclude.onExpression(); Class interpreterClass = exclude.interpretedBy(); if (interpreterClass.equals(ExpressionInterpreter.class)) { interpreterClass = defaultExpressionInterpreterClass; } ExpressionInterpreter expressionInterpreter = ClassUtils.tryToInstantiateClass(interpreterClass); if (expressionInterpreter == null) { if (LOG.isLoggable(Level.WARNING)) { LOG.warning("can't instantiate " + interpreterClass.getClass().getName()); } return true; } return expressionInterpreter.evaluate(expressions); } private void veto(ProcessAnnotatedType processAnnotatedType, String vetoType) { processAnnotatedType.veto(); LOG.finer(vetoType + " based veto for bean with type: " + processAnnotatedType.getAnnotatedType().getJavaClass()); } private static String getJarVersion(Class targetClass) { String manifestFileLocation = getManifestFileLocationOfClass(targetClass); try { return new Manifest(new URL(manifestFileLocation).openStream()) //weld doesn't use IMPLEMENTATION_VERSION .getMainAttributes().getValue(Attributes.Name.SPECIFICATION_VERSION); } catch (Exception e) { return null; } } private static String getManifestFileLocationOfClass(Class targetClass) { String manifestFileLocation; try { manifestFileLocation = getManifestLocation(targetClass); } catch (Exception e) { //in this case we have a proxy manifestFileLocation = getManifestLocation(targetClass.getSuperclass()); } return manifestFileLocation; } private static String getManifestLocation(Class targetClass) { String classFilePath = targetClass.getCanonicalName().replace('.', '/') + ".class"; String manifestFilePath = "/META-INF/MANIFEST.MF"; String classLocation = targetClass.getResource(targetClass.getSimpleName() + ".class").toString(); return classLocation.substring(0, classLocation.indexOf(classFilePath) - 1) + manifestFilePath; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/DefaultFutureableStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.future; import org.apache.deltaspike.core.api.future.Futureable; import org.apache.deltaspike.core.impl.util.AnnotatedMethods; import org.apache.deltaspike.core.spi.future.FutureableStrategy; import org.apache.deltaspike.core.util.ExceptionUtils; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.LinkedList; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @Dependent public class DefaultFutureableStrategy implements FutureableStrategy { private static final Class COMPLETION_STAGE; private static final Class COMPLETABLE_FUTURE; private static final Method COMPLETABLE_STAGE_TO_FUTURE; // only for weld1 private static final boolean IS_WELD1; private static final ThreadLocal> STACK = new ThreadLocal>() { @Override protected LinkedList initialValue() { return new LinkedList(); } }; static { Class completionStageClass = null; Class completableFutureClass = null; Method completionStageClassToCompletableFuture = null; try { final ClassLoader classLoader = ClassLoader.getSystemClassLoader(); completionStageClass = classLoader.loadClass("java.util.concurrent.CompletionStage"); completionStageClassToCompletableFuture = completionStageClass.getMethod("toCompletableFuture"); completableFutureClass = classLoader.loadClass("java.util.concurrent.CompletableFuture"); } catch (final Exception e) { // not on java 8 } COMPLETION_STAGE = completionStageClass; COMPLETABLE_FUTURE = completableFutureClass; COMPLETABLE_STAGE_TO_FUTURE = completionStageClassToCompletableFuture; { // workaround for weld -> use a thread local to track the invocations boolean weld1 = false; try { final Class impl = Thread.currentThread().getContextClassLoader() .loadClass("org.jboss.weld.manager.BeanManagerImpl"); final Package pck = impl.getPackage(); weld1 = "Weld Implementation".equals(pck.getImplementationTitle()) && pck.getSpecificationVersion() != null && pck.getSpecificationVersion().startsWith("1.1."); } catch (final Throwable cnfe) { // no-op } IS_WELD1 = weld1; } } @Inject private ThreadPoolManager manager; @Inject private BeanManager beanManager; private transient ConcurrentMap configByMethod = new ConcurrentHashMap(); @Override public Object execute(final InvocationContext ic) throws Exception { final CallKey invocationKey; if (IS_WELD1) { invocationKey = new CallKey(ic); { // weld1 workaround final LinkedList stack = STACK.get(); if (!stack.isEmpty() && stack.getLast().equals(invocationKey)) { try { return ic.proceed(); } finally { if (stack.isEmpty()) { STACK.remove(); } } } } } else { invocationKey = null; } // validate usage final Class returnType = ic.getMethod().getReturnType(); if (!Future.class.isAssignableFrom(returnType) && !void.class.isAssignableFrom(returnType) && (COMPLETION_STAGE == null || !COMPLETION_STAGE.isAssignableFrom(returnType))) { throw new IllegalArgumentException("Return type should be a CompletableStage, Future or void"); } if (configByMethod == null) { synchronized (this) { if (configByMethod == null) { configByMethod = new ConcurrentHashMap(); } } } // running < j8 we cant have cancellation //final AtomicReference> cancelHook = new AtomicReference>(); final Callable invocation = new Callable() { @Override public Object call() throws Exception { final LinkedList callStack; if (IS_WELD1) { callStack = STACK.get(); callStack.add(invocationKey); } else { callStack = null; } try { final Object proceed = ic.proceed(); final Future future = COMPLETION_STAGE == null || !COMPLETION_STAGE.isInstance(proceed) ? Future.class.cast(proceed) : Future.class.cast(COMPLETABLE_STAGE_TO_FUTURE.invoke(proceed)); return future.get(); } catch (final InvocationTargetException e) { throw ExceptionUtils.throwAsRuntimeException(e.getCause()); } catch (final Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } finally { if (IS_WELD1) { callStack.removeLast(); if (callStack.isEmpty()) { STACK.remove(); } } } } }; final ExecutorService pool = getOrCreatePool(ic); if (void.class.isAssignableFrom(returnType)) { pool.submit(invocation); return null; } if (COMPLETABLE_FUTURE == null) // not on java 8 can only be a future { return pool.submit(invocation); } // java 8, use CompletableFuture, it impl CompletionStage and Future so everyone is happy final Object completableFuture = COMPLETABLE_FUTURE.newInstance(); pool.submit(new J8PromiseCompanionTask(completableFuture, invocation)); // TODO: handle cancel return completableFuture; } protected ExecutorService getOrCreatePool(final InvocationContext ic) { final Method method = ic.getMethod(); ExecutorService executorService = configByMethod.get(method); if (executorService == null) { final AnnotatedType annotatedType = beanManager.createAnnotatedType(method.getDeclaringClass()); final AnnotatedMethod annotatedMethod = AnnotatedMethods.findMethod(annotatedType, method); final Futureable methodConfig = annotatedMethod.getAnnotation(Futureable.class); final ExecutorService instance = manager.find( (methodConfig == null ? annotatedType.getAnnotation(Futureable.class) : methodConfig).value()); configByMethod.putIfAbsent(method, instance); executorService = instance; } return executorService; } private static final class CallKey { private final InvocationContext ic; private final int hash; private CallKey(final InvocationContext ic) { this.ic = ic; final Object[] parameters = ic.getParameters(); this.hash = ic.getMethod().hashCode() + (parameters == null ? 0 : Arrays.hashCode(parameters)); } @Override public boolean equals(final Object o) { return this == o || !(o == null || getClass() != o.getClass()) && equals(ic, CallKey.class.cast(o).ic); } @Override public int hashCode() { return hash; } private boolean equals(final InvocationContext ic1, final InvocationContext ic2) { final Object[] parameters1 = ic1.getParameters(); final Object[] parameters2 = ic2.getParameters(); return ic2.getMethod().equals(ic1.getMethod()) && (parameters1 == parameters2 || (parameters1 != null && parameters2 != null && Arrays.equals(parameters1, ic2.getParameters()))); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/FutureableInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.future; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.future.Futureable; import org.apache.deltaspike.core.spi.future.FutureableStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @Interceptor @Futureable @Priority(1000) public class FutureableInterceptor implements Serializable { @Inject private FutureableStrategy futureableStrategy; @AroundInvoke public Object invoke(final InvocationContext ic) throws Exception { return futureableStrategy.execute(ic); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/J8PromiseCompanionTask.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.future; import org.apache.deltaspike.core.util.ExceptionUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.Callable; class J8PromiseCompanionTask implements Runnable { private static final Method COMPLETABLE_FUTURE_COMPLETE; private static final Method COMPLETABLE_FUTURE_COMPLETE_ERROR; static { Class completableFutureClass = null; Method completableFutureComplete = null; Method completableFutureCompleteError = null; try { final ClassLoader classLoader = ClassLoader.getSystemClassLoader(); completableFutureClass = classLoader.loadClass("java.util.concurrent.CompletableFuture"); completableFutureComplete = completableFutureClass.getMethod("complete", Object.class); completableFutureCompleteError = completableFutureClass.getMethod("completeExceptionally", Throwable.class); } catch (final Exception e) { // not on java 8 } COMPLETABLE_FUTURE_COMPLETE = completableFutureComplete; COMPLETABLE_FUTURE_COMPLETE_ERROR = completableFutureCompleteError; } private Object dep; private Callable fn; J8PromiseCompanionTask(final Object dep, Callable fn) { this.dep = dep; this.fn = fn; } public void run() { try { COMPLETABLE_FUTURE_COMPLETE.invoke(dep, fn.call()); } catch (final InvocationTargetException e) { try { COMPLETABLE_FUTURE_COMPLETE_ERROR.invoke(dep, e.getCause()); } catch (IllegalAccessException e1) { throw ExceptionUtils.throwAsRuntimeException(e1); } catch (final InvocationTargetException e1) { throw ExceptionUtils.throwAsRuntimeException(e1.getCause()); } } catch (Exception e) { try { COMPLETABLE_FUTURE_COMPLETE_ERROR.invoke(dep, e); } catch (IllegalAccessException e1) { throw ExceptionUtils.throwAsRuntimeException(e1); } catch (final InvocationTargetException e1) { throw ExceptionUtils.throwAsRuntimeException(e1.getCause()); } } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/future/ThreadPoolManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.future; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import javax.naming.InitialContext; import javax.naming.NamingException; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import static java.util.Arrays.asList; @ApplicationScoped public class ThreadPoolManager { private final ConcurrentMap pools = new ConcurrentHashMap(); private final Collection> contexts = new ArrayList>(8); private volatile boolean closed = false; @Inject private BeanManager beanManager; @PreDestroy private void shutdown() { closed = true; final long timeout = CoreBaseConfig.TimeoutCustomization.FUTUREABLE_TERMINATION_TIMEOUT_IN_MILLISECONDS; for (final ExecutorService es : pools.values()) { es.shutdown(); } for (final ExecutorService es : pools.values()) { try { es.awaitTermination(timeout, TimeUnit.MILLISECONDS); } catch (final InterruptedException e) { Thread.interrupted(); } } pools.clear(); for (final CreationalContext ctx : contexts) { ctx.release(); } contexts.clear(); } public ExecutorService find(final String name) { if (closed) { throw new IllegalStateException("Container is shutting down"); } ExecutorService pool = pools.get(name); if (pool == null) { synchronized (this) { pool = pools.get(name); if (pool == null) { // the instantiation does the following: // 1. check if there is a named bean matching this name using @Default qualifier // 2. check if there is a JNDI entry (ManagedExecutorService case) matching this name // 3. create a new executor service based on the DS-config // 1. final Set> beans = beanManager.getBeans(name); if (beans != null && !beans.isEmpty()) { final Bean bean = beanManager.resolve(beans); if (bean.getTypes().contains(ExecutorService.class)) { final CreationalContext creationalContext = beanManager.createCreationalContext(null); if (!beanManager.isNormalScope(bean.getScope())) { contexts.add(creationalContext); } pool = ExecutorService.class.cast(beanManager.getReference( bean, ExecutorService.class, creationalContext)); } } if (pool == null) // 2. { for (final String prefix : asList( "", "java:app/", "java:global/", "java:global/threads/", "java:global/deltaspike/", "java:")) { try { final Object instance = new InitialContext().lookup(prefix + name); if (ExecutorService.class.isInstance(instance)) { pool = ExecutorService.class.cast(instance); break; } } catch (final NamingException e) { // no-op } } } if (pool == null) // 3. { final String configPrefix = "futureable.pool." + name + "."; final int coreSize = ConfigResolver.resolve(configPrefix + "coreSize") .as(Integer.class) .withDefault(Math.max(2, Runtime.getRuntime().availableProcessors())) .getValue(); final int maxSize = ConfigResolver.resolve(configPrefix + "maxSize") .as(Integer.class) .withDefault(coreSize) .getValue(); final long keepAlive = ConfigResolver.resolve(configPrefix + "keepAlive.value") .as(Long.class) .withDefault(0L) .getValue(); final String keepAliveUnit = ConfigResolver.resolve(configPrefix + "keepAlive.unit") .as(String.class) .withDefault("MILLISECONDS") .getValue(); final String queueType = ConfigResolver.resolve(configPrefix + "queue.type") .as(String.class) .withDefault("LINKED") .getValue(); final BlockingQueue queue; if ("ARRAY".equalsIgnoreCase(queueType)) { final int size = ConfigResolver.resolve(configPrefix + "queue.size") .as(Integer.class) .withDefault(1024) .getValue(); final boolean fair = ConfigResolver.resolve(configPrefix + "queue.fair") .as(Boolean.class) .withDefault(false) .getValue(); queue = new ArrayBlockingQueue(size, fair); } else if ("SYNCHRONOUS".equalsIgnoreCase(queueType)) { final boolean fair = ConfigResolver.resolve(configPrefix + "queue.fair") .as(Boolean.class) .withDefault(false) .getValue(); queue = new SynchronousQueue(fair); } else { final int capacity = ConfigResolver.resolve(configPrefix + "queue.capacity") .as(Integer.class) .withDefault(Integer.MAX_VALUE) .getValue(); queue = new LinkedBlockingQueue(capacity); } final String threadFactoryName = ConfigResolver.getPropertyValue( configPrefix + "threadFactory.name"); final ThreadFactory threadFactory; if (threadFactoryName != null) { threadFactory = lookupByName(threadFactoryName, ThreadFactory.class); } else { threadFactory = Executors.defaultThreadFactory(); } final String rejectedHandlerName = ConfigResolver.getPropertyValue( configPrefix + "rejectedExecutionHandler.name"); final RejectedExecutionHandler rejectedHandler; if (rejectedHandlerName != null) { rejectedHandler = lookupByName(rejectedHandlerName, RejectedExecutionHandler.class); } else { rejectedHandler = new ThreadPoolExecutor.AbortPolicy(); } pool = new ThreadPoolExecutor( coreSize, maxSize, keepAlive, TimeUnit.valueOf(keepAliveUnit), queue, threadFactory, rejectedHandler); } pools.put(name, pool); } } } return pool; } private T lookupByName(final String name, final Class type) { final Set> tfb = beanManager.getBeans(name); final Bean bean = beanManager.resolve(tfb); final CreationalContext ctx = beanManager.createCreationalContext(null); if (!beanManager.isNormalScope(bean.getScope())) { contexts.add(ctx); } return type.cast(beanManager.getReference(bean, type, ctx)); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/interceptor/GlobalInterceptorWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.interceptor; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; class GlobalInterceptorWrapper implements AnnotatedType { private final AnnotatedType wrapped; private Map, Annotation> annotations; private Set annotationSet; GlobalInterceptorWrapper(AnnotatedType wrapped, Annotation priorityAnnotation) { this.wrapped = wrapped; Set originalAnnotationSet = wrapped.getAnnotations(); this.annotations = new HashMap, Annotation>(originalAnnotationSet.size()); for (Annotation originalAnnotation : originalAnnotationSet) { this.annotations.put(originalAnnotation.annotationType(), originalAnnotation); } this.annotations.put(priorityAnnotation.annotationType(), priorityAnnotation); this.annotationSet = new HashSet(this.annotations.size()); this.annotationSet.addAll(this.annotations.values()); } @Override public Class getJavaClass() { return wrapped.getJavaClass(); } @Override public Set getConstructors() { return wrapped.getConstructors(); } @Override public Set getMethods() { return wrapped.getMethods(); } @Override public Set getFields() { return wrapped.getFields(); } @Override public Type getBaseType() { return wrapped.getBaseType(); } @Override public Set getTypeClosure() { return wrapped.getTypeClosure(); } @Override public T getAnnotation(Class targetClass) { return (T) this.annotations.get(targetClass); } @Override public Set getAnnotations() { return this.annotationSet; } @Override public boolean isAnnotationPresent(Class targetClass) { return this.annotations.containsKey(targetClass); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/interceptor/interdyn/AnnotationRule.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.interceptor.interdyn; import java.lang.annotation.Annotation; /** * Contains a mapping between a dynamic interceptor rule and the name of the additional annotation to be added */ public class AnnotationRule { /** * A RegExp to identify the classes which should get modified */ private String rule; /** * The Annotation to be added */ private Annotation additionalAnnotation; private boolean requiresProxy; public AnnotationRule(String rule, Annotation interceptorBinding, boolean requiresProxy) { this.rule = rule; this.additionalAnnotation = interceptorBinding; this.requiresProxy = requiresProxy; } public String getRule() { return rule; } public Annotation getAdditionalAnnotation() { return additionalAnnotation; } public boolean requiresProxy() { return requiresProxy; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/interceptor/interdyn/InterDynExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.interceptor.interdyn; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; /** *

InterDyn is a CDI (JSR-299) Extension for dynamically * applying annotations (e.g. CDI interceptors) to a class.

* * The main usage is to apply Interceptors per regExp, thus the name. * */ public class InterDynExtension implements Deactivatable, Extension { private List interceptorRules = new ArrayList(); private Logger logger = Logger.getLogger(InterDynExtension.class.getName()); private Map usedInterceptorBindings = new HashMap(); private boolean enabled = false; @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) { if (!ClassDeactivationUtils.isActivated(getClass())) { return; } enabled = CoreBaseConfig.InterDynCustomization.INTERDYN_ENABLED.getValue(); if (enabled) { logger.info("Starting with deltaspike.interdyn instrumentation"); init(); } } public void init() { Set ruleConfigKeys = new HashSet(); // first we collect all the rule property names for (String propertyName : ConfigResolver.getAllProperties().keySet()) { if (propertyName.startsWith(CoreBaseConfig.InterDynCustomization.INTERDYN_RULE_PREFIX) && propertyName.contains(".match")) { ruleConfigKeys.add(propertyName.substring(0, propertyName.indexOf(".match"))); } } for (String ruleConfigKey : ruleConfigKeys) { String match = ConfigResolver.getPropertyValue(ruleConfigKey + ".match"); String annotationClassName = ConfigResolver.getPropertyValue(ruleConfigKey + ".annotation"); if (match != null && annotationClassName != null && match.length() > 0 && annotationClassName.length() > 0) { Annotation anno = getAnnotationImplementation(annotationClassName); boolean requiresProxy = anno.annotationType().getAnnotation(InterceptorBinding.class) != null; interceptorRules.add(new AnnotationRule(match, anno, requiresProxy)); } } if (interceptorRules.isEmpty()) { enabled = false; } } public void processAnnotatedType(@Observes ProcessAnnotatedType pat) { if (enabled) { AnnotatedType at = pat.getAnnotatedType(); String beanClassName = at.getJavaClass().getName(); for (AnnotationRule rule : interceptorRules) { if (beanClassName.matches(rule.getRule())) { if (rule.requiresProxy() && !ClassUtils.isProxyableClass(at.getJavaClass())) { logger.info("Skipping unproxyable class " + beanClassName + " even if matches rule=" + rule.getRule()); return; } pat.configureAnnotatedType() .add(rule.getAdditionalAnnotation()); logger.info("Adding Dynamic Interceptor " + rule.getAdditionalAnnotation() + " to class " + beanClassName ); } } } } private Annotation getAnnotationImplementation(String interceptorBindingClassName) { Annotation ann = usedInterceptorBindings.get(interceptorBindingClassName); if (ann == null) { Class annClass; try { annClass = (Class) ClassUtils.getClassLoader(null).loadClass(interceptorBindingClassName); } catch (ClassNotFoundException e) { throw new RuntimeException("Error while picking up dynamic InterceptorBindingType for class" + interceptorBindingClassName, e); } ann = AnnotationInstanceProvider.of(annClass); usedInterceptorBindings.put(interceptorBindingClassName, ann); } return ann; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/interpreter/PropertyExpressionInterpreter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.interpreter; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.interpreter.BasePropertyExpressionInterpreter; /** * Interpreter which uses the lookup chain of DeltaSpike for configured values */ public class PropertyExpressionInterpreter extends BasePropertyExpressionInterpreter { /** * {@inheritDoc} */ @Override protected String getConfiguredValue(String key) { return ConfigResolver.getProjectStageAwarePropertyValue(key); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/AttributeAccessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.jmx; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Just a helper class mapping a JMX attribute. * It make the link between the attribute and its accessors validating * operations (read/write) are possible. */ public class AttributeAccessor { private final Method getter; private final Method setter; private final boolean presentAsTabularIfPossible; public AttributeAccessor(final Method get, final Method set, final boolean presentAsTabularIfPossible) { this.setter = set; this.getter = get; this.presentAsTabularIfPossible = presentAsTabularIfPossible; } public boolean isPresentAsTabularIfPossible() { return presentAsTabularIfPossible; } public Object get(final Object instance) throws InvocationTargetException, IllegalAccessException { if (getter == null) { throw new IllegalAccessException("This attribute has no getter"); } return getter.invoke(instance); } public void set(final Object instance, final Object value) throws InvocationTargetException, IllegalAccessException { if (setter == null) { throw new IllegalAccessException("This attribute has no setter"); } setter.invoke(instance, value); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/BroadcasterProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; import org.apache.deltaspike.core.api.jmx.MBean; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; @ApplicationScoped public class BroadcasterProducer { @Inject private MBeanExtension extension; @Produces @Dependent public JmxBroadcaster jmxBroadcaster(final InjectionPoint ip) { final Class declaringClass = ip.getMember().getDeclaringClass(); final JmxBroadcaster broadcaster = extension.getBroadcasterFor(declaringClass); if (broadcaster == null) { //TODO discuss validation during bootstrapping throw new IllegalStateException("Invalid injection of " + JmxBroadcaster.class.getName() + " in " + declaringClass.getName() + " detected. It is required to annotate the class with @" + MBean.class.getName()); } return broadcaster; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/DynamicMBeanWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.jmx; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; import org.apache.deltaspike.core.api.jmx.JmxManaged; import org.apache.deltaspike.core.api.jmx.JmxParameter; import org.apache.deltaspike.core.api.jmx.MBean; import org.apache.deltaspike.core.api.jmx.NotificationInfo; import org.apache.deltaspike.core.api.jmx.Table; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ParameterUtil; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; import javax.management.ImmutableDescriptor; import javax.management.InvalidAttributeValueException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanException; import javax.management.MBeanFeatureInfo; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.ReflectionException; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * This class is the MBean implementation of a CDI bean. * It basically delegates to a CDI instance. */ public class DynamicMBeanWrapper extends NotificationBroadcasterSupport implements DynamicMBean, JmxBroadcaster { public static final Logger LOGGER = Logger.getLogger(DynamicMBeanWrapper.class.getName()); private final MBeanInfo info; private final Map fields = new HashMap(); private final Map operations = new HashMap(); private final ClassLoader classloader; private final Class clazz; private final boolean normalScope; private final Annotation[] qualifiers; private Object instance = null; /** * The constructor is the builder for the MBean. All the MBean parsing logic is done here. * * @param annotatedMBean the class of the CDI managed bean * @param normalScope is the CDI bean @Dependent or not * @param qualifiers qualfiers of the CDI bean (used to retrieve it) */ public DynamicMBeanWrapper(final Class annotatedMBean, final boolean normalScope, final Annotation[] qualifiers) { this.clazz = annotatedMBean; this.classloader = Thread.currentThread().getContextClassLoader(); this.normalScope = normalScope; this.qualifiers = qualifiers; final List attributeInfos = new ArrayList(); final List operationInfos = new ArrayList(); final List notificationInfos = new ArrayList(); // class final String description = getDescription(annotatedMBean.getAnnotation(MBean.class).description(), annotatedMBean.getName()); final NotificationInfo notification = annotatedMBean.getAnnotation(NotificationInfo.class); if (notification != null) { notificationInfos.add(getNotificationInfo(notification, annotatedMBean.getName())); } final NotificationInfo.List notifications = annotatedMBean.getAnnotation(NotificationInfo.List.class); if (notifications != null) { for (NotificationInfo notificationInfo : notifications.value()) { notificationInfos.add(getNotificationInfo(notificationInfo, annotatedMBean.getName())); } } // methods for (Method method : annotatedMBean.getMethods()) { final int modifiers = method.getModifiers(); final JmxManaged annotation = method.getAnnotation(JmxManaged.class); if (method.getDeclaringClass().equals(Object.class) || !Modifier.isPublic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isStatic(modifiers) || annotation == null) { continue; } operations.put(method.getName(), new Operation(method, annotation.convertToTabularData())); String operationDescr = getDescription(annotation.description(), method.getName()); Annotation[][] parametersAnnotations = method.getParameterAnnotations(); Class[] parameterTypes = method.getParameterTypes(); MBeanParameterInfo[] parameterInfos = new MBeanParameterInfo[parameterTypes.length]; for (int i = 0; i < parametersAnnotations.length; i++) { String parameterDescription = null; String parameterName = "p" + (i + 1); String java8ParameterName = ParameterUtil.getName(method, i); if (java8ParameterName != null) { parameterName = java8ParameterName; } for (int j = 0; j < parametersAnnotations[i].length; j++) { if (parametersAnnotations[i][j] instanceof JmxParameter) { JmxParameter jmxParameter = (JmxParameter) parametersAnnotations[i][j]; if (!"".equals(jmxParameter.name())) { parameterName = jmxParameter.name(); } if (!"".equals(jmxParameter.description())) { parameterDescription = jmxParameter.description(); } } } parameterInfos[i] = new MBeanParameterInfo(parameterName, parameterTypes[i].getName(), parameterDescription ); } operationInfos.add(new MBeanOperationInfo(method.getName(), operationDescr, parameterInfos, method.getReturnType().getName(), MBeanOperationInfo.UNKNOWN )); } Class clazz = annotatedMBean; while (!Object.class.equals(clazz) && clazz != null) { for (Field field : clazz.getDeclaredFields()) { final JmxManaged annotation = field.getAnnotation(JmxManaged.class); if (annotation != null) { field.setAccessible(true); final String fieldName = field.getName(); final String fieldDescription = getDescription(annotation.description(), fieldName); final Class type = field.getType(); final String methodName; if (fieldName.length() > 1) { methodName = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); } else { methodName = Character.toString(Character.toUpperCase(fieldName.charAt(0))); } Method setter = null; Method getter = null; try { getter = clazz.getMethod("get" + methodName); } catch (NoSuchMethodException e1) { try { getter = clazz.getMethod("is" + methodName); } catch (NoSuchMethodException e2) { // ignored } } try { setter = clazz.getMethod("set" + methodName, field.getType()); } catch (NoSuchMethodException e) { // ignored } attributeInfos.add(new MBeanAttributeInfo( fieldName, toMBeanType(type).getName(), fieldDescription, getter != null, setter != null, false)); fields.put(fieldName, new AttributeAccessor(getter, setter, annotation.convertToTabularData())); } } clazz = clazz.getSuperclass(); } Collections.sort(attributeInfos, MBeanFeatureInfoSorter.INSTANCE); Collections.sort(operationInfos, MBeanFeatureInfoSorter.INSTANCE); Collections.sort(notificationInfos, MBeanFeatureInfoSorter.INSTANCE); info = new MBeanInfo(annotatedMBean.getName(), description, attributeInfos.toArray(new MBeanAttributeInfo[attributeInfos.size()]), null, // default constructor is mandatory operationInfos.toArray(new MBeanOperationInfo[operationInfos.size()]), notificationInfos.toArray(new MBeanNotificationInfo[notificationInfos.size()])); } private Class toMBeanType(final Class type) { if (Map.class.isAssignableFrom(type) || Table.class.isAssignableFrom(type)) { return TabularData.class; } return type; } private MBeanNotificationInfo getNotificationInfo(final NotificationInfo notificationInfo, String sourceInfo) { return new MBeanNotificationInfo( notificationInfo.types(), notificationInfo.notificationClass().getName(), getDescription(notificationInfo.description(), sourceInfo), new ImmutableDescriptor(notificationInfo.descriptorFields())); } private String getDescription(final String description, String defaultDescription) { if (description.isEmpty()) { return defaultDescription; } String descriptionValue = description.trim(); if (descriptionValue.startsWith("{") && descriptionValue.endsWith("}")) { return ConfigResolver.getPropertyValue( descriptionValue.substring(1, descriptionValue.length() - 1), defaultDescription); } return description; } @Override public MBeanInfo getMBeanInfo() { return info; } @Override public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (fields.containsKey(attribute)) { final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classloader); try { final AttributeAccessor attributeAccessor = fields.get(attribute); final Object value = attributeAccessor.get(instance()); return attributeAccessor.isPresentAsTabularIfPossible() ? toResult(attribute, value) : value; } catch (IllegalArgumentException e) { LOGGER.log(Level.SEVERE, "can't get " + attribute + " value", e); } catch (IllegalAccessException e) { LOGGER.log(Level.SEVERE, "can't get " + attribute + " value", e); } catch (InvocationTargetException e) { LOGGER.log(Level.SEVERE, "can't get " + attribute + " value", e); } finally { Thread.currentThread().setContextClassLoader(oldCl); } } throw new AttributeNotFoundException(); } private Object toResult(final String attribute, final Object value) throws InvocationTargetException, IllegalAccessException { if (Map.class.isInstance(value)) { Map map = Map.class.cast(value); return toTabularData(attribute, attribute, new Table().withColumns(map.keySet()).withLine(map.values())); } if (Table.class.isInstance(value)) { return toTabularData(attribute, attribute, Table.class.cast(value)); } return value; } private TabularData toTabularData(final String typeName, final String description, final Table table) { final OpenType[] types = new OpenType[table.getColumnNames().size()]; for (int i = 0; i < types.length; i++) { types[i] = SimpleType.STRING; } try { final String[] keys = table.getColumnNames().toArray(new String[table.getColumnNames().size()]); final CompositeType ct = new CompositeType( typeName, description, keys, keys, types); final TabularType type = new TabularType(typeName, description, ct, keys); final TabularDataSupport data = new TabularDataSupport(type); for (final Collection line : table.getLines()) { data.put(new CompositeDataSupport(ct, keys, line.toArray(new Object[line.size()]))); } return data; } catch (final OpenDataException e) { throw new IllegalArgumentException(e); } } @Override public void setAttribute(final Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { if (fields.containsKey(attribute.getName())) { final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classloader); try { fields.get(attribute.getName()).set(instance(), attribute.getValue()); } catch (IllegalArgumentException e) { LOGGER.log(Level.SEVERE, "can't set " + attribute + " value", e); } catch (IllegalAccessException e) { LOGGER.log(Level.SEVERE, "can't set " + attribute + " value", e); } catch (InvocationTargetException e) { LOGGER.log(Level.SEVERE, "can't set " + attribute + " value", e); } finally { Thread.currentThread().setContextClassLoader(oldCl); } } else { throw new AttributeNotFoundException(); } } @Override public AttributeList getAttributes(final String[] attributes) { final AttributeList list = new AttributeList(); for (String n : attributes) { try { list.add(new Attribute(n, getAttribute(n))); } catch (Exception ignore) { // no-op } } return list; } @Override public AttributeList setAttributes(final AttributeList attributes) { final AttributeList list = new AttributeList(); for (Object o : attributes) { final Attribute attr = (Attribute) o; try { setAttribute(attr); list.add(attr); } catch (Exception ignore) { // no-op } } return list; } @Override public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException { if (operations.containsKey(actionName)) { final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classloader); try { final Operation operation = operations.get(actionName); final Object result = operation.getOperation().invoke(instance(), params); return operation.isPresentAsTabularIfPossible() ? toResult(actionName, result) : result; } catch (InvocationTargetException e) { final Throwable cause = e.getCause(); if (cause instanceof Error) { throw (Error) cause; } if (cause instanceof MBeanException) { throw (MBeanException) cause; } throw new MBeanException((Exception) cause, actionName + " failed with exception"); } catch (IllegalAccessException e) { throw new ReflectionException(e, actionName + " could not be invoked"); } catch (IllegalArgumentException e) { throw new ReflectionException(e, actionName + " could not be invoked"); } finally { Thread.currentThread().setContextClassLoader(oldCl); } } throw new ReflectionException(new NoSuchMethodException(actionName + " doesn't exist")); } private synchronized Object instance() { final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(classloader); try { if (instance != null) { return instance; } if (normalScope) { instance = BeanProvider.getContextualReference(clazz, qualifiers); } else { final BeanManager bm = BeanManagerProvider.getInstance().getBeanManager(); final Set> beans = bm.getBeans(clazz, qualifiers); if (beans == null || beans.isEmpty()) { throw new IllegalStateException("Could not find beans for Type=" + clazz + " and qualifiers:" + Arrays.toString(qualifiers)); } final Bean resolvedBean = bm.resolve(beans); final CreationalContext creationalContext = bm.createCreationalContext(resolvedBean); instance = bm.getReference(resolvedBean, clazz, creationalContext); creationalContext.release(); } return instance; } finally { Thread.currentThread().setContextClassLoader(oldCl); } } @Override public void send(final Notification notification) { sendNotification(notification); } private static class MBeanFeatureInfoSorter implements Comparator { private static final Comparator INSTANCE = new MBeanFeatureInfoSorter(); @Override public int compare(final T o1, final T o2) { return o1.getName().compareTo(o2.getName()); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/MBeanExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.jmx; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; import org.apache.deltaspike.core.api.jmx.MBean; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.BeanUtils; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.BeforeShutdown; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessManagedBean; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.annotation.Annotation; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; public class MBeanExtension implements Extension, Deactivatable { private static final Logger LOGGER = Logger.getLogger(MBeanExtension.class.getName()); private static final String DEFAULT_TYPE = "MBeans"; private static final String DEFAULT_CATEGORY = "org.apache.deltaspike"; private final Map, DynamicMBeanWrapper> wrappers = new ConcurrentHashMap, DynamicMBeanWrapper>(); private final Collection objectNames = new ArrayList(); private Boolean isActivated = true; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } protected void processBean(@Observes final ProcessManagedBean bean, final BeanManager bm) throws Exception { if (!isActivated) { return; } MBean mBeanAnnotation = bean.getAnnotated().getAnnotation(MBean.class); if (mBeanAnnotation != null) { registerObject(bean, mBeanAnnotation, bm); } } protected void shutdown(@Observes final BeforeShutdown shutdown) throws Exception { if (!isActivated) { return; } final MBeanServer mBeanServer = mBeanServer(); for (ObjectName objectName : objectNames) { mBeanServer.unregisterMBean(objectName); LOGGER.info("Unregistered MBean " + objectName.getCanonicalName()); } objectNames.clear(); } private void registerObject(final ProcessManagedBean bean, final MBean mBeanAnnotation, final BeanManager bm) throws Exception { final Class clazz = bean.getAnnotatedBeanClass().getJavaClass(); String objectNameValue = mBeanAnnotation.objectName(); if (objectNameValue.isEmpty()) { final String type = getConfigurableAttribute(mBeanAnnotation.type(), DEFAULT_TYPE); final String category = getConfigurableAttribute(mBeanAnnotation.category(), DEFAULT_CATEGORY); final String properties = getConfigurableAttribute(mBeanAnnotation.properties(), ""); final String name = mBeanAnnotation.name(); final StringBuilder builder = new StringBuilder(category).append(':'); if (!properties.contains("type=")) { builder.append("type=").append(type); } else if (!DEFAULT_TYPE.equals(type)) { LOGGER.warning("type() ignored on " + clazz + " since properties contains it."); } if (!properties.contains("name=")) { if (!name.isEmpty() || properties.isEmpty()) { builder.append(",name="); if (name.isEmpty()) { builder.append(clazz.getName()); } else { builder.append(name); } } // else skip. type is important in JMX but name is a fully custom property so we are able to skip it } if (!properties.isEmpty()) { builder.append(',').append(properties); } objectNameValue = builder.toString(); } final ObjectName objectName = new ObjectName(objectNameValue); final boolean normalScoped = isNormalScope(bean.getAnnotated().getAnnotations(), bm); final Annotation[] qualifiers = qualifiers(bean.getAnnotatedBeanClass(), bm); final DynamicMBeanWrapper mbean = new DynamicMBeanWrapper(clazz, normalScoped, qualifiers); final MBeanServer server = mBeanServer(); if (server.isRegistered(objectName) && CoreBaseConfig.MBeanIntegration.AUTO_UNREGISTER) { server.unregisterMBean(objectName); } server.registerMBean(mbean, objectName); objectNames.add(objectName); wrappers.put(clazz, mbean); LOGGER.info("Registered MBean " + objectName); // don't use canonical name cause it can reorder properties } private Annotation[] qualifiers(final AnnotatedType annotatedBeanClass, final BeanManager bm) { final Set qualifiers = BeanUtils.getQualifiers(bm, annotatedBeanClass.getAnnotations()); return qualifiers.toArray(new Annotation[qualifiers.size()]); } // annotated doesn't always contain inherited annotations // TODO we have to check the origin of this issue private boolean isNormalScope(final Set annotations, final BeanManager bm) { for (Annotation annotation : annotations) { if (bm.isNormalScope(annotation.annotationType())) { return true; } } return false; } JmxBroadcaster getBroadcasterFor(final Class clazz) { return wrappers.get(clazz); } private MBeanServer mBeanServer() { return ManagementFactory.getPlatformMBeanServer(); } private String getConfigurableAttribute(final String annotationAttributeValue, final String defaultValue) { String val = annotationAttributeValue.trim(); if (val.startsWith("{") && val.endsWith("}")) { val = ConfigResolver.getPropertyValue(val.substring(1, val.length() - 1), defaultValue); } return val == null || val.isEmpty() ? defaultValue : val; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/jmx/Operation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.jmx; import java.lang.reflect.Method; /** * Just a helper class mapping a JMX operation. */ class Operation { private final Method operation; private final boolean presentAsTabularIfPossible; Operation(final Method operation, final boolean presentAsTabularIfPossible) { this.operation = operation; this.presentAsTabularIfPossible = presentAsTabularIfPossible; } boolean isPresentAsTabularIfPossible() { return presentAsTabularIfPossible; } Method getOperation() { return operation; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/lock/DefaultLockedStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.lock; import org.apache.deltaspike.core.spi.lock.LockedStrategy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.util.concurrent.locks.Lock; @Dependent public class DefaultLockedStrategy implements LockedStrategy { @Inject private LockSupplierStorage lockSupplierStorage; @Override public Object execute(InvocationContext ic) throws Exception { final Lock lock = lockSupplierStorage.getLockSupplier(ic).get(); try { return ic.proceed(); } finally { lock.unlock(); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/lock/LockSupplier.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.lock; import java.util.concurrent.locks.Lock; interface LockSupplier { Lock get(); } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/lock/LockSupplierStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.lock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.lock.Locked; import org.apache.deltaspike.core.impl.util.AnnotatedMethods; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import static org.apache.deltaspike.core.api.lock.Locked.Operation.READ; @ApplicationScoped @Typed(LockSupplierStorage.class) public class LockSupplierStorage implements Locked.LockFactory { private final ConcurrentMap locks = new ConcurrentHashMap(); // read or write private final ConcurrentMap lockSuppliers = new ConcurrentHashMap(); @Inject private BeanManager beanManager; protected LockSupplier getLockSupplier(final InvocationContext ic) { final Method key = ic.getMethod(); LockSupplier operation = lockSuppliers.get(key); if (operation == null) { final Class declaringClass = key.getDeclaringClass(); final AnnotatedType annotatedType = beanManager.createAnnotatedType(declaringClass); final AnnotatedMethod annotatedMethod = AnnotatedMethods.findMethod(annotatedType, key); Locked config = annotatedMethod.getAnnotation(Locked.class); if (config == null) { config = annotatedType.getAnnotation(Locked.class); } final Locked.LockFactory factory = config.factory() != Locked.LockFactory.class ? Locked.LockFactory.class.cast( beanManager.getReference(beanManager.resolve( beanManager.getBeans( config.factory())), Locked.LockFactory.class, null)) : this; final ReadWriteLock writeLock = factory.newLock(annotatedMethod, config.fair()); final long timeout = config.timeoutUnit().toMillis(config.timeout()); final Lock lock = config.operation() == READ ? writeLock.readLock() : writeLock.writeLock(); if (timeout > 0) { operation = new LockSupplier() { @Override public Lock get() { try { if (!lock.tryLock(timeout, TimeUnit.MILLISECONDS)) { throw new IllegalStateException("Can't lock for " + key + " in " + timeout + "ms"); } } catch (final InterruptedException e) { Thread.interrupted(); throw new IllegalStateException("Locking interrupted", e); } return lock; } }; } else { operation = new LockSupplier() { @Override public Lock get() { lock.lock(); return lock; } }; } final LockSupplier existing = lockSuppliers.putIfAbsent(key, operation); if (existing != null) { operation = existing; } } return operation; } @Override public ReadWriteLock newLock(final AnnotatedMethod method, final boolean fair) { final String name = method.getJavaMember().getDeclaringClass().getName(); ReadWriteLock lock = locks.get(name); if (lock == null) { lock = new ReentrantReadWriteLock(fair); final ReadWriteLock existing = locks.putIfAbsent(name, lock); if (existing != null) { lock = existing; } } return lock; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/lock/LockedInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.lock; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.lock.Locked; import org.apache.deltaspike.core.spi.lock.LockedStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @Locked @Interceptor @Priority(1000) public class LockedInterceptor implements Serializable { @Inject private LockedStrategy lockedStrategy; @AroundInvoke public Object invoke(final InvocationContext ic) throws Exception { return lockedStrategy.execute(ic); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultLocaleResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import org.apache.deltaspike.core.api.message.LocaleResolver; import jakarta.enterprise.context.Dependent; import java.io.Serializable; import java.util.Locale; /** * Provide the default implementation for picking up the Locale * for messages. */ @Dependent public class DefaultLocaleResolver implements LocaleResolver, Serializable { private static final long serialVersionUID = 2075618472090834156L; @Override public Locale getLocale() { return Locale.getDefault(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageInterpolator; import org.apache.deltaspike.core.api.message.MessageResolver; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Locale; import static org.apache.deltaspike.core.api.message.MessageResolver.MISSING_RESOURCE_MARKER; /** * {@inheritDoc} */ @Vetoed public class DefaultMessage implements Message { private String messageTemplate; private List arguments = new ArrayList<>(); private MessageContext messageContext; public DefaultMessage(MessageContext messageContext) { reset(); this.messageContext = messageContext; } protected void reset() { messageTemplate = null; arguments = new ArrayList<>(); } @Override public Message argument(Serializable... arguments) { if (arguments != null) { Collections.addAll(this.arguments, arguments); } return this; } @Override public Message template(String messageTemplate) { this.messageTemplate = messageTemplate; return this; } @Override public String getTemplate() { return messageTemplate; } @Override public Serializable[] getArguments() { return arguments.toArray(new Serializable[arguments.size()]); } @Override public String toString() { return toString((String) null); } @Override public String toString(String category) { // the string construction happens in 3 phases // first try to pickup the message via the MessageResolver String template = getTemplate(); if (template == null) { return ""; } String ret = template; MessageResolver messageResolver = messageContext.getMessageResolver(); if (messageResolver != null) { String resolvedTemplate = messageResolver.getMessage(messageContext, template, category); if (resolvedTemplate == null) { // this means an error happened during message resolving resolvedTemplate = markAsUnresolved(template); } ret = resolvedTemplate; template = resolvedTemplate; } // last step is to interpolate the message MessageInterpolator messageInterpolator = messageContext.getMessageInterpolator(); if (messageInterpolator != null) { Locale locale = messageContext.getLocale(); ret = messageInterpolator.interpolate(template, getArguments(), locale); } return ret; } private String markAsUnresolved(String template) { if (messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) { template = messageTemplate.substring(1, messageTemplate.length() - 1); } StringBuilder sb = new StringBuilder(MISSING_RESOURCE_MARKER + template + MISSING_RESOURCE_MARKER); if (getArguments() != null && getArguments().length > 0) { sb.append(" ").append(Arrays.toString(getArguments())); } return sb.toString(); } @Override public String toString(MessageContext messageContext) { return toString(messageContext, null); } @Override public String toString(MessageContext messageContext, String category) { return messageContext.message() .template(getTemplate()) .argument(getArguments()) .toString(category); } /** * Attention, the {@link #messageContext} is deliberately not part of the equation! */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Message)) { return false; } Message other = (Message) o; if (getTemplate() == null && other.getTemplate() != null) { return false; } if (getTemplate() != null && !getTemplate().equals(other.getTemplate())) { return false; } //noinspection RedundantIfStatement if (arguments != null ? !Arrays.equals(arguments.toArray(), other.getArguments()) : other.getArguments() != null) { return false; } return true; } /** * Attention, the {@link #messageContext} is deliberately not part of the equation! */ @Override public int hashCode() { int result = getTemplate().hashCode(); result = 31 * result + (arguments != null ? arguments.hashCode() : 0); return result; } @Override public Message argumentArray(Serializable[] arguments) { if (arguments != null) { return argument(Arrays.asList(arguments)); } return this; } @Override public Message argument(Collection arguments) { if (arguments != null) { this.arguments.addAll(arguments); } return this; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.message.LocaleResolver; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageInterpolator; import org.apache.deltaspike.core.api.message.MessageResolver; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; @Dependent @Typed(MessageContext.class) class DefaultMessageContext implements MessageContext { private static final long serialVersionUID = -110779217295211303L; @Inject private MessageInterpolator messageInterpolator = null; @Inject private MessageResolver messageResolver = null; @Inject private LocaleResolver localeResolver = null; private List messageSources = new ArrayList(); DefaultMessageContext() { } DefaultMessageContext(MessageContext otherMessageContext) { messageInterpolator(otherMessageContext.getMessageInterpolator()); localeResolver(otherMessageContext.getLocaleResolver()); messageResolver(otherMessageContext.getMessageResolver()); messageSources.addAll(otherMessageContext.getMessageSources()); } @Override public MessageContext clone() { return new DefaultMessageContext(this); } @Override public Message message() { return new DefaultMessage(this); } @Override public MessageContext messageSource(String... messageSource) { List newMessageSources = new ArrayList(); for (String currentMessageSource : messageSource) { //don't insert message-sources twice if (!messageSources.contains(currentMessageSource)) { newMessageSources.add(currentMessageSource); } } // add on first position messageSources.addAll(0, newMessageSources); return this; } @Override public Locale getLocale() { if (getLocaleResolver() == null) { return Locale.getDefault(); } return getLocaleResolver().getLocale(); } @Override public LocaleResolver getLocaleResolver() { return localeResolver; } @Override public List getMessageSources() { return Collections.unmodifiableList(messageSources); } @Override public MessageContext localeResolver(LocaleResolver localeResolver) { this.localeResolver = localeResolver; return this; } @Override public MessageInterpolator getMessageInterpolator() { return messageInterpolator; } @Override public MessageContext messageInterpolator(MessageInterpolator messageInterpolator) { this.messageInterpolator = messageInterpolator; return this; } @Override public MessageResolver getMessageResolver() { return messageResolver; } @Override public MessageContext messageResolver(MessageResolver messageResolver) { this.messageResolver = messageResolver; return this; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageInterpolator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import org.apache.deltaspike.core.api.message.MessageInterpolator; import jakarta.enterprise.context.ApplicationScoped; import java.io.Serializable; import java.util.Locale; /** * {@inheritDoc} */ @ApplicationScoped public class DefaultMessageInterpolator implements MessageInterpolator, Serializable { private static final long serialVersionUID = -8854087197813424812L; @Override public String interpolate(String messageTemplate, Serializable[] arguments, Locale locale) { if (arguments == null || arguments.length == 0) { return messageTemplate; } return String.format(locale, messageTemplate, arguments); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/DefaultMessageResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageResolver; import org.apache.deltaspike.core.util.PropertyFileUtils; import jakarta.enterprise.context.Dependent; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; @Dependent @SuppressWarnings("UnusedDeclaration") public class DefaultMessageResolver implements MessageResolver { private static final long serialVersionUID = 5834411208472341006L; @Override public String getMessage(MessageContext messageContext, String messageTemplate, String category) { // we can use {{ as escaping for now if (messageTemplate.startsWith("{{")) { // in which case we just cut of the first '{' return messageTemplate.substring(1); } if (messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) { String resourceKey = messageTemplate.substring(1, messageTemplate.length() - 1); List messageSources = getMessageSources(messageContext); if (messageSources == null || messageSources.isEmpty()) { // using {} without a bundle is always an error return null; } Iterator messageSourceIterator = messageSources.iterator(); Locale locale = messageContext.getLocale(); String currentMessageSource; while (messageSourceIterator.hasNext()) { currentMessageSource = messageSourceIterator.next(); try { ResourceBundle messageBundle = PropertyFileUtils.getResourceBundle(currentMessageSource, locale); if (category != null && category.length() > 0) { try { return messageBundle.getString(resourceKey + "_" + category); } catch (MissingResourceException e) { // we fallback on the version without the category return messageBundle.getString(resourceKey); } } return messageBundle.getString(resourceKey); } catch (MissingResourceException e) { if (!messageSourceIterator.hasNext()) { return null; } } } } return messageTemplate; } protected List getMessageSources(MessageContext messageContext) { return messageContext.getMessageSources(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.Bean; @Vetoed abstract class MessageBundleContext { private static final ThreadLocal MESSAGE_BUNDLE_BEAN = new ThreadLocal(); private MessageBundleContext() { // prevent instantiation } static void setBean(Bean bean) { MESSAGE_BUNDLE_BEAN.set(bean); } static void reset() { MESSAGE_BUNDLE_BEAN.set(null); MESSAGE_BUNDLE_BEAN.remove(); } static Bean getCurrentMessageBundleBean() { return MESSAGE_BUNDLE_BEAN.get(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.spi.*; import jakarta.enterprise.inject.spi.configurator.BeanConfigurator; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageTemplate; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.BeanConfiguratorUtils; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import java.io.Serializable; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.*; /** * Extension for handling {@link MessageBundle}s. * * @see MessageBundle * @see MessageTemplate */ public class MessageBundleExtension implements Extension, Deactivatable { private final Collection> messageBundleTypes = new HashSet>(); private List deploymentErrors = new ArrayList(); private Boolean isActivated = true; @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } @SuppressWarnings("UnusedDeclaration") protected void detectInterfaces(@Observes ProcessAnnotatedType processAnnotatedType) { if (!isActivated) { return; } AnnotatedType type = processAnnotatedType.getAnnotatedType(); if (type.isAnnotationPresent(MessageBundle.class)) { if (validateMessageBundle(type.getJavaClass())) { messageBundleTypes.add(type); } } } /** * @return true if all is well */ private boolean validateMessageBundle(Class currentClass) { boolean ok = true; // sanity check: annotated class must be an Interface if (!currentClass.isInterface()) { deploymentErrors.add("@MessageBundle must only be used on Interfaces, but got used on class " + currentClass.getName()); return false; } for (Method currentMethod : currentClass.getDeclaredMethods()) { if (!currentMethod.isAnnotationPresent(MessageTemplate.class)) { continue; } if (String.class.isAssignableFrom(currentMethod.getReturnType())) { continue; } if (Message.class.isAssignableFrom(currentMethod.getReturnType())) { continue; } deploymentErrors.add(currentMethod.getReturnType().getName() + " isn't supported. Details: " + currentMethod.getDeclaringClass().getName() + "#" + currentMethod.getName() + " only " + String.class.getName() + " or " + Message.class.getName()); ok = false; } return ok; } @SuppressWarnings("UnusedDeclaration") protected void installMessageBundleProducerBeans(@Observes AfterBeanDiscovery abd, BeanManager beanManager) { if (!deploymentErrors.isEmpty()) { abd.addDefinitionError(new IllegalArgumentException("The following MessageBundle problems where found: " + Arrays.toString(deploymentErrors.toArray()))); return; } for (AnnotatedType type : messageBundleTypes) { addAsBean(abd, beanManager, type); } } protected void addAsBean(AfterBeanDiscovery abd, BeanManager beanManager, AnnotatedType type) { BeanConfigurator beanConfigurator = abd.addBean() .createWith(cc -> { final Bean invocationHandlerBean = beanManager.resolve( beanManager.getBeans(MessageBundleInvocationHandler.class)); return createMessageBundleProxy(type.getJavaClass(), (MessageBundleInvocationHandler) beanManager.getReference(invocationHandlerBean, MessageBundleInvocationHandler.class, cc)); }); BeanConfiguratorUtils.read(beanManager, beanConfigurator, type) .types(type.getJavaClass(), Object.class, Serializable.class) .addQualifier(Default.Literal.INSTANCE) .scope(ApplicationScoped.class) // needs to be a normalscope due to a bug in older Weld versions .id("MessageBundleBean#" + type.getJavaClass().getName()); } @SuppressWarnings("UnusedDeclaration") protected void cleanup(@Observes AfterDeploymentValidation afterDeploymentValidation) { messageBundleTypes.clear(); } private T createMessageBundleProxy(Class type, MessageBundleInvocationHandler handler) { return type.cast(Proxy.newProxyInstance(ClassUtils.getClassLoader(null), new Class[]{type, Serializable.class}, handler)); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageBundleInvocationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Typed; import jakarta.inject.Inject; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.deltaspike.core.api.message.LocaleResolver; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageInterpolator; import org.apache.deltaspike.core.api.message.MessageResolver; import org.apache.deltaspike.core.api.message.MessageContextConfig; import org.apache.deltaspike.core.api.message.MessageTemplate; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; /** * This Proxy InvocationHandler implements the handling for all our * {@link org.apache.deltaspike.core.api.message.MessageBundle}s. */ @Dependent @Typed(MessageBundleInvocationHandler.class) public class MessageBundleInvocationHandler implements InvocationHandler, Serializable { private static final long serialVersionUID = -8980912335543392357L; @Inject private MessageContext baseMessageContext = null; /** * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, * java.lang.reflect.Method, java.lang.Object[]) */ @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (method.getDeclaringClass().equals(Object.class)) { // this sometimes gets invoked directly by the container // there is no perfect solution for those methods, // so we try to use the best info we have atm. if ("hashCode".equals(method.getName())) { return proxy.getClass().hashCode(); } if ("toString".equals(method.getName())) { return proxy.getClass().toString(); } if ("equals".equals(method.getName())) { return proxy.getClass().equals(args[0].getClass()); } return null; } final MessageTemplate messageTemplate = method.getAnnotation(MessageTemplate.class); String messageTemplateValue; if (messageTemplate != null) { messageTemplateValue = messageTemplate.value(); } else { messageTemplateValue = "{" + method.getName() + "}"; } MessageContext messageContext = resolveMessageContextFromArguments(args); List arguments = resolveMessageArguments(args); if (messageContext == null) { messageContext = baseMessageContext.clone(); MessageContextConfig messageContextConfig = method.getDeclaringClass().getAnnotation(MessageContextConfig.class); if (messageContextConfig != null) { applyMessageContextConfig(messageContext, messageContextConfig); } } String messageBundleName = method.getDeclaringClass().getName(); Message message = messageContext .messageSource(messageBundleName).message() .template(messageTemplateValue) .argument(arguments.toArray(new Serializable[arguments.size()])); if (String.class.isAssignableFrom(method.getReturnType())) { return message.toString(); } return message; } private void applyMessageContextConfig(MessageContext messageContext, MessageContextConfig messageContextConfig) { if (!MessageResolver.class.equals(messageContextConfig.messageResolver())) { Class messageResolverClass = ClassUtils.tryToLoadClassForName(messageContextConfig.messageResolver().getName()); messageContext.messageResolver( BeanProvider.getContextualReference(messageResolverClass, Any.Literal.INSTANCE)); } if (!MessageInterpolator.class.equals(messageContextConfig.messageInterpolator())) { Class messageInterpolatorClass = ClassUtils.tryToLoadClassForName(messageContextConfig.messageInterpolator().getName()); messageContext.messageInterpolator( BeanProvider.getContextualReference(messageInterpolatorClass, Any.Literal.INSTANCE)); } if (!LocaleResolver.class.equals(messageContextConfig.localeResolver())) { Class localeResolverClass = ClassUtils.tryToLoadClassForName(messageContextConfig.localeResolver().getName()); messageContext.localeResolver( BeanProvider.getContextualReference(localeResolverClass, Any.Literal.INSTANCE)); } String[] messageSources = messageContextConfig.messageSource(); messageContext.messageSource(messageSources); } private List resolveMessageArguments(Object[] args) { List arguments = new ArrayList(); if (args != null && args.length > 0) { for (int i = 0; i < args.length; i++) { Object arg = args[i]; if (i == 0 && arg != null && MessageContext.class.isAssignableFrom(arg.getClass())) { continue; } if (arg instanceof Serializable) { arguments.add((Serializable) arg); } else { // for non-serializable objects we perform an immediate toString() instead arguments.add(arg == null ? null : arg.toString()); } } } return arguments; } private MessageContext resolveMessageContextFromArguments(Object[] args) { if (args != null && args.length > 0 && args[0] != null && MessageContext.class.isAssignableFrom(args[0].getClass())) { return (MessageContext) args[0]; } return null; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/message/MessageFormatMessageInterpolator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.message; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; import java.io.Serializable; import java.util.Locale; import java.text.MessageFormat; import org.apache.deltaspike.core.api.message.MessageInterpolator; /** * This is an Alternative implementation of a {@link MessageInterpolator} which * uses java.text.MessageFormat for formatting. * * Please note that for some EE containers you might need to add this <alternative>> * to all JARs and classpath entries beanx.xml files. * * {@inheritDoc} */ @ApplicationScoped @Alternative public class MessageFormatMessageInterpolator implements MessageInterpolator, Serializable { private static final long serialVersionUID = -8854087197813424812L; @Override public String interpolate(String messageTemplate, Serializable[] arguments, Locale locale) { MessageFormat messageFormat = new MessageFormat(messageTemplate, locale); return messageFormat.format(arguments); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/monitoring/InvocationMonitorInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.monitoring; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.monitoring.InvocationMonitored; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; import java.util.logging.Level; import java.util.logging.Logger; @Interceptor @InvocationMonitored @Priority(1000) public class InvocationMonitorInterceptor implements Serializable { private static final Logger logger = Logger.getLogger(InvocationMonitorInterceptor.class.getName()); @Inject private RequestInvocationCounter requestInvocationCounter; @AroundInvoke public Object track(InvocationContext ic) throws Exception { long start = System.nanoTime(); Object retVal = ic.proceed(); long end = System.nanoTime(); try { requestInvocationCounter.count(ic.getTarget().getClass().getName(), ic.getMethod().getName(), end - start); } catch (ContextNotActiveException cnae) { logger.log(Level.FINE, "could not monitor invocatino to {} due to RequestContext not being active", ic.getMethod().toString()); } return retVal; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/monitoring/InvocationResultLogger.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.monitoring; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.api.exclude.Exclude; import org.apache.deltaspike.core.api.monitoring.MonitorResultEvent; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Logger; /** * This class will observe all {@link MonitorResultEvent}s * and log them accordingly */ @ApplicationScoped @Exclude(onExpression = InvocationResultLogger.DISABLED_EXPRESSION) public class InvocationResultLogger { static final String DISABLED_EXPRESSION = CoreBaseConfig.InterDynCustomization.CONFIG_INVOCATIONRESULTLOGGER_ENABLED + "==false"; private static final Logger logger = Logger.getLogger(InvocationResultLogger.class.getName()); private static final int DEFAULT_MAX_LOG_LINES = 8; private static final String PROPERTY_MAX_LOG_LINES = "MAX_LOG_LINES"; private int maxLogLines = DEFAULT_MAX_LOG_LINES + 1; @PostConstruct private void init() { String maxLogLinesProp = System.getProperty(PROPERTY_MAX_LOG_LINES); if (maxLogLinesProp != null) { maxLogLines = Integer.parseInt(maxLogLinesProp) + 1; } logger.info("Using MAX_LOG_LINE=" + maxLogLines); } public void logMonitorResultEvents(@Observes MonitorResultEvent mre) { // we copy them because we don't like to make the event data dirty. // there might be other observers interested in the result... List methodInvocations = createMethodResultEntries(mre.getMethodInvocations(), mre.getMethodDurations()); List classInvocations = createClassResultEntries(mre.getClassInvocations()); StringBuilder sb = new StringBuilder(); sb.append("Top Class Invocations:\n"); for (int i = 1; i < maxLogLines && i <= classInvocations.size(); i++) { ResultEntry re = classInvocations.get(classInvocations.size() - i); sb.append(" count: ").append(re.getCount()).append("\t").append(re.getToken()).append("\n"); } logger.info(sb.toString()); sb = new StringBuilder(); sb.append("Top Method Invocations:\n"); for (int i = 1; i < maxLogLines && i <= methodInvocations.size(); i++) { ResultEntry re = methodInvocations.get(methodInvocations.size() - i); sb.append(" dur[ms]: ").append(re.getDuration() / 1e6f).append("\tcount: "). append(re.getCount()).append("\t").append(re.getToken()).append("\n"); } logger.info(sb.toString()); } private List createMethodResultEntries(Map invocations, Map durations) { List resultEntries = new ArrayList(invocations.size()); for (Map.Entry entry : invocations.entrySet()) { long dur = durations.get(entry.getKey()).longValue(); resultEntries.add(new ResultEntry(entry.getValue().intValue(), entry.getKey(), dur)); } Collections.sort(resultEntries); return resultEntries; } private List createClassResultEntries(Map invocations) { List resultEntries = new ArrayList(invocations.size()); for (Map.Entry entry : invocations.entrySet()) { resultEntries.add(new ResultEntry(entry.getValue().intValue(), entry.getKey(), 0L)); } Collections.sort(resultEntries); return resultEntries; } private static class ResultEntry implements Comparable { private Integer count; private String token; private long duration; private ResultEntry(Integer count, String token, long duration) { this.count = count; this.token = token; this.duration = duration; } public Integer getCount() { return count; } public String getToken() { return token; } public long getDuration() { return duration; } public int compareTo(ResultEntry o) { if (duration == 0 && o.duration == 0) { return count.compareTo(o.count); } return duration < o.duration ? -1 : (duration == o.duration ? 0 : 1); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/monitoring/RequestInvocationCounter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.monitoring; import org.apache.deltaspike.core.api.monitoring.MonitorResultEvent; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.event.Event; import jakarta.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * This bean will get used to count invocations for a single request */ @RequestScoped public class RequestInvocationCounter { @Inject private Event mre; /** * Counter for all method invocations * key = fully qualified method name (includes class) * value = Integer with value */ private Map methodInvocations = new HashMap(); /** * Duration of all method invocations * key = fully qualified method name (includes class) * value = Integer with value */ private Map methodDurations = new HashMap(); /** * Counter for all class invocations * key = fully qualified class name * value = Integer with value */ private Map classInvocations = new HashMap(); @PreDestroy public void postUsage() { mre.fire(new MonitorResultEvent(methodInvocations, classInvocations, methodDurations)); } /** * increment the respective counters * @param className the getName() of the class * @param methodName the invoked methods name * @param duration duration of the method invocation in nano time */ public void count(String className, String methodName, long duration) { AtomicInteger classCount = classInvocations.get(className); if (classCount == null) { classCount = new AtomicInteger(0); classInvocations.put(className, classCount); } classCount.incrementAndGet(); String methodKey = className + "#" + methodName; AtomicInteger methCount = methodInvocations.get(methodKey); if (methCount == null) { methCount = new AtomicInteger(0); methodInvocations.put(methodKey, methCount); } methCount.incrementAndGet(); AtomicLong methDur = methodDurations.get(methodKey); if (methDur == null) { methDur = new AtomicLong(0); methodDurations.put(methodKey, methDur); } methDur.addAndGet(duration); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/AbstractBeanHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope; 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 java.io.Serializable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractBeanHolder implements Serializable { private Map storageMap = new ConcurrentHashMap(); private final boolean useConcurrentStorage; private final boolean usePassivationCapableStorage; protected AbstractBeanHolder() { this(true, true); } protected AbstractBeanHolder(boolean useConcurrentStorage, boolean usePassivationCapableStorage) { this.useConcurrentStorage = useConcurrentStorage; this.usePassivationCapableStorage = usePassivationCapableStorage; } public ContextualStorage getContextualStorage(BeanManager beanManager, K key, boolean createIfNotExist) { ContextualStorage contextualStorage = storageMap.get(key); if (contextualStorage == null && createIfNotExist) { contextualStorage = createContextualStorage(beanManager, key); } return contextualStorage; } protected synchronized ContextualStorage createContextualStorage(BeanManager beanManager, K key) { ContextualStorage contextualStorage = storageMap.get(key); if (contextualStorage == null) { contextualStorage = new ContextualStorage(beanManager, useConcurrentStorage, usePassivationCapableStorage); storageMap.put(key, contextualStorage); } return contextualStorage; } public Map getStorageMap() { return storageMap; } public Map forceNewStorage() { Map oldStorageMap = storageMap; storageMap = new ConcurrentHashMap(); return oldStorageMap; } @PreDestroy public void destroyBeans() { Map oldWindowContextStorages = forceNewStorage(); for (ContextualStorage contextualStorage : oldWindowContextStorages.values()) { AbstractContext.destroyAllActive(contextualStorage); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/DeltaSpikeContextExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.scope.conversation.ConversationBeanHolder; import org.apache.deltaspike.core.impl.scope.conversation.GroupedConversationContext; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessBeanAccessHistory; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessBeanHolder; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessContext; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessViewHistory; import org.apache.deltaspike.core.impl.scope.window.WindowBeanHolder; import org.apache.deltaspike.core.impl.scope.window.WindowContextImpl; import org.apache.deltaspike.core.impl.scope.window.WindowIdHolder; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; /** * Handle all DeltaSpike WindowContext and ConversationContext * related features. */ public class DeltaSpikeContextExtension implements Extension, Deactivatable { private WindowContextImpl windowContext; private GroupedConversationContext conversationContext; private ViewAccessContext viewAccessScopedContext; private Boolean isActivated = true; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } public void registerDeltaSpikeContexts(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { if (!isActivated) { return; } windowContext = new WindowContextImpl(beanManager); conversationContext = new GroupedConversationContext(beanManager, windowContext); viewAccessScopedContext = new ViewAccessContext(beanManager, windowContext); afterBeanDiscovery.addContext(windowContext); afterBeanDiscovery.addContext(conversationContext); afterBeanDiscovery.addContext(viewAccessScopedContext); } /** * We can only initialize our contexts in AfterDeploymentValidation because * getBeans must not be invoked earlier than this phase to reduce randomness * caused by Beans no being fully registered yet. */ public void initializeDeltaSpikeContexts(@Observes AfterDeploymentValidation adv, BeanManager beanManager) { if (!isActivated) { return; } WindowBeanHolder windowBeanHolder = BeanProvider.getContextualReference(beanManager, WindowBeanHolder.class, false); WindowIdHolder windowIdHolder = BeanProvider.getContextualReference(beanManager, WindowIdHolder.class, false); windowContext.init(windowBeanHolder, windowIdHolder); ConversationBeanHolder conversationBeanHolder = BeanProvider.getContextualReference(beanManager, ConversationBeanHolder.class, false); conversationContext.init(conversationBeanHolder); ViewAccessBeanHolder viewAccessBeanHolder = BeanProvider.getContextualReference(beanManager, ViewAccessBeanHolder.class, false); ViewAccessBeanAccessHistory viewAccessBeanAccessHistory = BeanProvider.getContextualReference(beanManager, ViewAccessBeanAccessHistory.class, false); ViewAccessViewHistory viewAccessViewHistory = BeanProvider.getContextualReference(beanManager, ViewAccessViewHistory.class, false); viewAccessScopedContext.init(viewAccessBeanHolder, viewAccessBeanAccessHistory, viewAccessViewHistory); } public WindowContextImpl getWindowContext() { return windowContext; } public GroupedConversationContext getConversationContext() { return conversationContext; } public ViewAccessContext getViewAccessScopedContext() { return viewAccessScopedContext; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/ConversationBeanHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.core.impl.scope.AbstractBeanHolder; @WindowScoped public class ConversationBeanHolder extends AbstractBeanHolder { private static final long serialVersionUID = 6313493410718133308L; } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/ConversationKey.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.scope.ConversationGroup; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Default; import jakarta.inject.Named; import java.io.Serializable; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashSet; import java.util.Set; public class ConversationKey implements Serializable { private static final long serialVersionUID = 6565204223928766263L; private final Class groupKey; //HashSet due to Serializable warning in checkstyle rules private HashSet qualifiers; public ConversationKey(Class groupKey, Annotation... qualifiers) { this.groupKey = groupKey; //TODO maybe we have to add a real qualifier instead Class annotationType; for (Annotation qualifier : qualifiers) { annotationType = qualifier.annotationType(); if (Any.class.isAssignableFrom(annotationType) || Default.class.isAssignableFrom(annotationType) || Named.class.isAssignableFrom(annotationType) || ConversationGroup.class.isAssignableFrom(annotationType)) { //won't be used for this key! continue; } if (this.qualifiers == null) { this.qualifiers = new HashSet(); } this.qualifiers.add(qualifier); } } public Class getConversationGroup() { return groupKey; } public Set getQualifiers() { if (qualifiers == null) { return Collections.emptySet(); } return Collections.unmodifiableSet(this.qualifiers); } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof ConversationKey)) { return false; } ConversationKey that = (ConversationKey) o; if (!groupKey.equals(that.groupKey)) { return false; } if (qualifiers == null && that.qualifiers == null) { return true; } if (qualifiers != null && that.qualifiers == null) { return false; } if (!that.qualifiers.equals(qualifiers)) { return false; } return true; } /** * {@inheritDoc} */ @Override public int hashCode() { int result = groupKey.hashCode(); result = 31 * result + (qualifiers != null ? qualifiers.hashCode() : 0); return result; } /** * {@inheritDoc} */ @Override public String toString() { StringBuilder result = new StringBuilder("conversation-key\n"); result.append("\n"); result.append("\tgroup:\t\t"); result.append(this.groupKey.getName()); result.append("\n"); result.append("\tqualifiers:\t"); if (qualifiers != null) { for (Annotation qualifier : this.qualifiers) { result.append(qualifier.annotationType().getName()); result.append(" "); } } else { result.append("---"); } return result.toString(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/GroupedConversationArtifactProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.scope.GroupedConversation; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.impl.util.ConversationUtils; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; @ApplicationScoped public class GroupedConversationArtifactProducer { @Inject private DeltaSpikeContextExtension deltaSpikeContextExtension; @Produces @Dependent public GroupedConversationManager getGroupedConversationManager() { return new InjectableGroupedConversationManager(deltaSpikeContextExtension.getConversationContext()); } @Produces @Dependent public GroupedConversation getGroupedConversation(InjectionPoint injectionPoint, BeanManager beanManager) { ConversationKey conversationKey = ConversationUtils.convertToConversationKey(injectionPoint.getBean(), beanManager); return new InjectableGroupedConversation(conversationKey, getGroupedConversationManager()); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/GroupedConversationContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.scope.ConversationSubGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import org.apache.deltaspike.core.impl.scope.window.WindowContextImpl; import org.apache.deltaspike.core.impl.util.ConversationUtils; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.util.context.AbstractContext; import org.apache.deltaspike.core.util.context.ContextualInstanceInfo; import org.apache.deltaspike.core.util.context.ContextualStorage; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @Vetoed //TODO add RequestCache //TODO ConversationSubGroup public class GroupedConversationContext extends AbstractContext implements GroupedConversationManager { private static final long serialVersionUID = -5463564406828391468L; private final BeanManager beanManager; private final WindowContextImpl windowContext; private ConversationBeanHolder conversationBeanHolder; public GroupedConversationContext(BeanManager beanManager, WindowContextImpl windowContext) { super(beanManager); this.beanManager = beanManager; this.windowContext = windowContext; } public void init(ConversationBeanHolder conversationBeanHolder) { this.conversationBeanHolder = conversationBeanHolder; } @Override protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { ConversationKey conversationKey = ConversationUtils.convertToConversationKey(contextual, this.beanManager); return this.conversationBeanHolder.getContextualStorage(this.beanManager, conversationKey, createIfNotExist); } @Override protected List getActiveContextualStorages() { List result = new ArrayList(); result.addAll(this.conversationBeanHolder.getStorageMap().values()); return result; } @Override public Class getScope() { return GroupedConversationScoped.class; } @Override public boolean isActive() { return this.windowContext.isActive(); //autom. active once a window is active } @Override public ContextualStorage closeConversation(Class conversationGroup, Annotation... qualifiers) { ConversationKey conversationKey = new ConversationKey(conversationGroup, qualifiers); ContextualStorage contextualStorage = this.conversationBeanHolder.getStorageMap().remove(conversationKey); if (contextualStorage != null) { AbstractContext.destroyAllActive(contextualStorage); } return contextualStorage; } @Override public Set closeConversationGroup(Class conversationGroup) { Set result = new HashSet(); ConversationSubGroup conversationSubGroup = conversationGroup.getAnnotation(ConversationSubGroup.class); Set> subGroups = null; if (conversationSubGroup != null) { conversationGroup = ConversationUtils.getDeclaredConversationGroup(conversationGroup); subGroups = new HashSet>(conversationSubGroup.subGroup().length); Collections.addAll(subGroups, conversationSubGroup.subGroup()); } Map storageMap = this.conversationBeanHolder.getStorageMap(); for (Map.Entry entry : storageMap.entrySet()) { if (entry.getKey().getConversationGroup().equals(conversationGroup)) { if (subGroups == null) { AbstractContext.destroyAllActive(entry.getValue()); result.add(entry.getValue()); storageMap.remove(entry.getKey()); //ok due to ConcurrentHashMap } else { tryToDestroySubGroup(subGroups, entry); if (entry.getValue().getStorage().isEmpty()) { storageMap.remove(entry.getKey()); //ok due to ConcurrentHashMap } } } } return result; } private void tryToDestroySubGroup(Set> subGroups, Map.Entry entry) { ContextualStorage storage = entry.getValue(); for (Map.Entry> storageEntry : storage.getStorage().entrySet()) { for (Class subGroup : subGroups) { Class classOfEntry = storageEntry.getValue().getContextualInstance().getClass(); if (subGroup.equals(classOfEntry) || (subGroup.isInterface() && subGroup.isAssignableFrom(classOfEntry))) { Contextual bean = storage.getBean(storageEntry.getKey()); AbstractContext.destroyBean(bean, storageEntry.getValue()); storage.getStorage().remove(storageEntry.getKey()); //ok due to ConcurrentHashMap break; } } } } @Override public void closeConversations() { this.conversationBeanHolder.destroyBeans(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/InjectableGroupedConversation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.scope.GroupedConversation; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.util.Set; @Vetoed class InjectableGroupedConversation implements GroupedConversation { private static final long serialVersionUID = -3909049219127821425L; private final ConversationKey conversationKey; private final GroupedConversationManager conversationManager; InjectableGroupedConversation(ConversationKey conversationKey, GroupedConversationManager conversationManager) { this.conversationManager = conversationManager; this.conversationKey = conversationKey; } @Override public void close() { Set qualifiers = this.conversationKey.getQualifiers(); this.conversationManager.closeConversation( this.conversationKey.getConversationGroup(), qualifiers.toArray(new Annotation[qualifiers.size()])); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/conversation/InjectableGroupedConversationManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.conversation; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.util.context.ContextualStorage; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.util.Set; @Vetoed class InjectableGroupedConversationManager implements GroupedConversationManager { private transient volatile GroupedConversationManager conversationManager; InjectableGroupedConversationManager(GroupedConversationManager conversationManager) { this.conversationManager = conversationManager; } private GroupedConversationManager getConversationManager() { if (this.conversationManager == null) { this.conversationManager = BeanProvider.getContextualReference(DeltaSpikeContextExtension.class).getConversationContext(); } return conversationManager; } @Override public ContextualStorage closeConversation(Class conversationGroup, Annotation... qualifiers) { return getConversationManager().closeConversation(conversationGroup, qualifiers); } @Override public Set closeConversationGroup(Class conversationGroup) { return getConversationManager().closeConversationGroup(conversationGroup); } @Override public void closeConversations() { getConversationManager().closeConversations(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/InjectableViewAccessContextManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.viewaccess.ViewAccessContextManager; import jakarta.enterprise.inject.Vetoed; @Vetoed class InjectableViewAccessContextManager implements ViewAccessContextManager { private transient volatile ViewAccessContextManager viewAccessContextManager; public InjectableViewAccessContextManager(ViewAccessContextManager viewAccessContextManager) { this.viewAccessContextManager = viewAccessContextManager; } private ViewAccessContextManager getConversationManager() { if (this.viewAccessContextManager == null) { this.viewAccessContextManager = BeanProvider.getContextualReference(DeltaSpikeContextExtension.class).getViewAccessScopedContext(); } return this.viewAccessContextManager; } @Override public void close() { getConversationManager().close(); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/ViewAccessBeanAccessHistory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import java.util.ArrayList; import java.util.List; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class ViewAccessBeanAccessHistory { private final List accessedBeans = new ArrayList(); public List getAccessedBeans() { return accessedBeans; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/ViewAccessBeanHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.core.impl.scope.AbstractBeanHolder; @WindowScoped public class ViewAccessBeanHolder extends AbstractBeanHolder { private static final long serialVersionUID = 6313403410718143908L; } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/ViewAccessContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; import org.apache.deltaspike.core.impl.scope.window.WindowContextImpl; import org.apache.deltaspike.core.spi.scope.viewaccess.ViewAccessContextManager; import org.apache.deltaspike.core.util.context.AbstractContext; import org.apache.deltaspike.core.util.context.ContextualInstanceInfo; import org.apache.deltaspike.core.util.context.ContextualStorage; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.PassivationCapable; import java.lang.annotation.Annotation; import java.util.Map; @Vetoed public class ViewAccessContext extends AbstractContext implements ViewAccessContextManager { private static final String KEY = "VAS"; //TODO re-visit key (e.g. view-id instead of using one big storage) private final BeanManager beanManager; private final WindowContextImpl windowContext; private ViewAccessBeanHolder viewAccessBeanHolder; private ViewAccessBeanAccessHistory viewAccessBeanAccessHistory; private ViewAccessViewHistory viewAccessViewHistory; public ViewAccessContext(BeanManager beanManager, WindowContextImpl windowContext) { super(beanManager); this.beanManager = beanManager; this.windowContext = windowContext; } public void init(ViewAccessBeanHolder viewAccessBeanHolder, ViewAccessBeanAccessHistory viewAccessBeanAccessHistory, ViewAccessViewHistory viewAccessViewHistory) { this.viewAccessBeanHolder = viewAccessBeanHolder; this.viewAccessBeanAccessHistory = viewAccessBeanAccessHistory; this.viewAccessViewHistory = viewAccessViewHistory; } @Override public T get(Contextual bean) { try { return super.get(bean); } finally { if (bean instanceof PassivationCapable) { PassivationCapable pc = (PassivationCapable) bean; viewAccessBeanAccessHistory.getAccessedBeans().add(pc.getId()); } } } @Override public T get(Contextual bean, CreationalContext creationalContext) { try { return super.get(bean, creationalContext); } finally { if (bean instanceof PassivationCapable) { PassivationCapable pc = (PassivationCapable) bean; viewAccessBeanAccessHistory.getAccessedBeans().add(pc.getId()); } } } @Override protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { return this.viewAccessBeanHolder.getContextualStorage(this.beanManager, KEY, createIfNotExist); } @Override public Class getScope() { return ViewAccessScoped.class; } @Override public boolean isActive() { return this.windowContext.isActive(); //autom. active once a window is active } public void onProcessingViewFinished(String view) { close(view, false); } public void close(String view, boolean force) { // ignore if WindowContext isn't active - our ViewAccessViewHistory is WindowScoped if (!windowContext.isActive()) { return; } // destroy beans only if the view has been changed if (force || !view.equals(viewAccessViewHistory.getLastView())) { viewAccessViewHistory.setLastView(view); destroyExpiredBeans(force); } // clear history after each rendering process viewAccessBeanAccessHistory.getAccessedBeans().clear(); } private void destroyExpiredBeans(boolean force) { ContextualStorage storage = viewAccessBeanHolder.getContextualStorage(beanManager, KEY, false); if (storage != null) { for (Map.Entry> storageEntry : storage.getStorage().entrySet()) { if (force || !viewAccessBeanAccessHistory.getAccessedBeans().contains((String) storageEntry.getKey())) { Contextual bean = storage.getBean(storageEntry.getKey()); AbstractContext.destroyBean(bean, storageEntry.getValue()); storage.getStorage().remove(storageEntry.getKey()); //ok due to ConcurrentHashMap } } } } @Override public void close() { close(null, true); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/ViewAccessContextArtifactProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.viewaccess.ViewAccessContextManager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; @ApplicationScoped public class ViewAccessContextArtifactProducer { @Inject private DeltaSpikeContextExtension deltaSpikeContextExtension; @Produces @Dependent public ViewAccessContextManager getViewAccessContextManager() { return new InjectableViewAccessContextManager(this.deltaSpikeContextExtension.getViewAccessScopedContext()); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/viewaccess/ViewAccessViewHistory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.viewaccess; import java.io.Serializable; import org.apache.deltaspike.core.api.scope.WindowScoped; @WindowScoped public class ViewAccessViewHistory implements Serializable { private static final long serialVersionUID = 8917607910721148527L; private String lastView; public String getLastView() { return lastView; } public void setLastView(String lastView) { this.lastView = lastView; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/DefaultWindowContextQuotaHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.core.spi.scope.window.WindowContextQuotaHandler; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import java.util.Stack; @SessionScoped //could be also dependent-scoped since we only inject it in one session-scoped bean, however, //if users would like to customize the behavior they wouldn't be able to use it (if it would be dependent-scoped) public class DefaultWindowContextQuotaHandler implements WindowContextQuotaHandler { protected int maxWindowContextCount; @Inject private WindowContextQuotaHandlerCache quotaHandlerCache; private Stack windowIdStack = new Stack(); @PostConstruct protected void init() { this.maxWindowContextCount = CoreBaseConfig.ScopeCustomization.WindowRestriction.MAX_COUNT; } public synchronized /*no issue due to session-scoped instance*/ void checkWindowContextQuota(String windowId) { if (windowId == null) { return; } if (this.quotaHandlerCache.cacheWindowId(windowId)) { return; } /* * the following part gets executed only once per request, if the window-id is the same */ if (this.windowIdStack.contains(windowId)) { if (windowIdStack.size() > 1) //don't move it up if there is just one entry { this.windowIdStack.remove(windowId); this.windowIdStack.push(windowId); } } else { this.windowIdStack.push(windowId); if (this.windowIdStack.size() > this.maxWindowContextCount) { String windowIdToRemove = this.windowIdStack.remove(0); //destroy it lazily at the end of the request to avoid an overhead during the request //which might be caused by pre-destroy logic of window-scoped beans this.quotaHandlerCache.setWindowIdToDestroy(windowIdToRemove); } } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/InjectableWindowContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import jakarta.enterprise.inject.Vetoed; //keep it public for supporting #{dsWindowContext.getCurrentWindowId()} in addition to //#{dsWindowContext.currentWindowId} @Vetoed public class InjectableWindowContext implements WindowContext { private static final long serialVersionUID = -3606786361833889628L; private transient volatile WindowContext windowContext; InjectableWindowContext(WindowContext windowContext) { this.windowContext = windowContext; } private WindowContext getWindowContext() { if (this.windowContext == null) { this.windowContext = BeanProvider.getContextualReference(DeltaSpikeContextExtension.class).getWindowContext(); } return this.windowContext; } @Override public String getCurrentWindowId() { return getWindowContext().getCurrentWindowId(); } @Override public void activateWindow(String windowId) { getWindowContext().activateWindow(windowId); } @Override public boolean closeWindow(String windowId) { return getWindowContext().closeWindow(windowId); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowBeanHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import org.apache.deltaspike.core.impl.scope.AbstractBeanHolder; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.scope.window.WindowContextQuotaHandler; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.core.util.context.ContextualStorage; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; /** * This holder will store the window Ids and it's beans for the current * HTTP Session. We use standard SessionScoped bean to not need * to treat async-supported and similar headache. */ @SessionScoped public class WindowBeanHolder extends AbstractBeanHolder { private static final long serialVersionUID = 6313493410718133308L; @Inject private WindowContextQuotaHandler windowContextQuotaHandler; private boolean windowContextQuotaHandlerEnabled; @PostConstruct protected void init() { Class windowContextQuotaHandlerClass = ProxyUtils.getUnproxiedClass(windowContextQuotaHandler.getClass()); this.windowContextQuotaHandlerEnabled = ClassDeactivationUtils.isActivated(windowContextQuotaHandlerClass); } @Override public ContextualStorage getContextualStorage(BeanManager beanManager, String key, boolean createIfNotExist) { ContextualStorage result = super.getContextualStorage(beanManager, key, createIfNotExist); if (this.windowContextQuotaHandlerEnabled) { //only check it once the storage was created successfully this.windowContextQuotaHandler.checkWindowContextQuota(key); } return result; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowContextImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.core.util.context.AbstractContext; import org.apache.deltaspike.core.util.context.ContextualStorage; /** * CDI Context to handle @{@link WindowScoped} beans. * This also implements the interface to control the id of * the currently active 'window' (e.g. a web browser tab). */ @Vetoed public class WindowContextImpl extends AbstractContext implements WindowContext { /** * Holds the currently active windowId of each Request */ private WindowIdHolder windowIdHolder; /** * Contains the stored WindowScoped contextual instances. */ private WindowBeanHolder windowBeanHolder; /** * needed for serialisation and passivationId */ private BeanManager beanManager; public WindowContextImpl(BeanManager beanManager) { super(beanManager); this.beanManager = beanManager; } /** * We need to pass the session scoped windowbean holder and the * requestscoped windowIdHolder in a later phase because * getBeans is only allowed from AfterDeploymentValidation onwards. */ public void init(WindowBeanHolder windowBeanHolder, WindowIdHolder windowIdHolder) { this.windowBeanHolder = windowBeanHolder; this.windowIdHolder = windowIdHolder; } @Override public void activateWindow(String windowId) { windowIdHolder.setWindowId(windowId); } @Override public String getCurrentWindowId() { if (windowIdHolder == null) { return null; } return windowIdHolder.getWindowId(); } @Override public boolean closeWindow(String windowId) { if (windowId == null) { return false; } ContextualStorage windowStorage = windowBeanHolder.getStorageMap().remove(windowId); if (windowStorage != null) { if (windowId.equals(this.windowIdHolder.getWindowId())) { this.windowIdHolder.setWindowId(null); } AbstractContext.destroyAllActive(windowStorage); } return windowStorage != null; } @Override protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExist) { String windowId = getCurrentWindowId(); if (windowId == null) { throw new ContextNotActiveException("WindowContext: no windowId set for the current Thread yet!"); } return windowBeanHolder.getContextualStorage(beanManager, windowId, createIfNotExist); } @Override public Class getScope() { return WindowScoped.class; } /** * The WindowContext is active once a current windowId is set for the current Thread. * @return */ @Override public boolean isActive() { String windowId = getCurrentWindowId(); return windowId != null; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowContextProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import jakarta.inject.Named; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.window.WindowContext; /** * This producer provides access to the internally created * {@link WindowContext} implementation. * It simply wraps through to the instance used in the * {@link org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension}. */ @ApplicationScoped public class WindowContextProducer { @Inject private DeltaSpikeContextExtension deltaSpikeContextExtension; @Produces @Named("dsWindowContext") @Dependent public WindowContext getWindowContext() { return new InjectableWindowContext(deltaSpikeContextExtension.getWindowContext()); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowContextQuotaHandlerCache.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import java.io.Serializable; @RequestScoped public class WindowContextQuotaHandlerCache implements Serializable { private String checkedWindowId; private String windowIdToRemove; @Inject private WindowContext windowContext; /** * @param currentWindowId window-id which gets processed right now * @return true if the previously checked window-id is the same, false otherwise */ public boolean cacheWindowId(String currentWindowId) { boolean result = currentWindowId.equals(this.checkedWindowId); this.checkedWindowId = currentWindowId; return result; } public void setWindowIdToDestroy(String windowIdToRemove) { this.windowIdToRemove = windowIdToRemove; } @PreDestroy public void cleanup() { if (this.windowIdToRemove != null) { this.windowContext.closeWindow(this.windowIdToRemove); } } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/scope/window/WindowIdHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.scope.window; import jakarta.enterprise.context.RequestScoped; /** * Simple class which just provides a @RequestScoped windowId. * This assures that there is maximum one single windowId associated * with a single Thread or Request. We use @RequestScoped because * this also works in async-supported Servlets without having to * take care about moving info between ThreadLocals. */ @RequestScoped public class WindowIdHolder { private String windowId; /** * @return the detected windowId or null if not yet set. */ public String getWindowId() { return windowId; } /** * Set the windowId for the current thread. * @param windowId */ public void setWindowId(String windowId) { this.windowId = windowId; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/throttling/DefaultThrottledStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.throttling; import org.apache.deltaspike.core.spi.throttling.ThrottledStrategy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; @Dependent public class DefaultThrottledStrategy implements ThrottledStrategy { @Inject private InvokerStorage metadata; @Override public Object execute(InvocationContext ic) throws Exception { return metadata.getOrCreateInvoker(ic).invoke(ic); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/throttling/Invoker.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.throttling; import org.apache.deltaspike.core.util.ExceptionUtils; import jakarta.interceptor.InvocationContext; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; class Invoker { private final int weight; private final Semaphore semaphore; private final long timeout; Invoker(final Semaphore semaphore, final int weight, final long timeout) { this.semaphore = semaphore; this.weight = weight; this.timeout = timeout; } public Object invoke(final InvocationContext context) throws Exception { if (timeout > 0) { try { if (!semaphore.tryAcquire(weight, timeout, TimeUnit.MILLISECONDS)) { throw new IllegalStateException( "Can't acquire " + weight + " permits for " + context.getMethod() + " in " + timeout + "ms"); } } catch (final InterruptedException e) { return onInterruption(e); } } else { try { semaphore.acquire(weight); } catch (final InterruptedException e) { return onInterruption(e); } } try { return context.proceed(); } finally { semaphore.release(weight); } } private static Semaphore onInterruption(final InterruptedException e) { Thread.interrupted(); throw ExceptionUtils.throwAsRuntimeException(e); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/throttling/InvokerStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.throttling; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.throttling.Throttled; import org.apache.deltaspike.core.api.throttling.Throttling; import org.apache.deltaspike.core.impl.util.AnnotatedMethods; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.lang.reflect.Method; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Semaphore; @ApplicationScoped @Typed(InvokerStorage.class) public class InvokerStorage implements Throttling.SemaphoreFactory { private final ConcurrentMap semaphores = new ConcurrentHashMap(); private final ConcurrentMap providers = new ConcurrentHashMap(); @Inject private BeanManager beanManager; Invoker getOrCreateInvoker(final InvocationContext ic) { final Method method = ic.getMethod(); Invoker i = providers.get(method); if (i == null) { final Class declaringClass = method.getDeclaringClass(); final AnnotatedType annotatedType = beanManager.createAnnotatedType(declaringClass); final AnnotatedMethod annotatedMethod = AnnotatedMethods.findMethod(annotatedType, method); Throttled config = annotatedMethod.getAnnotation(Throttled.class); if (config == null) { config = annotatedType.getAnnotation(Throttled.class); } Throttling sharedConfig = annotatedMethod.getAnnotation(Throttling.class); if (sharedConfig == null) { sharedConfig = annotatedType.getAnnotation(Throttling.class); } final Throttling.SemaphoreFactory factory = sharedConfig != null && sharedConfig.factory() != Throttling.SemaphoreFactory.class ? Throttling.SemaphoreFactory.class.cast( beanManager.getReference(beanManager.resolve( beanManager.getBeans( sharedConfig.factory())), Throttling.SemaphoreFactory.class, null)) : this; final Semaphore semaphore = factory.newSemaphore( annotatedMethod, sharedConfig != null && !sharedConfig.name().isEmpty() ? sharedConfig.name() : declaringClass.getName(), sharedConfig != null && sharedConfig.fair(), sharedConfig != null ? sharedConfig.permits() : 1); final long timeout = config.timeoutUnit().toMillis(config.timeout()); final int weigth = config.weight(); i = new Invoker(semaphore, weigth, timeout); final Invoker existing = providers.putIfAbsent(ic.getMethod(), i); if (existing != null) { i = existing; } } return i; } @Override public Semaphore newSemaphore(final AnnotatedMethod method, final String name, final boolean fair, final int permits) { Semaphore semaphore = semaphores.get(name); if (semaphore == null) { semaphore = new Semaphore(permits, fair); final Semaphore existing = semaphores.putIfAbsent(name, semaphore); if (existing != null) { semaphore = existing; } } return semaphore; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/throttling/ThrottledInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.throttling; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.throttling.Throttled; import org.apache.deltaspike.core.spi.throttling.ThrottledStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @Throttled @Interceptor @Priority(1000) public class ThrottledInterceptor implements Serializable { @Inject private ThrottledStrategy throttledStrategy; @AroundInvoke public Object invoke(final InvocationContext ic) throws Exception { return throttledStrategy.execute(ic); } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/AnnotatedMethods.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.util; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import java.lang.reflect.Method; public final class AnnotatedMethods { private AnnotatedMethods() { // no-op } public static AnnotatedMethod findMethod(final AnnotatedType type, final Method method) { AnnotatedMethod annotatedMethod = null; for (final AnnotatedMethod am : type.getMethods()) { if (am.getJavaMember().equals(method)) { annotatedMethod = am; break; } } if (annotatedMethod == null) { throw new IllegalStateException("No annotated method for " + method); } return annotatedMethod; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/ConversationUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.util; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.ConversationSubGroup; import org.apache.deltaspike.core.impl.scope.conversation.ConversationKey; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.PassivationCapable; import java.lang.annotation.Annotation; import java.util.Set; @Vetoed public abstract class ConversationUtils { private ConversationUtils() { } public static ConversationKey convertToConversationKey(Contextual contextual, BeanManager beanManager) { if (!(contextual instanceof Bean)) { if (contextual instanceof PassivationCapable) { contextual = beanManager.getPassivationCapableBean(((PassivationCapable) contextual).getId()); } else { throw new IllegalArgumentException( contextual.getClass().getName() + " is not of type " + Bean.class.getName()); } } Bean bean = (Bean) contextual; //don't cache it (due to the support of different producers) ConversationGroup conversationGroupAnnotation = findConversationGroupAnnotation(bean); Class conversationGroup; if (conversationGroupAnnotation != null) { conversationGroup = conversationGroupAnnotation.value(); } else { conversationGroup = bean.getBeanClass(); } Set qualifiers = bean.getQualifiers(); return new ConversationKey(conversationGroup, qualifiers.toArray(new Annotation[qualifiers.size()])); } private static ConversationGroup findConversationGroupAnnotation(Bean bean) { Set qualifiers = bean.getQualifiers(); for (Annotation qualifier : qualifiers) { if (ConversationGroup.class.isAssignableFrom(qualifier.annotationType())) { return (ConversationGroup) qualifier; } } return null; } public static Class getDeclaredConversationGroup(Class conversationGroup) { ConversationSubGroup conversationSubGroup = conversationGroup.getAnnotation(ConversationSubGroup.class); if (conversationSubGroup == null) { return conversationGroup; } Class result = conversationSubGroup.of(); if (!ConversationSubGroup.class.equals(result)) { return result; } result = conversationGroup.getSuperclass(); if ((result == null || Object.class.getName().equals(result.getName())) && conversationGroup.getInterfaces().length == 1) { return conversationGroup.getInterfaces()[0]; } if (result == null) { //TODO move validation to the bootstrapping process throw new IllegalStateException(conversationGroup.getName() + " hosts an invalid usage of @" + ConversationSubGroup.class.getName()); } return result; } } ================================================ FILE: deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/util/JndiUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.core.impl.util; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.inject.Vetoed; import javax.naming.InitialContext; import javax.naming.Name; import javax.naming.NameClassPair; import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; /** * This is the internal helper class for low level access to JNDI */ @Vetoed public abstract class JndiUtils { private static final Logger LOG = Logger.getLogger(JndiUtils.class.getName()); private static InitialContext initialContext = null; static { try { initialContext = new InitialContext(); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } private JndiUtils() { // prevent instantiation } /** * Resolves an instance for the given name. * * @param name current name * @param targetType target type * @param type * @return the found instance, null otherwise */ public static T lookup(Name name, Class targetType) { try { return verifyLookupResult(initialContext.lookup(name), name.toString(), targetType); } catch (NamingException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } /** * Resolves an instance for the given name. * * @param name current name * @param targetType target type * @param type * @return the found instance, null otherwise */ public static T lookup(String name, Class targetType) { try { return verifyLookupResult(initialContext.lookup(name), name, targetType); } catch (NamingException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } /** * Does a checks on given instance looked up previously from JNDI. * * @param name current name * @param targetType target type * @param type * @return the found instance, null otherwise */ @SuppressWarnings("unchecked") private static T verifyLookupResult(Object result, String name, Class targetType) { if (result != null) { if (targetType.isAssignableFrom(result.getClass())) { // we have a value and the type fits return (T) result; } else if (result instanceof String) //but the target type != String { // lookedUp might be a class name try { Class classOfResult = ClassUtils.loadClassForName((String) result); if (targetType.isAssignableFrom(classOfResult)) { try { return (T) classOfResult.newInstance(); } catch (Exception e) { // could not create instance LOG.log(Level.SEVERE, "Class " + classOfResult + " from JNDI lookup for name " + name + " could not be instantiated", e); } } else { // lookedUpClass does not extend/implement expectedClass LOG.log(Level.SEVERE, "JNDI lookup for key " + name + " returned class " + classOfResult.getName() + " which does not implement/extend the expected class" + targetType.getName()); } } catch (ClassNotFoundException cnfe) { // could not find class LOG.log(Level.SEVERE, "Could not find Class " + result + " from JNDI lookup for name " + name, cnfe); } } else { // we have a value, but the value does not fit LOG.log(Level.SEVERE, "JNDI lookup for key " + name + " should return a value of " + targetType + ", but returned " + result); } } return null; } /** * Resolves an instances for the given naming context. * * @param name context name * @param type target type * @param type * @return the found instances, null otherwise */ public static Map list(String name, Class type) { Map result = new HashMap(); try { NameParser nameParser = initialContext.getNameParser(name); NamingEnumeration enumeration = initialContext.list(name); while (enumeration.hasMoreElements()) { try { NameClassPair binding = enumeration.nextElement(); Name bindingName = nameParser.parse(name).add(binding.getName()); result.put(binding.getName(), lookup(bindingName, type)); } catch (NamingException e) { if (LOG.isLoggable(Level.FINEST)) { // this is expected if there is no entry in JNDI for the requested name or type // so finest level is ok, if devs want to see it they can enable this logger level. LOG.log(Level.FINEST, "InitialContext#list failed!", e); } } } } catch (NamingException e) { // this is fine at this point, since the individual lines will be caught currently. LOG.log(Level.WARNING,"Problem reading the name of the JNDI location " + name + " or failuring listing pairs.",e); } return result; } } ================================================ FILE: deltaspike/core/impl/src/main/resources/META-INF/MANIFEST.MF ================================================ Main-Class: org.apache.deltaspike.core.impl.crypto.CipherCli Bundle-License: https://www.apache.org/licenses/LICENSE-2.0.txt ================================================ FILE: deltaspike/core/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/core/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.core.impl.exclude.extension.ExcludeExtension org.apache.deltaspike.core.impl.message.MessageBundleExtension org.apache.deltaspike.core.impl.config.ConfigurationExtension org.apache.deltaspike.core.impl.jmx.MBeanExtension org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension org.apache.deltaspike.core.impl.interceptor.interdyn.InterDynExtension ================================================ FILE: deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.api.config.ConfigResolver$ConfigProvider ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.core.impl.config.ConfigProviderImpl ================================================ FILE: deltaspike/core/impl/src/main/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.core.impl.config.DefaultConfigSourceProvider ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/BeanConfigResolverTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import java.util.function.BiFunction; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.test.core.api.config.beans.ServerEndpointPojoWithCt; import org.apache.deltaspike.test.core.api.config.beans.ServerEndpointPojoWithFields; import org.junit.Assert; import org.junit.Test; public class BeanConfigResolverTest { @Test public void testBeanConverterConfig() { final BiFunction serverBeanConverter = (cfg, path) -> new ServerEndpointPojoWithCt( cfg.resolve(path + "host").getValue(), cfg.resolve(path + "port").as(Integer.class).getValue(), cfg.resolve(path + "path").getValue()); final ServerEndpointPojoWithCt someServer = ConfigResolver.resolve("myapp.some.server") .asBean(ServerEndpointPojoWithCt.class, serverBeanConverter) .getValue(); Assert.assertNotNull(someServer); Assert.assertEquals("http://myserver:80/myapp/endpoint1", someServer.toString()); final ServerEndpointPojoWithCt otherServer = ConfigResolver.resolve("myapp.other.server") .asBean(ServerEndpointPojoWithCt.class, serverBeanConverter) .getValue(); Assert.assertNotNull(otherServer); Assert.assertEquals("https://otherserver:443/otherapp/endpoint2", otherServer.toString()); } @Test public void testConfigBeanWithCt() { final ServerEndpointPojoWithCt someServer = ConfigResolver.resolve("myapp.some.server") .asBean(ServerEndpointPojoWithCt.class) .getValue(); Assert.assertNotNull(someServer); Assert.assertEquals("http://myserver:80/myapp/endpoint1", someServer.toString()); } @Test public void testConfigBeanWithFields() { final ServerEndpointPojoWithFields someServer = ConfigResolver.resolve("myapp.some.server") .asBean(ServerEndpointPojoWithFields.class) .getValue(); Assert.assertNotNull(someServer); Assert.assertEquals("http://myserver:80/myapp/endpoint1", someServer.toString()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigHelperTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.junit.Assert; import org.junit.Test; import java.util.HashMap; import java.util.Map; import java.util.Set; public class ConfigHelperTest { @Test public void testDiffConfig() { ConfigResolver.ConfigHelper cfgHelper = ConfigResolver.getConfigProvider().getHelper(); Map oldVal = new HashMap<>(); Map newVal = new HashMap<>(); oldVal.put("a", "1"); newVal.put("b", "2"); newVal.put("a", "1"); assertAll(cfgHelper.diffConfig(null, newVal), "a", "b"); assertAll(cfgHelper.diffConfig(oldVal, null), "a"); assertAll(cfgHelper.diffConfig(oldVal, newVal), "b"); assertAll(cfgHelper.diffConfig(oldVal, oldVal)); assertAll(cfgHelper.diffConfig(newVal, newVal)); newVal.put("a", "5"); assertAll(cfgHelper.diffConfig(oldVal, newVal), "a", "b"); } private void assertAll(Set actualVals, String... expectedVals) { Assert.assertNotNull(actualVals); Assert.assertEquals(expectedVals.length, actualVals.size()); for (String expectedVal : expectedVals) { Assert.assertTrue(actualVals.contains(expectedVal)); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.config.ConfigFilter; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiFunction; @SuppressWarnings("Duplicates") public class ConfigResolverTest { private static final String DEFAULT_VALUE = "defaultValue"; @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void testOverruledValue() { String result = ConfigResolver.getPropertyValue("test"); Assert.assertEquals("test2", result); } @Test public void testOrderOfAllValues() { List result = ConfigResolver.getAllPropertyValues("test"); Assert.assertEquals(2, result.size()); Assert.assertEquals("test1", result.get(0)); Assert.assertEquals("test2", result.get(1)); } @Test public void testStandaloneConfigSource() { Assert.assertNull(ConfigResolver.getPropertyValue("notexisting")); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey")); } @Test public void testGetProjectStageAwarePropertyValue() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); Assert.assertNull(ConfigResolver.getProjectStageAwarePropertyValue("notexisting", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3")); Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("testkey3")); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("testkey3", DEFAULT_VALUE)); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback", DEFAULT_VALUE)); Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("deltaspike.test.projectstagefallback")); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withDefault(DEFAULT_VALUE).withCurrentProjectStage(true).getValue()); Assert.assertEquals("", ConfigResolver.resolve("deltaspike.test.projectstagefallback").as(String.class).withCurrentProjectStage(true).getValue()); } @Test public void testGetPropertyAwarePropertyValue() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); Assert.assertNull(ConfigResolver.getPropertyAwarePropertyValue("notexisting", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor")); Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor")); Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor", null)); Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3")); Assert.assertEquals("", ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor")); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor", DEFAULT_VALUE)); Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor")); Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2")); Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX")); Assert.assertEquals("TestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor", null)); Assert.assertEquals("PostgreDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendor2", null)); Assert.assertEquals("UnitTestDataSource", ConfigResolver.getPropertyAwarePropertyValue("dataSource", "dbvendorX", null)); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("dataSourceX", "dbvendorX", DEFAULT_VALUE)); } @Test public void testConfigFilter() { ConfigFilter configFilter = new TestConfigFilter(); Assert.assertEquals("shouldGetDecrypted: value", configFilter.filterValue("somekey.encrypted", "value")); Assert.assertEquals("**********", configFilter.filterValueForLog("somekey.password", "value")); ConfigResolver.addConfigFilter(configFilter); Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyValue("testkey4.encrypted")); Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted")); Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getProjectStageAwarePropertyValue("testkey4.encrypted", null)); Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor")); Assert.assertEquals("shouldGetDecrypted: value", ConfigResolver.getPropertyAwarePropertyValue("testkey4.encrypted", "dbvendor", null)); List allPropertyValues = ConfigResolver.getAllPropertyValues("testkey4.encrypted"); Assert.assertNotNull(allPropertyValues); Assert.assertEquals(1, allPropertyValues.size()); Assert.assertEquals("shouldGetDecrypted: value", allPropertyValues.get(0)); } @Test public void testGetConfigFilter() { // make sure no ConfigFilter is left over from previous tests ConfigResolver.getConfigProvider().releaseConfig(ClassUtils.getClassLoader(null)); List configFilters = ConfigResolver.getConfigFilters(); Assert.assertNotNull(configFilters); Assert.assertEquals(1, configFilters.size()); Assert.assertEquals(SecretTestConfigFilter.class, configFilters.get(0).getClass()); } @Test public void testConfigVariableReplacement() { { String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", "", true); Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url); } { String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true); Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url); } } @Test public void testConfigVariableReplacementInDefault() { { String url = ConfigResolver.getPropertyValue("deltaspike.test.notexisting", "url: ${deltaspike.test.host.url}", true); Assert.assertEquals("url: http://localhost:12345", url); } { String url = ConfigResolver.getPropertyValue("deltaspike.test.someapp.soap.endpoint", true); Assert.assertEquals("http://localhost:12345/someservice/myendpoint", url); } } @Test public void testConfigVariableNotExisting() { { String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", "", true); Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url); } { String url = ConfigResolver.getPropertyValue("deltaspike.test.nonexisting.variable", true); Assert.assertEquals("${does.not.exist}/someservice/myendpoint", url); } } @Test public void testConfigVariableRecursiveDeclaration() { String url = ConfigResolver.getPropertyValue("deltaspike.test.recursive.variable1", "", true); Assert.assertEquals("pre-crazy-post/ohgosh/crazy", url); ConfigResolver.TypedResolver tr = ConfigResolver.resolve("deltaspike.test.recursive.variable1") .evaluateVariables(true).logChanges(true); Assert.assertEquals("pre-crazy-post/ohgosh/crazy", tr.getValue()); } @Test public void testTypedResolver_NonExistingValue() { final String key = "non.existing.key"; ConfigResolver.TypedResolver resolver = ConfigResolver.resolve(key) .logChanges(true); Assert.assertNull(resolver.getValue()); setTestConfigSourceValue(key, "somevalue"); Assert.assertEquals("somevalue", resolver.getValue()); setTestConfigSourceValue(key, null); Assert.assertNull(resolver.getValue()); } @Test public void testTypedResolver_OnChange() { final String key = "non.existing.key"; final AtomicInteger valueChanged = new AtomicInteger(0); ConfigResolver.TypedResolver resolver = ConfigResolver.resolve(key) .logChanges(true) .onChange((k, oldValue, newValue) -> { Assert.assertEquals(key, k); valueChanged.incrementAndGet(); }); Assert.assertNull(resolver.getValue()); setTestConfigSourceValue(key, "somevalue"); Assert.assertEquals("somevalue", resolver.getValue()); Assert.assertEquals(1, valueChanged.get()); setTestConfigSourceValue(key, "newvalue"); Assert.assertEquals("newvalue", resolver.getValue()); Assert.assertEquals(2, valueChanged.get()); // this time we do not change anything Assert.assertEquals("newvalue", resolver.getValue()); Assert.assertEquals(2, valueChanged.get()); // last change setTestConfigSourceValue(key, null); Assert.assertNull(resolver.getValue()); Assert.assertEquals(3, valueChanged.get()); } @Test public void testProjectStageAwarePropertyValueReference_1() { final String expectedFooUrl = "http://bar-dev/services"; final String actualFooUrl = ConfigResolver.getProjectStageAwarePropertyValue( "foo.url"); Assert.assertEquals(expectedFooUrl, actualFooUrl); } @Test public void testProjectStageAwarePropertyValueReference_2() { final String expected = "projectStageAware-exampleEntry-1-is-tomato-UnitTest"; final String projectStageAwareExampleEntry1 = ConfigResolver.getProjectStageAwarePropertyValue( "deltaspike.test.exampleEntry-2", ""); Assert.assertEquals(expected, projectStageAwareExampleEntry1); } @Test public void testConfiguredListValues_WithWhitespace() { List emails = ConfigResolver.resolve("test.list.value.emails").asList().getValue(); Assert.assertNotNull(emails); Assert.assertEquals(3, emails.size()); Assert.assertTrue(emails.contains("test1@apache.org")); Assert.assertTrue(emails.contains("test2@apache.org")); Assert.assertTrue(emails.contains("test3@apache.org")); } @Test public void testConfiguredListValues_WithEscaping() { List escapedValues = ConfigResolver.resolve("test.list.value.escaped.list").asList().getValue(); Assert.assertNotNull(escapedValues); Assert.assertEquals(3, escapedValues.size()); Assert.assertTrue(escapedValues.contains("val,ue1")); Assert.assertTrue(escapedValues.contains("value2")); Assert.assertTrue(escapedValues.contains("val\\ue3")); } @Test public void testConfiguredListValues_OtherType() { List intValues = ConfigResolver.resolve("test.list.intvalues").as(Integer.class).asList().getValue(); Assert.assertNotNull(intValues); Assert.assertEquals(4, intValues.size()); Assert.assertTrue(intValues.contains(3)); Assert.assertTrue(intValues.contains(7)); Assert.assertTrue(intValues.contains(11)); Assert.assertTrue(intValues.contains(17)); } @Test public void testConfiguredListValues_NotExisting() { List intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().getValue(); Assert.assertNotNull(intValues); Assert.assertEquals(0, intValues.size()); } @Test public void testConfiguredListValues_WithDefault() { List intValues = ConfigResolver.resolve("test.list.not_existing").as(Integer.class).asList().withDefault(Arrays.asList(99, 88, 77)).getValue(); Assert.assertNotNull(intValues); Assert.assertEquals(3, intValues.size()); Assert.assertTrue(intValues.contains(99)); Assert.assertTrue(intValues.contains(88)); Assert.assertTrue(intValues.contains(77)); } private void setTestConfigSourceValue(String key, String value) { ConfigSource[] configSources = ConfigResolver.getConfigSources(); for (ConfigSource configSource : configSources) { if (configSource instanceof TestConfigSource) { if (value == null) { configSource.getProperties().remove(key); } else { configSource.getProperties().put(key, value); } break; } } } public static class TestConfigFilter implements ConfigFilter { @Override public String filterValue(String key, String value) { if (key.contains("encrypted")) { return "shouldGetDecrypted: " + value; } return value; } @Override public String filterValueForLog(String key, String value) { if (key.contains("password")) { return "**********"; } return value; } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigSnapshotTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import java.util.HashMap; import java.util.Map; import org.apache.deltaspike.core.api.config.Config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.ConfigSnapshot; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class ConfigSnapshotTest { private static final String HOST_KEY = "ds.test.myapp.host"; private static final String PORT1_KEY = "ds.test.myapp.port1"; private static final String PORT2_KEY = "ds.test.myapp.port2"; private ConfigResolver.TypedResolver hostCfg; private ConfigResolver.TypedResolver port1Cfg; private ConfigResolver.TypedResolver port2Cfg; @Test public void testConfigTx() { Config cfg = ConfigResolver.getConfig(); ConfigurableTestConfigSource configSource = ConfigurableTestConfigSource.instance(); try { Map newVals = new HashMap<>(); newVals.put(HOST_KEY, "host1"); newVals.put(PORT1_KEY, "1"); newVals.put(PORT2_KEY, "1"); configSource.setValues(newVals); hostCfg = cfg.resolve(HOST_KEY); port1Cfg = cfg.resolve(PORT1_KEY).as(Integer.class); port2Cfg = cfg.resolve(PORT2_KEY).as(Integer.class); assertEquals("host1", hostCfg.getValue()); assertEquals(Integer.valueOf(1), port1Cfg.getValue()); assertEquals(Integer.valueOf(1), port2Cfg.getValue()); ConfigSnapshot configSnapshot = cfg.snapshotFor(hostCfg, port1Cfg, port2Cfg); assertNotNull(configSnapshot); assertEquals("host1", hostCfg.getValue(configSnapshot)); assertEquals(Integer.valueOf(1), port1Cfg.getValue(configSnapshot)); assertEquals(Integer.valueOf(1), port2Cfg.getValue(configSnapshot)); // and those values don't change, even if we modify the underlying ConfigSource! newVals.clear(); newVals.put(HOST_KEY, "host2"); newVals.put(PORT1_KEY, "2"); newVals.put(PORT2_KEY, "2"); configSource.setValues(newVals); assertEquals("host1", hostCfg.getValue(configSnapshot)); assertEquals(Integer.valueOf(1), port1Cfg.getValue(configSnapshot)); assertEquals(Integer.valueOf(1), port2Cfg.getValue(configSnapshot)); // but the actual config did really change! assertEquals("host2", hostCfg.getValue()); assertEquals(Integer.valueOf(2), port1Cfg.getValue()); assertEquals(Integer.valueOf(2), port2Cfg.getValue()); } finally { configSource.clear(); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigSourceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import java.io.File; import java.io.FileWriter; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; /** * Unit tests for {@link org.apache.deltaspike.core.spi.config.ConfigSource} */ public class ConfigSourceTest { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Test public void testConfigViaSystemProperty() { String key = "testProperty01"; String value = "test_value_01"; // the value is not yet configured String configuredValue = ConfigResolver.getPropertyValue(key); Assert.assertNull(configuredValue); String myDefaultValue = "theDefaultValueDummy"; configuredValue = ConfigResolver.getPropertyValue(key, myDefaultValue); Assert.assertEquals(myDefaultValue, configuredValue); // now we set a value for the config key System.setProperty(key, value); configuredValue = ConfigResolver.getPropertyValue(key); Assert.assertEquals(value, configuredValue); System.setProperty(key, ""); configuredValue = ConfigResolver.getPropertyValue(key); Assert.assertEquals("", configuredValue); } @Test public void testConfigViaClasspathPropertyFile() { String key = "testProperty02"; String value = "test_value_02"; String configuredValue = ConfigResolver.getPropertyValue(key); Assert.assertEquals(value, configuredValue); } @Test public void testConfigUninitializedDefaultValue() { String key = "nonexistingProperty01"; // passing in null as default value should work fine String configuredValue = ConfigResolver.getPropertyValue(key, null); Assert.assertNull(configuredValue); String myDefaultValue = "theDefaultValueDummy"; configuredValue = ConfigResolver.getPropertyValue(key, myDefaultValue); Assert.assertEquals(myDefaultValue, configuredValue); } @Test public void testConfigViaMetaInfPropertyFile() { String key = "testProperty03"; String value = "test_value_03"; String configuredValue = ConfigResolver.getPropertyValue(key); Assert.assertEquals(value, configuredValue); } @Test public void testConfigFilter() { String secretVal = ConfigResolver.getPropertyValue("my.very.secret"); Assert.assertNotNull(secretVal); Assert.assertEquals("a secret value: onlyIDoKnowIt", secretVal); } @Test public void testEnvProperties() { String javaHome = System.getenv("JAVA_HOME"); if (javaHome == null || javaHome.isEmpty()) { // weird, should exist. Anyway, in that case we cannot test it. return; } // we search for JAVA.HOME which should also give us JAVA_HOME String value = ConfigResolver.getPropertyValue("JAVA.HOME"); Assert.assertNotNull(value); Assert.assertEquals(javaHome, value); } @Test public void testUserHomeConfigProperties() throws Exception { String userHomeKey = "user.home"; String oldUserHome = System.getProperty(userHomeKey); try { File newUserHomeFolder = temporaryFolder.newFolder(); System.setProperty(userHomeKey, newUserHomeFolder.getAbsolutePath()); File dsHomeConfig = new File(newUserHomeFolder, ".deltaspike/apache-deltaspike.properties"); dsHomeConfig.getParentFile().mkdirs(); FileWriter fw = new FileWriter(dsHomeConfig); fw.write("ds.test.fromHome=withLove\ndeltaspike_ordinal=123"); fw.close(); // force freshly picking up all ConfigSources for this test ConfigResolver.freeConfigSources(); Assert.assertEquals("withLove", ConfigResolver.getPropertyValue("ds.test.fromHome")); } finally { System.setProperty(userHomeKey, oldUserHome); ConfigResolver.freeConfigSources(); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigurableTestConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.config.ConfigSource; import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; /** * A ConfigSource which is backed by a ThreadLocal. * So it can be dynamically configured even for parallel tests. * * Note that you MUST call the {@link #clear()} method at the end of a method which uses this ConfigSource. */ public class ConfigurableTestConfigSource implements ConfigSource { private static ThreadLocal> props = new ThreadLocal<>(); private Consumer> reportAttributeChange; @Override public int getOrdinal() { return 500; } public static ConfigurableTestConfigSource instance() { return (ConfigurableTestConfigSource) Arrays.stream(ConfigResolver.getConfig().getConfigSources()) .filter(cs -> cs instanceof ConfigurableTestConfigSource) .findFirst() .get(); } @Override public Map getProperties() { Map propMap = props.get(); if (propMap == null) { propMap = new ConcurrentHashMap<>(); props.set(propMap); } return propMap; } @Override public String getPropertyValue(String key) { return getProperties().get(key); } @Override public String getConfigName() { return this.getClass().getSimpleName(); } @Override public boolean isScannable() { return true; } public void clear() { props.set(null); props.remove(); } public void setValues(Map values) { getProperties().putAll(values); // now notify our Config that some values got changed reportAttributeChange.accept(values.keySet()); } @Override public void setOnAttributeChange(Consumer> reportAttributeChange) { this.reportAttributeChange = reportAttributeChange; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/SecretTestConfigFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import org.apache.deltaspike.core.spi.config.ConfigFilter; /** * a test ConfigFilter which decrypts the secret message */ public class SecretTestConfigFilter implements ConfigFilter { @Override public String filterValue(String key, String value) { if (key.contains("secret")) { return "a secret value: " + value; } return value; } @Override public String filterValueForLog(String key, String value) { if (key.contains("secret")) { return "**********"; } return value; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import java.util.HashMap; import java.util.Map; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.test.util.activation.EditableTestDeactivator; /** * Test ConfigSource * * It statically returns 'testvalue' for the key 'testkey' */ public class TestConfigSource implements ConfigSource { private int ordinal = 700; private Map props = new HashMap(); public TestConfigSource() { // a ProjectStage overloaded value props.put("testkey", "testvalue"); props.put("testkey.UnitTest", "unittestvalue"); // a value without any overloading props.put("testkey2", "testvalue"); // a value which got ProjectStage overloaded to an empty value props.put("testkey3", "testvalue"); props.put("testkey3.UnitTest", ""); // now for the PropertyAware tests props.put("dbvendor.UnitTest", "mysql"); props.put("dbvendor", "postgresql"); props.put("dataSource.mysql.Production", "java:/comp/env/MyDs"); props.put("dataSource.mysql.UnitTest", "TestDataSource"); props.put("dataSource.postgresql", "PostgreDataSource"); props.put("dataSource.UnitTest", "UnitTestDataSource"); props.put("dataSource", "DefaultDataSource"); // another one props.put("dbvendor2.Production", "mysql"); props.put("dbvendor2", "postgresql"); props.put("dbvendor3", "h2"); props.put("testkey4.encrypted", "value"); props.put("testkey4.password", "mysecretvalue"); props.put("deltaspike.test.string-value", "configured"); props.put("deltaspike.test.integer-value", "5"); props.put("deltaspike.test.long-value", "8589934592"); props.put("deltaspike.test.float-value", "-1.1"); props.put("deltaspike.test.double-value", "4e40"); props.put("deltaspike.test.boolean-value", Boolean.FALSE.toString()); props.put("deltaspike.test.class-value", TestConfigSource.class.getName()); props.put("deltaspike.test.date-value", "2014-12-24"); props.put("deltaspike.test.invalid-value", "wrong"); props.put("org.apache.deltaspike.core.spi.activation.ClassDeactivator",EditableTestDeactivator.class.getName()); // test for variable replacement props.put("deltaspike.test.host.url", "http://localhost:12345"); props.put("deltaspike.test.someapp.soap.endpoint", "${deltaspike.test.host.url}/someservice/myendpoint"); props.put("deltaspike.test.nonexisting.variable", "${does.not.exist}/someservice/myendpoint"); props.put("deltaspike.test.recursive.variable1", "${deltaspike.test.recursive.variable2}/ohgosh/${deltaspike.test.recursive.variable3}"); props.put("deltaspike.test.recursive.variable2", "pre-${deltaspike.test.recursive.variable3}-post"); props.put("deltaspike.test.recursive.variable3", "crazy"); props.put("deltaspike.test.projectstagefallback.UnitTest", ""); props.put("deltaspike.test.projectstagefallback", "Value without ProjectStage"); // ProjectStage aware property value with resolved reference props.put("foo.url", "${bar.url}/services"); props.put("bar.url", "undefined"); props.put("bar.url.UnitTest", "http://bar-dev"); props.put("bar.url.Production", "http://bar-prod"); props.put("deltaspike.test.exampleEntry-1", "tomato"); props.put("deltaspike.test.exampleEntry-1.UnitTest", "tomato-UnitTest"); props.put("deltaspike.test.exampleEntry-2", "default-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}"); props.put("deltaspike.test.exampleEntry-2.UnitTest", "projectStageAware-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}"); // values for testing the list handling props.put("test.list.value.emails", "test1@apache.org, test2@apache.org, \n test3@apache.org"); props.put("test.list.value.escaped.list","val\\,ue1,value2, val\\\\ue3"); props.put("test.list.intvalues","3,7, 11 ,\t 17\n"); } @Override public String getConfigName() { return "testConfig"; } @Override public int getOrdinal() { return ordinal; } @Override public String getPropertyValue(String key) { return props.get(key); } @Override public Map getProperties() { return props; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TestConfigSourceProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.ConfigSourceProvider; /** * ConfigSourceProvider for basic unit-test */ public class TestConfigSourceProvider implements ConfigSourceProvider { @Override public List getConfigSources() { return Arrays.asList(new TestConfigSource1(), new TestConfigSource2()); } private static class TestConfigSource1 implements ConfigSource { @Override public String getPropertyValue(String key) { if ("test".equals(key)) { return "test1"; } if (ConfigSource.DELTASPIKE_ORDINAL.equals(key)) { return "1"; } return null; } @Override public Map getProperties() { Map map = new HashMap(); map.put("test", "test1"); return map; } @Override public String getConfigName() { return TestConfigSourceProvider.class.getName(); } } private static class TestConfigSource2 implements ConfigSource { @Override public int getOrdinal() { return 2; } @Override public String getPropertyValue(String key) { if ("test".equals(key)) { return "test2"; } return null; } @Override public Map getProperties() { Map map = new HashMap(); map.put("test", "test2"); return map; } @Override public String getConfigName() { return TestConfigSourceProvider.class.getName(); } @Override public boolean isScannable() { return false; } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/TypedResolverTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.Date; import java.util.GregorianCalendar; import java.util.concurrent.TimeUnit; public class TypedResolverTest { @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void testValidTypes() { Assert.assertEquals("configured", ConfigResolver.resolve("deltaspike.test.string-value").getValue()); Assert.assertEquals(Boolean.FALSE, ConfigResolver.resolve("deltaspike.test.boolean-value").as(Boolean.class) .getValue()); Assert.assertEquals(TestConfigSource.class, ConfigResolver.resolve("deltaspike.test.class-value").as(Class .class).getValue()); Assert.assertEquals(5l, (int) ConfigResolver.resolve("deltaspike.test.integer-value").as(Integer.class) .getValue()); Assert.assertEquals(8589934592l, (long) ConfigResolver.resolve("deltaspike.test.long-value").as(Long.class) .getValue()); Assert.assertEquals(-1.1f, (float) ConfigResolver.resolve("deltaspike.test.float-value").as(Float.class) .getValue(), 0); Assert.assertEquals(4e40d, (double) ConfigResolver.resolve("deltaspike.test.double-value").as(Double.class) .getValue(), 0); } @Test public void testConverter() { Assert.assertEquals(new GregorianCalendar(2014, 12, 24).getTime(), ConfigResolver.resolve("deltaspike.test.date-value") .as(Date.class, new TestDateConverter()).getValue()); // test fallback to default Assert.assertEquals(new GregorianCalendar(2015, 01, 01).getTime(), ConfigResolver.resolve("deltaspike.test.INVALID-date-value") .as(Date.class, new TestDateConverter()) .withDefault(new GregorianCalendar(2015, 01, 01).getTime()) .getValue()); } @Test public void testProjectStageAware() { Assert.assertEquals("unittestvalue", ConfigResolver.resolve("testkey") .withCurrentProjectStage(true) .getValue()); Assert.assertEquals("testvalue", ConfigResolver.resolve("testkey") .withCurrentProjectStage(false) .getValue()); // property without PS, with PS-aware Assert.assertEquals("testvalue", ConfigResolver.resolve("testkey2") .withCurrentProjectStage(true) .getValue()); } @Test public void testParameterized() { // param OK, ps OK Assert.assertEquals("TestDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor") .getValue()); // param OK, NO ps Assert.assertEquals("PostgreDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(false) .parameterizedBy("dbvendor") .getValue()); // param doesn't resolve, ps OK Assert.assertEquals("UnitTestDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("INVALIDPARAMETER") .getValue()); // param OK, ps OK, NO base.param.ps, NO base.param, fall back to base.ps Assert.assertEquals("UnitTestDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor3") .getValue()); // param OK, NO ps, base.param undefined, fall back to base Assert.assertEquals("DefaultDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(false) .parameterizedBy("dbvendor3") .getValue()); } @Test public void testDefault() { Assert.assertEquals(10l, (long) ConfigResolver.resolve("INVALIDKEY") .as(Long.class) .withDefault(10l).getValue()); // string default Assert.assertEquals(10l, (long) ConfigResolver.resolve("INVALIDKEY") .as(Long.class) .withStringDefault("10").getValue()); } @Test public void testStrict() { Assert.assertEquals("TestDataSource", ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor") .strictly(true) .getValue()); // no base.param, no value for base.param.ps Assert.assertEquals(null, ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor3") .strictly(true) .getValue()); // valid base.param, but no base.param.ps Assert.assertEquals(null, ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor2") .strictly(true) .getValue()); } @Test public void testGets() { ConfigResolver.TypedResolver resolver = ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor") .withDefault("TESTDEFAULT"); Assert.assertEquals("TestDataSource", resolver.getValue()); Assert.assertEquals("dataSource", resolver.getKey()); Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue()); Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey()); ConfigResolver.TypedResolver resolver2 = ConfigResolver.resolve("testkey2") .withCurrentProjectStage(true) .parameterizedBy("INVALIDPARAMETER"); Assert.assertEquals("testvalue", resolver2.getValue()); Assert.assertEquals("testkey2", resolver2.getResolvedKey()); } @Test public void testWithCacheTime() throws Exception { ConfigResolver.TypedResolver resolver = ConfigResolver.resolve("dataSource") .withCurrentProjectStage(true) .parameterizedBy("dbvendor") .cacheFor(TimeUnit.MILLISECONDS, 5) .withDefault("TESTDEFAULT"); Assert.assertEquals("TestDataSource", resolver.getValue()); Assert.assertEquals("TestDataSource", resolver.getValue()); Assert.assertEquals("dataSource", resolver.getKey()); Assert.assertEquals("TESTDEFAULT", resolver.getDefaultValue()); Assert.assertEquals("dataSource.mysql.UnitTest", resolver.getResolvedKey()); // because the clock steps in certain OS is only 16ms Thread.sleep(35L); Assert.assertEquals("TestDataSource", resolver.getValue()); } public static class TestDateConverter implements ConfigResolver.Converter { @Override public Date convert(String value) { String[] parts = value.split("-"); return new GregorianCalendar(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]), Integer.valueOf(parts[2])).getTime(); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/beans/ServerEndpointPojoWithCt.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.beans; import org.apache.deltaspike.core.api.config.ConfigProperty; /** * @author Mark Struberg */ public class ServerEndpointPojoWithCt extends ServerEndpointPojoWithFields { public ServerEndpointPojoWithCt(@ConfigProperty(name = "host") String host, @ConfigProperty(name = "port") Integer port, @ConfigProperty(name = "path") String path) { this.host = host; this.port = port; this.path = path; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/beans/ServerEndpointPojoWithFields.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.beans; /** * @author Mark Struberg */ public class ServerEndpointPojoWithFields { protected String host; protected Integer port; protected String path; @Override public String toString() { StringBuilder sb = new StringBuilder(); if (host == null) { return "unknown"; } sb.append((port != null && port.equals(443)) ? "https://" : "http://"); sb.append(host); sb.append(port == null ? ":80" : ":" + port); sb.append(path != null ? path : ""); return sb.toString(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/CdiFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.Filter; import org.apache.deltaspike.core.spi.config.ConfigFilter; import jakarta.enterprise.context.ApplicationScoped; @Filter @ApplicationScoped public class CdiFilter implements ConfigFilter { @Override public String filterValue(final String key, final String value) { return "custom-source.test".equals(key) ? new StringBuilder(value).reverse().toString() : value; } @Override public String filterValueForLog(final String key, final String value) { return value; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/CdiSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.Source; import org.apache.deltaspike.core.impl.config.MapConfigSource; import jakarta.enterprise.context.ApplicationScoped; import java.util.HashMap; import java.util.Map; @Source @ApplicationScoped public class CdiSource extends MapConfigSource { public CdiSource() { super(create()); } private static Map create() { final Map map = new HashMap(); map.put("custom-source.test", "eulav"); return map; } @Override public String getConfigName() { return "cdi-test"; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/ConfigBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.Configuration; import java.net.URL; import java.util.List; import java.util.Set; @Configuration public interface ConfigBean { @ConfigProperty(name = "configProperty1") int intProperty1(); @ConfigProperty(name = "configProperty1", defaultValue = "myDefaultValue") String stringProperty3Filled(); @ConfigProperty(name = "nonexistingProperty", defaultValue = "myDefaultValue") String stringProperty3Defaulted(); @ConfigProperty(name = "nonexistingProperty", defaultValue = "42") Integer intProperty4Defaulted(); @ConfigProperty(name = "configProperty1") Boolean booleanPropertyNull(); @ConfigProperty(name = "configProperty1", defaultValue = "false") boolean booleanPropertyFalse(); @ConfigProperty(name = "configPropertyTrue1") Boolean booleanPropertyTrue1(); @ConfigProperty(name = "configPropertyTrue2") Boolean booleanPropertyTrue2(); @ConfigProperty(name = "configPropertyTrue3") Boolean booleanPropertyTrue3(); @ConfigProperty(name = "configPropertyTrue4") Boolean booleanPropertyTrue4(); @ConfigProperty(name = "configPropertyTrue5") Boolean booleanPropertyTrue5(); @ConfigProperty(name = "configPropertyTrue6") Boolean booleanPropertyTrue6(); @ConfigProperty(name = "configPropertyTrue7") Boolean booleanPropertyTrue7(); @ConfigProperty(name = "configPropertyTrue8") Boolean booleanPropertyTrue8(); @ConfigProperty(name = "testDbConfig") String dbConfig(); @ConfigProperty(name = "defaultList", defaultValue = "http://localhost,http://127.0.0.1") List defaultListHandling(); @ConfigProperty(name = "defaultSet", defaultValue = "1,2") Set defaultSetHandling(); @ConfigProperty(name = "urlList", converter = SettingsBean.UrlList.class, defaultValue = "http://localhost,http://127.0.0.1") List urlList(); @ConfigProperty(name = "urlListFromProperties", converter = SettingsBean.UrlList.class) List urlListFromProperties(); @ConfigProperty(name = "custom-source.test") String customSourceValue(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/CustomConfigAnnotationWithMetaData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.ConfigProperty; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; 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.RetentionPolicy.RUNTIME; @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @ConfigProperty(name = "configProperty2") @Qualifier public @interface CustomConfigAnnotationWithMetaData { @Nonbinding boolean inverseConvert() default false; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/CustomConfigAnnotationWithMetaDataProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; /** * Sample producer for {@link CustomConfigAnnotationWithMetaData} */ @ApplicationScoped public class CustomConfigAnnotationWithMetaDataProducer extends BaseConfigPropertyProducer { @Produces @Dependent @CustomConfigAnnotationWithMetaData public Integer produceIntegerCustomConfig(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); if (configuredValue == null || configuredValue.length() == 0) { return 0; } Integer result = Integer.parseInt(configuredValue); CustomConfigAnnotationWithMetaData metaData = getAnnotation(injectionPoint, CustomConfigAnnotationWithMetaData.class); if (metaData != null && metaData.inverseConvert()) { return result * -1; } return result; } @Produces @Dependent @CustomConfigAnnotationWithMetaData public Long produceLongCustomConfig(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); if (configuredValue == null || configuredValue.length() == 0) { return 0L; } Long result = Long.parseLong(configuredValue); CustomConfigAnnotationWithMetaData metaData = getAnnotation(injectionPoint, CustomConfigAnnotationWithMetaData.class); if (metaData != null && metaData.inverseConvert()) { return result * -1L; } return result; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/InjectableConfigPropertyTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import jakarta.inject.Inject; import java.net.MalformedURLException; import java.net.URL; import java.util.HashSet; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.core.api.config.beans.ServerEndpointPojoWithCt; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.apache.deltaspike.test.core.api.config.injectable.numberconfig.NumberConfiguredBean; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @RunWith(Arquillian.class) @Category(SeCategory.class) //X TODO this is only SeCategory as there is currently an Arq problem with properties! public class InjectableConfigPropertyTest { /** *X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() { URL fileUrl = InjectableConfigPropertyTest.class.getClassLoader() .getResource("META-INF/apache-deltaspike.properties"); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "injectableConfigPropertyTest.jar") .addPackage(SettingsBean.class.getPackage()) .addPackage(ServerEndpointPojoWithCt.class.getPackage()) .addPackage(NumberConfiguredBean.class.getPackage()) .addAsManifestResource(FileUtils.getFileForURL(fileUrl.toString())) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "beanProvider.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @ConfigProperty(name = "myapp.some.server", cacheFor = 2, cacheUnit = TimeUnit.SECONDS) private @Inject Supplier someServer; @ConfigProperty(name = "myapp.other.server") private @Inject Supplier otherServer; @Test public void injectBeanViaProvider() { assertNotNull(someServer); final ServerEndpointPojoWithCt server1 = someServer.get(); assertNotNull(server1); Assert.assertEquals("http://myserver:80/myapp/endpoint1", server1.toString()); // once again final ServerEndpointPojoWithCt server2 = someServer.get(); assertNotNull(server2); Assert.assertEquals("http://myserver:80/myapp/endpoint1", server2.toString()); Assert.assertTrue(server1 == server2); assertNotNull(otherServer.get()); Assert.assertEquals("https://otherserver:443/otherapp/endpoint2", otherServer.get().toString()); } @Test public void injectionViaConfigProperty() { SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); assertEquals(14, settingsBean.getProperty1()); assertEquals(7L, settingsBean.getProperty2()); assertEquals(-7L, settingsBean.getInverseProperty2()); // also check the ones with defaultValue assertEquals("14", settingsBean.getProperty3Filled()); assertEquals("myDefaultValue", settingsBean.getProperty3Defaulted()); assertEquals("myDefaultValue", settingsBean.getSupplierStringProperty3Defaulted().get()); assertEquals(42, settingsBean.getProperty4Defaulted()); assertEquals(Integer.valueOf(42), settingsBean.getSupplierIntProperty4Defaulted().get()); assertEquals("some setting for prodDB", settingsBean.getDbConfig()); } @Test public void testBooleanPropertyInjection() { SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); assertEquals(Boolean.FALSE, settingsBean.getBooleanPropertyFalse()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue1()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue2()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue3()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue4()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue5()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue6()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue7()); assertEquals(Boolean.TRUE, settingsBean.getBooleanPropertyTrue8()); } @Test public void testNumberConfigInjection() { NumberConfiguredBean numberBean = BeanProvider.getContextualReference(NumberConfiguredBean.class, false); assertNull(numberBean.getPropertyNonexisting()); assertEquals(Float.valueOf(123.45f), numberBean.getPropertyFromConfig()); assertEquals(Float.valueOf(42.42f), numberBean.getPropertyNonexistingDefaulted()); } @Test public void testProjectStageAwareReplacement() { SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); assertEquals("https://myapp/login.xhtml", settingsBean.getProjectStageAwareVariableValue()); } @Test public void checkDynamicConvertedInjections() throws MalformedURLException { SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); assertEquals(asList(new URL("http://localhost"), new URL("http://127.0.0.1")), settingsBean.getUrlList()); assertEquals(singletonList(new URL("http://127.0.0.2")), settingsBean.getUrlListFromProperties()); } @Test public void checkCdiSourceFilter() throws MalformedURLException { SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); assertEquals("value", settingsBean.getCustomSourceValue()); } @Test public void proxy() throws MalformedURLException { ConfigBean settingsBean = BeanProvider.getContextualReference(ConfigBean.class); assertEquals(14, settingsBean.intProperty1()); assertEquals("14", settingsBean.stringProperty3Filled()); assertEquals("myDefaultValue", settingsBean.stringProperty3Defaulted()); assertEquals(42, settingsBean.intProperty4Defaulted().intValue()); assertEquals("some setting for prodDB", settingsBean.dbConfig()); assertEquals(Boolean.FALSE, settingsBean.booleanPropertyFalse()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue1()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue2()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue3()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue4()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue5()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue6()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue7()); assertEquals(Boolean.TRUE, settingsBean.booleanPropertyTrue8()); assertEquals(asList(new URL("http://localhost"), new URL("http://127.0.0.1")), settingsBean.urlList()); assertEquals(asList("http://localhost", "http://127.0.0.1"), settingsBean.defaultListHandling()); assertEquals(new HashSet(asList(1, 2)), settingsBean.defaultSetHandling()); assertEquals(singletonList(new URL("http://127.0.0.2")), settingsBean.urlListFromProperties()); assertEquals("value", settingsBean.customSourceValue()); } @Test public void proxyPrefix() throws MalformedURLException { PrefixedConfigBean settingsBean = BeanProvider.getContextualReference(PrefixedConfigBean.class); assertEquals("done", settingsBean.value()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/PrefixedConfigBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.Configuration; @Configuration(prefix = "prefix.") public interface PrefixedConfigBean { @ConfigProperty(name = "suffix") String value(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/SettingsBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable; import org.apache.deltaspike.core.api.config.ConfigProperty; import org.apache.deltaspike.core.api.config.ConfigResolver; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; @ApplicationScoped public class SettingsBean { final static String PROPERTY_NAME = "configProperty2"; @Inject @ConfigProperty(name = "configProperty1") private Integer intProperty1; private Long property2; @Inject @ConfigProperty(name = "configProperty1", defaultValue = "myDefaultValue") private String stringProperty3Filled; @Inject @ConfigProperty(name = "nonexistingProperty", defaultValue = "myDefaultValue") private String stringProperty3Defaulted; @Inject @ConfigProperty(name = "nonexistingProperty", defaultValue = "42") private Integer intProperty4Defaulted; @Inject @ConfigProperty(name = "nonexistingProperty", defaultValue = "myDefaultValue", cacheFor = 10, cacheUnit = TimeUnit.MINUTES) private Supplier supplierStringProperty3Defaulted; @Inject @ConfigProperty(name = "nonexistingProperty", defaultValue = "42") private Supplier supplierIntProperty4Defaulted; private Long inverseProperty2; @Inject @ConfigProperty(name = "configProperty1") private Boolean booleanPropertyNull; @Inject @ConfigProperty(name = "configProperty1", defaultValue = "false") private Boolean booleanPropertyFalse; @Inject @ConfigProperty(name = "configPropertyTrue1") private Boolean booleanPropertyTrue1; @Inject @ConfigProperty(name = "configPropertyTrue2") private Boolean booleanPropertyTrue2; @Inject @ConfigProperty(name = "configPropertyTrue3") private Boolean booleanPropertyTrue3; @Inject @ConfigProperty(name = "configPropertyTrue4") private Boolean booleanPropertyTrue4; @Inject @ConfigProperty(name = "configPropertyTrue5") private Boolean booleanPropertyTrue5; @Inject @ConfigProperty(name = "configPropertyTrue6") private Boolean booleanPropertyTrue6; @Inject @ConfigProperty(name = "configPropertyTrue7") private Boolean booleanPropertyTrue7; @Inject @ConfigProperty(name = "configPropertyTrue8") private Boolean booleanPropertyTrue8; @Inject @ConfigProperty(name = "testDbConfig") private String dbConfig; @Inject @ConfigProperty(name = "urlList", converter = UrlList.class, defaultValue = "http://localhost,http://127.0.0.1") private List urlList; @Inject @ConfigProperty(name = "urlListFromProperties", converter = UrlList.class) private List urlListFromProperties; @Inject @ConfigProperty(name = "custom-source.test") private String customSourceValue; @Inject @ConfigProperty(name = "myapp.login.url") private String projectStageAwareVariableValue; protected SettingsBean() { } @Inject public SettingsBean(@ConfigProperty(name= PROPERTY_NAME) Long property2) { this.property2 = property2; } @Inject protected void init(@CustomConfigAnnotationWithMetaData(inverseConvert = true) Long inverseProperty) { inverseProperty2 = inverseProperty; } int getProperty1() { return intProperty1; } long getProperty2() { return property2; } long getInverseProperty2() { return inverseProperty2; } public String getProperty3Defaulted() { return stringProperty3Defaulted; } public String getProperty3Filled() { return stringProperty3Filled; } public int getProperty4Defaulted() { return intProperty4Defaulted; } public Supplier getSupplierStringProperty3Defaulted() { return supplierStringProperty3Defaulted; } public Supplier getSupplierIntProperty4Defaulted() { return supplierIntProperty4Defaulted; } public Boolean getBooleanPropertyNull() { return booleanPropertyNull; } public boolean getBooleanPropertyFalse() { return booleanPropertyFalse; } public Boolean getBooleanPropertyTrue1() { return booleanPropertyTrue1; } public Boolean getBooleanPropertyTrue2() { return booleanPropertyTrue2; } public Boolean getBooleanPropertyTrue3() { return booleanPropertyTrue3; } public Boolean getBooleanPropertyTrue4() { return booleanPropertyTrue4; } public Boolean getBooleanPropertyTrue5() { return booleanPropertyTrue5; } public Boolean getBooleanPropertyTrue6() { return booleanPropertyTrue6; } public Boolean getBooleanPropertyTrue7() { return booleanPropertyTrue7; } public Boolean getBooleanPropertyTrue8() { return booleanPropertyTrue8; } public String getDbConfig() { return dbConfig; } public List getUrlList() { return urlList; } public List getUrlListFromProperties() { return urlListFromProperties; } public String getCustomSourceValue() { return customSourceValue; } public String getProjectStageAwareVariableValue() { return projectStageAwareVariableValue; } public static class UrlList implements ConfigResolver.Converter> { @Override public List convert(final String value) { final List urls = new ArrayList(); if (value != null) { for (final String segment : value.split(",")) { try { urls.add(new URL(segment)); } catch (final MalformedURLException e) { throw new IllegalArgumentException(e); } } } return urls; } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/numberconfig/NumberConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable.numberconfig; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.apache.deltaspike.core.api.config.ConfigProperty; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; 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.RetentionPolicy.RUNTIME; @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @Qualifier public @interface NumberConfig { @Nonbinding String name(); @Nonbinding String defaultValue() default ConfigProperty.NULL; @Nonbinding String pattern() default "#0.00"; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/numberconfig/NumberConfigPropertyProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable.numberconfig; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.ParseException; import java.util.Locale; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; @ApplicationScoped @SuppressWarnings("UnusedDeclaration") public class NumberConfigPropertyProducer extends BaseConfigPropertyProducer { @Produces @Dependent @NumberConfig(name = "unused") public Float produceNumberProperty(InjectionPoint injectionPoint) throws ParseException { // resolve the annotation NumberConfig metaData = getAnnotation(injectionPoint, NumberConfig.class); // get the configured value from the underlying configuration system String configuredValue = getPropertyValue(metaData.name(), metaData.defaultValue()); if (configuredValue == null) { return null; } // format according to the given pattern DecimalFormat df = new DecimalFormat(metaData.pattern(), new DecimalFormatSymbols(Locale.US)); return df.parse(configuredValue).floatValue(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/injectable/numberconfig/NumberConfiguredBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.injectable.numberconfig; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class NumberConfiguredBean { @Inject @NumberConfig(name = "propertyFloat") private Float propertyFromConfig; @Inject @NumberConfig(name = "propertyNonexisting") private Float propertyNonexisting; @Inject @NumberConfig(name = "propertyNonexisting", defaultValue = "42.42") private Float propertyNonexistingDefaulted; protected NumberConfiguredBean() { } public Float getPropertyFromConfig() { return propertyFromConfig; } public Float getPropertyNonexisting() { return propertyNonexisting; } public Float getPropertyNonexistingDefaulted() { return propertyNonexistingDefaulted; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/BaseTestConfigProperty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.util.Collections; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.impl.config.PropertyFileConfigSource; import org.junit.Assert; import org.junit.Test; public class BaseTestConfigProperty { protected final static String CONFIG_FILE_NAME = "myconfig.properties"; protected static final String CONFIG_VALUE = "deltaspike.dynamic.reloadable.config.value"; @Test public void testDynamicReload() throws Exception { File prop = File.createTempFile("deltaspike-test", ".properties"); try (BufferedWriter bw = new BufferedWriter(new FileWriter(prop))) { bw.write(CONFIG_VALUE + "=1\ndeltaspike_reload=1\n"); bw.flush(); } prop.deleteOnExit(); final PropertyFileConfigSource dynamicReloadConfigSource = new PropertyFileConfigSource(prop.toURI().toURL()); ConfigResolver.addConfigSources(Collections.singletonList(dynamicReloadConfigSource)); Assert.assertEquals("1", ConfigResolver.getPropertyValue(CONFIG_VALUE)); // we need to take care of file system granularity Thread.sleep(2100L); try (BufferedWriter bw = new BufferedWriter(new FileWriter(prop))) { bw.write(CONFIG_VALUE + "=2\ndeltaspike_reload=1\n"); bw.flush(); } Assert.assertEquals("2", ConfigResolver.getPropertyValue(CONFIG_VALUE)); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/ConfigPropertyWARTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ConfigPropertyWARTest extends BaseTestConfigProperty { private final static String PROPERTIES = "org.apache.deltaspike.ProjectStage = UnitTest\n" + ConfigResolver.DELTASPIKE_LOG_CONFIG + " = true"; @Deployment public static WebArchive deployEar() { return ShrinkWrap.create(WebArchive.class, "myPropertyTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addPackage(ConfigPropertyWARTest.class.getPackage()) .addAsResource(CONFIG_FILE_NAME) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsWebInfResource(new StringAsset(PROPERTIES), "classes/META-INF/apache-deltaspike.properties"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/FileConfigSourceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Test for picking up a file system based config */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class FileConfigSourceTest { @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "FileConfigSourceTest.jar") .addClasses(FileConfigSourceTest.class, FileSystemConfig.class) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "beanProvider.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test public void testConfig() { String val = ConfigResolver.getPropertyValue("deltaspike.test.config.from.file"); Assert.assertNotNull(val); Assert.assertEquals("it works", val); } public static class FileSystemConfig implements PropertyFileConfig { private final String configFileLocation; /** * This ct is actually only a hack to create a temporary file on the target system * With exactly the content we will later look up. */ public FileSystemConfig() { try { File tempFile = File.createTempFile("deltaspike", ".properties"); FileWriter fw = new FileWriter(tempFile); fw.write("deltaspike.test.config.from.file=it works"); fw.close(); configFileLocation = tempFile.toURI().toURL().toExternalForm(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public String getPropertyFileName() { return configFileLocation; } @Override public boolean isOptional() { return false; } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/MyCustomBootTimePropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Custom PropertyFileConfig which gets picked up via {@code java.util.ServiceLoader} * The values will already be available before the container gets booted! */ @Exclude // this is important to let the ConfigurationExtension know that it should not handle it public class MyCustomBootTimePropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "myboottimeconfig.properties"; } @Override public boolean isOptional() { return false; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/MyCustomEarPropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Custom PropertyFileConfig which gets picked up during * {@link jakarta.enterprise.inject.spi.ProcessAnnotatedType}. * We need to do this hack to avoid */ @Exclude public class MyCustomEarPropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "myconfig.properties"; } @Override public boolean isOptional() { return false; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/MyCustomPropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.PropertyFileConfig; /** * Custom PropertyFileConfig which gets picked up during * {@link jakarta.enterprise.inject.spi.ProcessAnnotatedType}. * The values will be available after the container got booted! */ public class MyCustomPropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "myconfig.properties"; } @Override public boolean isOptional() { return false; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/MyNotPickedUpPropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Custom PropertyFileConfig which gets picked up via {@code java.util.ServiceLoader} * The values will already be available before the container gets booted! */ @Exclude // this is important to let the ConfigurationExtension know that it should not handle it public class MyNotPickedUpPropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "mynotpickedupconfig.properties"; } @Override public boolean isOptional() { return false; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/propertyconfigsource/PropertyConfigSourceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.config.propertyconfigsource; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.Assert; import org.junit.Test; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) //X TODO this is only SeCategory as there is currently an Arq problem with properties! public class PropertyConfigSourceTest { private final static String CONFIG_FILE_NAME = "myconfig.properties"; private final static String BOOTCONFIG_FILE_NAME = "myboottimeconfig.properties"; private final static String NOT_PICKED_UP_CONFIG_FILE_NAME = "mynotpickedupconfig.properties"; /** *X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment(name = "tomee") public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "PropertyConfigSourceTest.jar") .addPackage(PropertyConfigSourceTest.class.getPackage()) .addAsResource(CONFIG_FILE_NAME) .addAsResource(BOOTCONFIG_FILE_NAME) .addAsResource(NOT_PICKED_UP_CONFIG_FILE_NAME) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "beanProvider.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test public void testCustomPropertyConfigSources() throws Exception { Assert.assertTrue( Thread.currentThread().getContextClassLoader().getResources(CONFIG_FILE_NAME).hasMoreElements()); String value = ConfigResolver.getPropertyValue("some.propertykey"); Assert.assertNotNull(value); Assert.assertEquals("somevalue", value); String bootTimeValue = ConfigResolver.getPropertyValue("some.boottimekey"); Assert.assertNotNull(bootTimeValue); Assert.assertEquals("correctvalue", bootTimeValue); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/AlwaysActiveBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import jakarta.enterprise.context.Dependent; /** * Class which is always active */ @Dependent public class AlwaysActiveBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/CustomExpressionBasedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Bean won't be excluded */ @Exclude(onExpression = "a eq b", interpretedBy = SimpleTestExpressionInterpreter.class) public class CustomExpressionBasedBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/CustomExpressionBasedNoBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Bean wil be excluded */ @Exclude(onExpression = "true eq true", interpretedBy = SimpleTestExpressionInterpreter.class) public class CustomExpressionBasedNoBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/DevBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; import org.apache.deltaspike.core.api.projectstage.ProjectStage; /** * Class which gets only included in case of project-stage development */ @Exclude(exceptIfProjectStage = ProjectStage.Development.class) public class DevBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/DevDbBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Class which gets excluded if the configured value for 'db' is 'prodDB' */ @Exclude(onExpression = "db==prodDB") public class DevDbBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ public abstract class ExcludeTest { /** * check if this package is included at all */ @Test public void simpleCheckOfBeansInPackage() { AlwaysActiveBean testBean = BeanProvider.getContextualReference(AlwaysActiveBean.class, true); Assert.assertNotNull(testBean); } /** * bean is excluded in any case */ @Test public void excludeWithoutCondition() { NoBean noBean = BeanProvider.getContextualReference(NoBean.class, true); Assert.assertNull(noBean); } /** * bean included in case of project-stage development */ @Test public void includeInCaseOfProjectStageProduction() { StdBean stdBean = BeanProvider.getContextualReference(StdBean.class, true); Assert.assertNotNull(stdBean); } /** * bean excluded in case of project-stage development */ @Test public void excludedInCaseOfProjectStageProduction() { DevBean devBean = BeanProvider.getContextualReference(DevBean.class, true); Assert.assertNull(devBean); } /** * beans de-/activated via expressions */ @Test public void excludedIfExpressionMatch() { ProdDbBean prodDbBean = BeanProvider.getContextualReference(ProdDbBean.class, true); Assert.assertNotNull(prodDbBean); DevDbBean devDbBean = BeanProvider.getContextualReference(DevDbBean.class, true); Assert.assertNull(devDbBean); } /** * bean excluded based on a custom expression syntax */ @Test public void excludedBasedOnCustomExpressionSyntax() { CustomExpressionBasedNoBean noBean = BeanProvider.getContextualReference(CustomExpressionBasedNoBean.class, true); Assert.assertNull(noBean); } /** * bean included based on a custom expression syntax */ @Test public void includedBasedOnCustomExpressionSyntax() { CustomExpressionBasedBean bean = BeanProvider.getContextualReference(CustomExpressionBasedBean.class, true); Assert.assertNotNull(bean); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeTestProjectStageDevelopment.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ public abstract class ExcludeTestProjectStageDevelopment { /** * bean included in case of project-stage development */ @Test public void includeInCaseOfProjectStageDevelopment() { DevBean devBean = BeanProvider.getContextualReference(DevBean.class, true); Assert.assertNotNull(devBean); } /** * bean excluded in case of project-stage development */ @Test public void excludedInCaseOfProjectStageDevelopment() { StdBean stdBean = BeanProvider.getContextualReference(StdBean.class, true); Assert.assertNull(stdBean); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeTestProjectStageEarFileDevelopment.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class ExcludeTestProjectStageEarFileDevelopment extends ExcludeTestProjectStageDevelopment { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = ExcludeTestProjectStageWarFileDevelopment.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(ExcludeTestProjectStageWarFileDevelopment.deploy()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeTestProjectStageWarFileDevelopment.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.AfterClass; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ @RunWith(Arquillian.class) public class ExcludeTestProjectStageWarFileDevelopment extends ExcludeTestProjectStageDevelopment { /** * X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() { String simpleName = ExcludeTestProjectStageWarFileDevelopment.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); // in case the Arquillian adapter doesn't properly handle resources on the classpath ProjectStageProducer.setProjectStage(ProjectStage.Development); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "excludeTestProjectStageDevelopmentTest.jar") .addPackage(ExcludeTestProjectStageWarFileDevelopment.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml") .addAsResource(new StringAsset("org.apache.deltaspike.ProjectStage = Development"), "apache-deltaspike.properties"); // when deployed on some remote container return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @AfterClass public static void resetProjectStage() { ProjectStageProducer.setProjectStage(null); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ExcludeWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import jakarta.enterprise.inject.spi.Extension; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.impl.exclude.extension.ExcludeExtension; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.test.core.impl.activation.TestClassDeactivator; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.AfterClass; import org.junit.runner.RunWith; import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Tests for {@link org.apache.deltaspike.core.api.exclude.Exclude} */ @RunWith(Arquillian.class) public class ExcludeWarFileTest extends ExcludeTest { /** * X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() throws IOException { String simpleName = ExcludeWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); // in case the Arquillian adapter doesn't properly handle resources on the classpath ProjectStageProducer.setProjectStage(ProjectStage.Production); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "excludeTest.jar") .addPackage(ExcludeWarFileTest.class.getPackage()) .addPackage(TestClassDeactivator.class.getPackage()) .addAsManifestResource(new StringAsset(getConfigContent()), "apache-deltaspike.properties") // when deployed on some remote container; .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, ExcludeExtension.class); } public static String getConfigContent() throws IOException { URL deltaspikeProps = ExcludeWarFileTest.class.getClassLoader().getResource("META-INF/apache-deltaspike.properties"); if (deltaspikeProps != null) { byte[] configContent = Files.readAllBytes(FileUtils.getFileForURL(deltaspikeProps.toString()).toPath()); return (new String(configContent, StandardCharsets.UTF_8) + "\norg.apache.deltaspike.ProjectStage = Production") .replace("deltaspike.interdyn.enabled=true", "deltaspike.interdyn.enabled=false"); } else { return ("\norg.apache.deltaspike.ProjectStage = Production"+ "\ndeltaspike.interdyn.enabled=false"); } } @AfterClass public static void resetProjectStage() { ProjectStageProducer.setProjectStage(null); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/NoBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Class which gets excluded in any case */ @Exclude public class NoBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/ProdDbBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; /** * Class which gets excluded if there is a configured value for the key called 'db' and * the value is not 'prodDB' */ @Exclude(onExpression = "db!=prodDB;db==*") public class ProdDbBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/SimpleTestExpressionInterpreter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.interpreter.ExpressionInterpreter; /** * Very simple interpreter for the custom test expressions */ public class SimpleTestExpressionInterpreter implements ExpressionInterpreter { /** * {@inheritDoc} */ @Override public Boolean evaluate(String expression) { if(expression.contains(" eq ")) { String[] parts = expression.split(" eq "); if(parts.length == 2 && parts[0].equals(parts[1])) { return true; } } return false; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/StdBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude; import org.apache.deltaspike.core.api.exclude.Exclude; import org.apache.deltaspike.core.api.projectstage.ProjectStage; /** * Class which gets excluded in case of project-stage development */ @Exclude(ifProjectStage = {ProjectStage.Development.class, ProjectStage.IntegrationTest.class}) public class StdBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/BaseEntity1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; public abstract class BaseEntity1 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/BaseEntity2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; import org.apache.deltaspike.core.api.exclude.Exclude; @Exclude public abstract class BaseEntity2 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/BaseEntity3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; import org.apache.deltaspike.core.api.exclude.Exclude; @Exclude public class BaseEntity3 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/Entity1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; public class Entity1 extends BaseEntity1 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/Entity2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; public class Entity2 extends BaseEntity2 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/Entity3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; public class Entity3 extends BaseEntity3 { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/exclude/uc001/EntityExcludeTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.exclude.uc001; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class EntityExcludeTest { @Deployment public static WebArchive deploy() { String simpleName = EntityExcludeTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); // in case the Arquillian adapter doesn't properly handle resources on the classpath ProjectStageProducer.setProjectStage(ProjectStage.Development); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(EntityExcludeTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml") .addAsResource(new StringAsset("org.apache.deltaspike.ProjectStage = Development"), "apache-deltaspike.properties"); // when deployed on some remote container; return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @AfterClass public static void resetProjectStage() { ProjectStageProducer.setProjectStage(null); } @Test public void entityWithoutExclusion() { Entity1 entity1 = BeanProvider.getContextualReference(Entity1.class, true); Assert.assertNotNull(entity1); } @Test public void excludedEntity() { Entity2 entity2 = BeanProvider.getContextualReference(Entity2.class, true); Assert.assertNull(entity2); } //TODO discuss it - if we don't need it, we can use @Inherited @Test public void excludedBaseClassWithoutInheritance() { BaseEntity3 baseEntity3 = BeanProvider.getContextualReference(BaseEntity3.class, true); Assert.assertTrue(baseEntity3 instanceof Entity3); Entity3 entity3 = BeanProvider.getContextualReference(Entity3.class, true); Assert.assertNotNull(entity3); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/interpreter/PropertyExpressionInterpreterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.interpreter; import org.apache.deltaspike.core.api.interpreter.ExpressionInterpreter; import org.apache.deltaspike.core.impl.interpreter.PropertyExpressionInterpreter; import org.junit.Assert; import org.junit.Test; /** * Tests for {@link org.apache.deltaspike.core.impl.interpreter.PropertyExpressionInterpreter} */ public class PropertyExpressionInterpreterTest { @Test public void testSimplePropertyExpressions() { ExpressionInterpreter interpreter = new PropertyExpressionInterpreter(){}; System.setProperty("k.1", "v1"); Assert.assertEquals(interpreter.evaluate("k.1==v1"), Boolean.TRUE); Assert.assertEquals(interpreter.evaluate("k.1==v2"), Boolean.FALSE); Assert.assertEquals(interpreter.evaluate("k.1!=v1"), Boolean.FALSE); Assert.assertEquals(interpreter.evaluate("k.1!=v2"), Boolean.TRUE); try { Assert.assertEquals(interpreter.evaluate("k.1=v1"), Boolean.TRUE); } catch (IllegalStateException e) { return; } Assert.fail(); } @Test public void testSimpleAndRequiredPropertyExpressions() { ExpressionInterpreter interpreter = new PropertyExpressionInterpreter(){}; System.setProperty("k.1", "v1"); Assert.assertEquals(interpreter.evaluate("k.1==v1;k.1==*"), Boolean.TRUE); Assert.assertEquals(interpreter.evaluate("ik.1==*"), Boolean.FALSE); Assert.assertEquals(interpreter.evaluate("k.1!=v2;k.1==*"), Boolean.TRUE); Assert.assertEquals(interpreter.evaluate("ik.1!=v2;ik.1==*"), Boolean.FALSE); } @Test public void testMultiplePropertyExpressions() { ExpressionInterpreter interpreter = new PropertyExpressionInterpreter(){}; System.setProperty("k.1", "v1"); System.setProperty("k.2", "v2"); Assert.assertEquals(interpreter.evaluate("k.1==v1;k.2==v2"), Boolean.TRUE); Assert.assertEquals(interpreter.evaluate("k.1==v1;k.2==v1"), Boolean.FALSE); Assert.assertEquals(interpreter.evaluate("k.1==v2;k.2==v2"), Boolean.FALSE); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/CustomMinimalMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; @MessageBundle @MessageContextConfig( localeResolver = FixedEnglishLocalResolver.class, messageSource = "customMinimalMessage") public interface CustomMinimalMessages { String sayHello(String name); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/ElPickedUpMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import jakarta.inject.Named; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; @Named @MessageBundle @MessageContextConfig( localeResolver = FixedEnglishLocalResolver.class, messageSource = "customMinimalMessage") public interface ElPickedUpMessages { String sayHello(String name); String text(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/FixedEnglishLocalResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.LocaleResolver; import jakarta.enterprise.context.ApplicationScoped; import java.util.Locale; @ApplicationScoped @TestConfiguration public class FixedEnglishLocalResolver implements LocaleResolver { private static final long serialVersionUID = 6947516315363672494L; @Override public Locale getLocale() { return Locale.ENGLISH; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/FixedGermanLocaleResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.LocaleResolver; import jakarta.enterprise.inject.Vetoed; import java.util.Locale; @Vetoed class FixedGermanLocaleResolver implements LocaleResolver { private static final long serialVersionUID = 1927000487639667775L; @Override public Locale getLocale() { return Locale.GERMAN; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/Jay.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import jakarta.inject.Inject; public class Jay { @Inject private TestMessages messages; String getMessage() { return messages.numberOfJaysSpotted(8); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageContextTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import java.io.Serializable; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import org.apache.deltaspike.core.api.message.LocaleResolver; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.utils.Serializer; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Tests for {@link MessageContext} */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class MessageContextTest { @Inject private SimpleMessage simpleMessage; @Inject private MessageContext messageContext; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { final JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "messageContextTest.jar") .addPackage(MessageContextTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "messageContextTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testSimpleMessage() { Assert.assertEquals("Welcome to DeltaSpike", this.simpleMessage.welcomeTo(this.messageContext, "DeltaSpike").toString()); } /** * We test that a non-existing category will fallback on the default message */ @Test public void testSimpleMessageCategory() { Assert.assertEquals("Welcome to DeltaSpike", this.simpleMessage.welcomeTo(this.messageContext, "DeltaSpike").toString("notexisting")); } @Test public void resolveTextTest() { final LocaleResolver localeResolver = new FixedEnglishLocalResolver(); final String messageText = this.messageContext .localeResolver(localeResolver) .messageResolver(new TestMessageResolver()) .message().template("{hello}").argument("hans").toString(); Assert.assertEquals("test message to hans", messageText); } @Test public void ignoreNullArguments() { final LocaleResolver localeResolver = new FixedEnglishLocalResolver(); final String messageText = this.messageContext .localeResolver(localeResolver) .messageResolver(new TestMessageResolver()) .message().template("{hello}").argument((Serializable[])null).toString(); Assert.assertEquals("test message to %s", messageText); } @Test public void resolveGermanMessageTextTest() { final LocaleResolver localeResolver = new FixedGermanLocaleResolver(); final String messageText = this.messageContext .localeResolver(localeResolver) .messageResolver(new TestMessageResolver()) .message().template("{hello}").argument("hans").toString(); Assert.assertEquals("Test Nachricht an hans", messageText); } @Test public void testArbitraryMessageContextRendering() { final LocaleResolver localeResolver = new FixedGermanLocaleResolver(); final Message message = this.messageContext .localeResolver(localeResolver) .messageResolver(new TestMessageResolver()) .message().template("{hello}").argument("hans"); Assert.assertEquals("Test Nachricht an hans", message.toString()); final MessageContext messageContext2 = this.messageContext.clone().localeResolver( new FixedEnglishLocalResolver()); Assert.assertEquals("test message to hans", message.toString(messageContext2)); } @Test public void createInvalidMessageTest() { String messageText = this.messageContext.message().template("{xyz123}").toString(); Assert.assertEquals("???xyz123???", messageText); messageText = this.messageContext .messageSource("nonexistingbundle.properties") .message() .template("{xyz123}") .toString(); Assert.assertEquals("???xyz123???", messageText); } @Test public void createInvalidMessageWithArgumentsTest() { final String messageText = this.messageContext.message().template("{xyz123}"). argument("123").argument("456").argument("789").toString(); Assert.assertEquals("???xyz123??? [123, 456, 789]", messageText); } @Test public void testMessageEquals() { final Message m1 = this.messageContext.message(); final Message m2 = this.messageContext.message(); final Message m3 = this.messageContext.messageResolver(new TestMessageResolver()).message(); Assert.assertEquals(m1, m1); Assert.assertEquals(m1, m2); Assert.assertEquals(m1, m3); Assert.assertEquals(m3, m1); Assert.assertEquals(m2, m3); m1.template("dumdidum").argument("nonono"); m2.template("dumdidum").argument("nonono"); Assert.assertEquals(m1, m2); Assert.assertEquals(m1.hashCode(), m2.hashCode()); m2.argument("toomuch"); Assert.assertFalse(m1.equals(m2)); Assert.assertFalse(m2.equals(m1)); } /** * Added check for System Property org.apache.deltaspike.weld.pre_1.1.10=true * If this exists then we will skip this test as it fails on WELD version < 1.1.10.Final * See DELTASPIKE-260 */ @Test public void testSerialization() { Assume.assumeTrue(System.getProperty("org.apache.deltaspike.weld.pre_1.1.10") == null); final Serializer messageSerializer = new Serializer(); final LocaleResolver localeResolver = new FixedGermanLocaleResolver(); final Message message = this.messageContext .localeResolver(localeResolver) .messageResolver(new TestMessageResolver()) .message().template("{hello}").argument("hans"); Assert.assertEquals("Test Nachricht an hans", message.toString()); final Message messageClone = messageSerializer.roundTrip(message); Assert.assertEquals(message, messageClone); Assert.assertEquals("Test Nachricht an hans", messageClone.toString()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageFormattedMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import java.util.Date; import org.apache.deltaspike.core.api.message.MessageBundle; /** * This is a test {@link MessageBundle} which uses the * Alternative {@link org.apache.deltaspike.core.impl.message.MessageFormatMessageInterpolator} * for formatting */ @MessageBundle public interface MessageFormattedMessage { String welcomeTo(String name); String incomeSinceDays(int days, float income); String commitsInProject(Date date, String projectName, int commits); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageFormattedMessageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.core.impl.message.MessageFormatMessageInterpolator; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; /** * Test for {@link MessageFormatMessageInterpolator} * formatted messages. */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class MessageFormattedMessageTest { @Inject private MessageFormattedMessage message; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { Asset beansXml = new StringAsset( "" + "" + MessageFormatMessageInterpolator.class.getName() + "" + "" ); JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "messageFormattedMessageTest.jar") .addPackage(MessageFormattedMessageTest.class.getPackage()) .addAsManifestResource(beansXml, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "messageFormattedMessageTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testSimpleMessage() { assertEquals("Welcome to DeltaSpike", message.welcomeTo("DeltaSpike")); assertEquals("The income since 42 days is 12.34", message.incomeSinceDays(42, 12.34f)); } @Test public void testNullMessage() { assertEquals("Welcome to null", message.welcomeTo(null)); } @Test public void testComplexMessageWithNull() { assertEquals("At null on null, project deltaspike had 10 commits.", message.commitsInProject(null, "deltaspike", 10)); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Tests for {@link org.apache.deltaspike.core.api.message.MessageTemplate} */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class MessageTest { @Inject private TestMessages messages; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "messageTest.jar") .addPackage(MessageTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "messageTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testMessageBundleInjection(Jay jay) { assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "Spotted 8 jays", jay.getMessage()); } @Test public void testInternationalizedMessage() { assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "Welcome to DeltaSpike", messages.welcomeToDeltaSpike()); } @Test public void testInternationalizedParametrizedMessage() { assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "Welcome to Apache DeltaSpike", messages.welcomeTo("Apache DeltaSpike")); } @Test public void testMessageCategory() { assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "Value good was set" , messages.messageWithCategory("good").toString()); assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "The value of the property has been set to good." , messages.messageWithCategory("good").toString("longText")); assertEquals(TestMessageInterpolator.SPECIALFORMATTED + "Value good was set" , messages.messageWithCategory("good").toString("notExistingCategory")); } @Test public void testObjectMethods() { messages.hashCode(); assertNotNull(messages.toString()); assertNotNull(messages.getClass()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MessageUser.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import java.io.Serializable; /** * A SessionScoped (passivating!) user which uses a DeltaSpike message */ @SessionScoped public class MessageUser implements Serializable { @Inject private SimpleMessage msg; public SimpleMessage getMsg() { return msg; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MinimalMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; @MessageBundle @MessageContextConfig(localeResolver = FixedEnglishLocalResolver.class) public interface MinimalMessages { String sayHello(String name); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/MinimalMessagesTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Filters; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Tests for type-safe messages without {@link org.apache.deltaspike.core.api.message.MessageTemplate} */ @RunWith(Arquillian.class) public class MinimalMessagesTest { @Inject private MinimalMessages minimalMessages; @Inject private CustomMinimalMessages customMinimalMessages; @Inject private ElPickedUpMessages injectedElPickedUpMessages; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "minimalMessageTest.jar") .addPackages(false, Filters.exclude(MessageContextTest.class), MinimalMessagesTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "minimalMessageTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsResource("customMinimalMessage_en.properties") .addAsResource("org/apache/deltaspike/test/core/api/message/MinimalMessages_en.properties") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testMinimalMessage() { Assert.assertEquals("Hello DeltaSpike", minimalMessages.sayHello("DeltaSpike")); } @Test public void testCustomMinimalMessage() { Assert.assertEquals("Hello DeltaSpike", customMinimalMessages.sayHello("DeltaSpike")); } @Test public void testExpressionLanguageIntegration() { ElPickedUpMessages elMessage = (ElPickedUpMessages) BeanProvider.getContextualReference("elPickedUpMessages"); Assert.assertNotNull(elMessage); Assert.assertEquals("Hello DeltaSpike", elMessage.sayHello("DeltaSpike")); Assert.assertEquals("Hello null", elMessage.sayHello(null)); Assert.assertEquals("Text", elMessage.text()); } @Test public void testExpressionLanguageIntegrationWithCustomName() { TypedMessageWithCustomName elMessage = (TypedMessageWithCustomName) BeanProvider.getContextualReference("namedTypedMessages"); Assert.assertNotNull(elMessage); Assert.assertEquals("Hello DeltaSpike", elMessage.sayHello("DeltaSpike")); Assert.assertEquals("Hello null", elMessage.sayHello(null)); Assert.assertEquals("Text", elMessage.text()); } @Test public void testInjectionOfNamedMessageBundle() { ElPickedUpMessages injectedElMessage = this.injectedElPickedUpMessages; Assert.assertNotNull(injectedElMessage); Assert.assertEquals("Hello DeltaSpike", injectedElMessage.sayHello("DeltaSpike")); Assert.assertEquals("Hello null", injectedElMessage.sayHello(null)); Assert.assertEquals("Text", injectedElMessage.text()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageTemplate; import org.apache.deltaspike.core.api.message.MessageBundle; @MessageBundle public interface SimpleMessage { @MessageTemplate("Welcome to DeltaSpike") String welcomeToDeltaSpike(); @MessageTemplate("Welcome to %s") Message welcomeTo(MessageContext messageContext, String name); @MessageTemplate("Welcome to %s") String welcomeWithStringVariable(String name); @MessageTemplate("Welcome to %f") String welcomeWithFloatVariable(Float value); @MessageTemplate("Counter: %04d") String counter(Integer value); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/SimpleMessageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.LocaleResolver; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.utils.Serializer; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Tests for {@link org.apache.deltaspike.core.api.message.MessageTemplate} */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class SimpleMessageTest { @Inject private SimpleMessage simpleMessage; @Inject private LocaleResolver localeResolver; @Inject private MessageUser messageUser; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "simpleMessageTest.jar") .addPackage(SimpleMessageTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "simpleMessageTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testSimpleMessage() { assertEquals("Welcome to DeltaSpike", simpleMessage.welcomeToDeltaSpike()); assertEquals("Welcome to DeltaSpike", simpleMessage.welcomeWithStringVariable("DeltaSpike")); } /** * This test checks if the {@link org.apache.deltaspike.core.api.message.LocaleResolver} * gets properly invoked. */ @Test public void testDefaultLocaleInMessage() { float f = 123.45f; String expectedResult = "Welcome to " + String.format(this.localeResolver.getLocale(), "%f", f); String result = simpleMessage.welcomeWithFloatVariable(f); assertEquals(expectedResult, result); } @Test public void testNullMessage() { String expectedResult = "Welcome to null"; String result = simpleMessage.welcomeWithStringVariable(null); assertEquals(expectedResult, result); } @Test public void testPaddingWithNullMessage() { String expectedResult = "Counter: null"; String result = simpleMessage.counter(null); assertEquals(expectedResult, result); } @Test public void testMessageSerialisation() { Serializer simpleMessageSerializer = new Serializer(); SimpleMessage sm2 = simpleMessageSerializer.roundTrip(simpleMessage); assertNotNull(sm2); } @Test public void testPassivationCapability() { assertEquals("Welcome to DeltaSpike", messageUser.getMsg().welcomeToDeltaSpike()); assertEquals("Welcome to DeltaSpike", messageUser.getMsg().welcomeWithStringVariable("DeltaSpike")); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestConfiguration.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; 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.RetentionPolicy.RUNTIME; /** *

Qualifier for marking beans which provide other configuration.

*/ @Target({ TYPE, PARAMETER, FIELD, METHOD, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @Qualifier public @interface TestConfiguration { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestLocalResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.impl.message.DefaultLocaleResolver; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; import java.util.Locale; @ApplicationScoped @Specializes public class TestLocalResolver extends DefaultLocaleResolver { private static final long serialVersionUID = 4947516315363672494L; @Override public Locale getLocale() { return Locale.ENGLISH; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageInterpolator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.MessageInterpolator; import jakarta.enterprise.context.ApplicationScoped; import java.io.Serializable; import java.util.Locale; @ApplicationScoped @TestConfiguration public class TestMessageInterpolator implements MessageInterpolator { private static final long serialVersionUID = 5636914399691923602L; public static final String SPECIALFORMATTED = "specialformatted "; @Override public String interpolate(String messageTemplate, Serializable[] arguments, Locale locale) { return SPECIALFORMATTED + String.format(locale, messageTemplate, arguments); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessageResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageResolver; import org.apache.deltaspike.core.util.PropertyFileUtils; import jakarta.enterprise.inject.Vetoed; import java.util.MissingResourceException; import java.util.ResourceBundle; @Vetoed public class TestMessageResolver implements MessageResolver { private static final long serialVersionUID = -7977480064291950923L; protected TestMessageResolver() { } @Override public String getMessage(MessageContext messageContext, String messageTemplate, String category) { if ( messageTemplate.startsWith("{") && messageTemplate.endsWith("}")) { String resourceKey = messageTemplate.substring(1, messageTemplate.length() - 1); try { ResourceBundle messageBundle = PropertyFileUtils .getResourceBundle(TestMessages.class.getName(), messageContext.getLocale()); String value = null; if (category != null && category.length() > 0) { value = messageBundle.getString(resourceKey + "." + category); } if (value == null) { value = messageBundle.getString(resourceKey); } return value; } catch (MissingResourceException e) { return resourceKey; } } return messageTemplate; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TestMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageTemplate; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; @MessageBundle @MessageContextConfig( messageInterpolator = TestMessageInterpolator.class, localeResolver = FixedEnglishLocalResolver.class ) public interface TestMessages { @MessageTemplate("Spotted %s jays") String numberOfJaysSpotted(int number); @MessageTemplate("{categoryMessage}") Message messageWithCategory(String value); @MessageTemplate("{welcome_to_deltaspike}") String welcomeToDeltaSpike(); @MessageTemplate("{welcome_to}") String welcomeTo(String name); @MessageTemplate("{welcome_to}") String welcomeTo(MessageContext messageContext, String name); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/TypedMessageWithCustomName.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; import jakarta.inject.Named; @Named("namedTypedMessages") @MessageBundle @MessageContextConfig( localeResolver = FixedEnglishLocalResolver.class, messageSource = "customMinimalMessage") public interface TypedMessageWithCustomName { String sayHello(String name); String text(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/broken/BrokenMessageBundleClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message.broken; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageTemplate; /** * This class is broken, as MessageBundle must only be used on Interfaces */ @MessageBundle public class BrokenMessageBundleClass { @MessageTemplate("Welcome to DeltaSpike") String welcomeToDeltaSpike() { return null; } @MessageTemplate("Welcome to %s") Message welcomeTo(MessageContext messageContext, String name) { return null; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/broken/BrokenMessageBundleOnClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message.broken; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.ShouldThrowException; //X import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.experimental.categories.Category; //X import org.junit.Test; //X import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; /** * Tests for broken MessageBundle definition * * This is currently disabled due to a few problems with DeploymentException validation: * a.) some containers wrap the internally thrown IllegalStateException into another Exception * b.) some arquillian container adapters throw up with a NPE * * TODO: fix the container and arquillian setup! */ //X @RunWith(Arquillian.class) @Category(SeCategory.class) public class BrokenMessageBundleOnClassTest { @Inject private BrokenMessageBundleClass messageBundle; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment @ShouldThrowException(Exception.class) public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "invalidMessageBundleTest.jar") .addPackage(BrokenMessageBundleClass.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "invalidMessageBundleTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } //X @Test public void testSimpleMessage() { assertEquals("Welcome to DeltaSpike", messageBundle.welcomeToDeltaSpike()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/locale/ConfigurableLocaleMessageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message.locale; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import java.util.Date; import java.util.Locale; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.impl.message.MessageBundleExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; /** * Tests for {@link org.apache.deltaspike.core.api.message.MessageTemplate} */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class ConfigurableLocaleMessageTest { private static final String BEANS_XML_CONTENT = "" + ConfigurableLocaleResolver.class.getName() + ""; @Inject private MessageWithLocale localizedMessage; @Inject private ConfigurableLocaleResolver localeResolver; @Inject private MessageContext messageContext; /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "localeMessageTest.jar") .addPackage(ConfigurableLocaleMessageTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap .create(WebArchive.class, "localeMessageTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(new StringAsset(BEANS_XML_CONTENT), "beans.xml") .addAsServiceProvider(Extension.class, MessageBundleExtension.class); } @Test public void testSimpleMessage() { assertEquals("Welcome to DeltaSpike", localizedMessage.welcomeToDeltaSpike()); assertEquals("Welcome to DeltaSpike", localizedMessage.welcomeWithStringVariable("DeltaSpike")); } /** * This test checks if the {@link org.apache.deltaspike.core.api.message.LocaleResolver} * gets properly invoked. */ @Test public void testDefaultLocaleInMessage() { internalTestLocales(Locale.GERMANY); internalTestLocales(Locale.US); internalTestLocales(Locale.FRANCE); } private void internalTestLocales(Locale locale) { localeResolver.setLocale(locale); float f = 123.45f; String expectedResult = "Welcome " + String.format(locale, "%f", f); String result = localizedMessage.welcomeWithFloatVariable(f); assertEquals(expectedResult, result); Date dt = new Date(); expectedResult = "Welcome " + String.format(locale, "%1$tB %1$te,%1$tY", dt); result = localizedMessage.welcomeWithDateVariable(dt); assertEquals(expectedResult, result); result = messageContext.message().template("Welcome at %tB").argument(dt).toString(); assertEquals("Welcome at " + String.format(locale, "%1$tB", dt), result); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/locale/ConfigurableLocaleResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message.locale; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; import java.util.Locale; import org.apache.deltaspike.core.api.message.LocaleResolver; /** * This alternative LocaleResolver replaces the DefaultLocaleResolver. * It allows us to set the Locale to different ones to test * variations. This is needed to avoid having test which by accident * only run in a single timezone/locale. */ @ApplicationScoped @Alternative public class ConfigurableLocaleResolver implements LocaleResolver { private static final long serialVersionUID = 1927000487639667775L; private Locale locale; @PostConstruct public void init() { locale = Locale.getDefault(); } @Override public Locale getLocale() { return locale; } public void setLocale(Locale locale) { this.locale = locale; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/message/locale/MessageWithLocale.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.message.locale; import java.util.Date; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageTemplate; @MessageBundle public interface MessageWithLocale { @MessageTemplate("Welcome to DeltaSpike") String welcomeToDeltaSpike(); @MessageTemplate("Welcome to %s") Message welcomeTo(MessageContext messageContext, String name); @MessageTemplate("Welcome to %s") String welcomeWithStringVariable(String name); @MessageTemplate("Welcome %f") String welcomeWithFloatVariable(Float floatValue); @MessageTemplate("Welcome %1$tB %1$te,%1$tY") String welcomeWithDateVariable(Date dateValue); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/ProjectStageProducerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.projectstage; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.junit.Assert; import org.junit.Test; /** * */ public class ProjectStageProducerTest { /** * Test a ProjectStage which got set by the jakarta.faces.ProjectStage */ @Test public void testProjectStageSetByEnvironment() { String[] oldEnvVals = new String[ProjectStageProducer.CONFIG_SETTING_KEYS.length]; for (int i = 0; i < ProjectStageProducer.CONFIG_SETTING_KEYS.length; i++) { String envName = ProjectStageProducer.CONFIG_SETTING_KEYS[i]; oldEnvVals[i] = "" + System.getProperty(envName); // and also clean them now System.setProperty(ProjectStageProducer.CONFIG_SETTING_KEYS[i], ""); } try { for (int i = 0; i < ProjectStageProducer.CONFIG_SETTING_KEYS.length; i++) { String envName = ProjectStageProducer.CONFIG_SETTING_KEYS[i]; System.setProperty(envName, "SystemTest"); ProjectStageProducer psp = ProjectStageProducer.getInstance(); Assert.assertNotNull(psp); ProjectStageProducer.setProjectStage(null); ProjectStage ps = psp.getProjectStage(); Assert.assertNotNull(ps); Assert.assertEquals(ps, ProjectStage.SystemTest); Assert.assertTrue(ps == ProjectStage.SystemTest); ProjectStageProducer.setProjectStage(null); System.setProperty(envName, "IntegrationTest"); ps = psp.getProjectStage(); Assert.assertNotNull(ps); Assert.assertEquals(ps, ProjectStage.IntegrationTest); Assert.assertTrue(ps == ProjectStage.IntegrationTest); System.setProperty(envName, ""); } } finally { // restore the old env values for (int i = 0; i < ProjectStageProducer.CONFIG_SETTING_KEYS.length; i++) { System.setProperty(ProjectStageProducer.CONFIG_SETTING_KEYS[i], oldEnvVals[i]); } // also reset the ProjectStageProducer again ProjectStageProducer.setProjectStage(null); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/ProjectStageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.projectstage; import org.junit.Test; import org.junit.Assert; import org.apache.deltaspike.core.api.projectstage.ProjectStage; /** * Test for {@link ProjectStage} */ public class ProjectStageTest { @Test public void testProjectStages() throws Exception { ProjectStage ps = ProjectStage.Development; Assert.assertNotNull(ps); ProjectStage psOther = ProjectStage.valueOf("CustomProjectStage"); Assert.assertNotNull(psOther); psOther = TestProjectStages.CustomProjectStage; Assert.assertNotNull(psOther); ProjectStage psProd = ProjectStage.valueOf("Production"); Assert.assertNotNull(psProd); ProjectStage[] values = ProjectStage.values(); Assert.assertNotNull(values); Assert.assertTrue(values.length == 7); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/projectstage/TestProjectStages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.projectstage; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.api.projectstage.ProjectStageHolder; /** * This is a test ProjectStage. It demonstrates how to add custom ProjectStages. * This TestProjectStage must get registered via the {@link java.util.ServiceLoader} * mechanism. Please see the file *
 *     META-INF/services/org.apache.deltaspike.core.api.projectstage.ProjectStageHolder
 * 
*/ public class TestProjectStages implements ProjectStageHolder { public static final class CustomProjectStage extends ProjectStage { private static final long serialVersionUID = 1029095387976167179L; } public static final CustomProjectStage CustomProjectStage = new CustomProjectStage(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/BeanManagerProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.junit.Assert; import org.junit.Test; import jakarta.enterprise.inject.spi.BeanManager; public abstract class BeanManagerProviderTest { @Test public void testBeanManagerProvider() throws Exception { BeanManagerProvider bmp = BeanManagerProvider.getInstance(); Assert.assertNotNull(bmp); BeanManager bm = bmp.getBeanManager(); Assert.assertNotNull(bm); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/BeanManagerProviderWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class BeanManagerProviderWarFileTest extends BeanManagerProviderTest { /** *X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() { String simpleName = BeanManagerProviderWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addPackage(BeanManagerProviderWarFileTest.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/BeanProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.utils.Serializer; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class BeanProviderTest { /** *X TODO creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "beanProviderTest.jar") .addPackage(BeanProviderTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "beanProvider.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } /** * lookup by type */ @Test public void simpleBeanLookupByType() { TestBean testBean = BeanProvider.getContextualReference(TestBean.class, false); Assert.assertNotNull(testBean); } /** * lookup by name with expected type */ @Test public void simpleBeanLookupByName() { TestBean testBean = BeanProvider.getContextualReference("extraNameBean", false, TestBean.class); Assert.assertNotNull(testBean); } /** * lookup by name without type */ @Test public void simpleBeanLookupByNameWithoutType() { { // test with the convenient operator (optional=false implied) Object testBean = BeanProvider.getContextualReference("extraNameBean"); Assert.assertNotNull(testBean); Assert.assertTrue(testBean instanceof TestBean); TestBean tb = (TestBean) testBean; Assert.assertEquals(4711, tb.getI()); } { // test with the 'optional' flag set to false Object testBean = BeanProvider.getContextualReference("extraNameBean", false); Assert.assertNotNull(testBean); Assert.assertTrue(testBean instanceof TestBean); TestBean tb = (TestBean) testBean; Assert.assertEquals(4711, tb.getI()); } { // test by name lookup with the 'optional' flag set to false try { Object testBean = BeanProvider.getContextualReference("thisBeanDoesNotExist"); Assert.fail("BeanProvider#getContextualReference should have blown up with a non-existing bean!"); } catch(IllegalStateException ise) { // all is well, this is exactly what should happen! } } { // test by type lookup with the 'optional' flag set to false try { // guess we can safely assume that there is no producer for a ConcurrentHashMap in the system... ConcurrentHashMap chm = BeanProvider.getContextualReference(ConcurrentHashMap.class); Assert.fail("BeanProvider#getContextualReference should have blown up with a non-existing bean!"); } catch(IllegalStateException ise) { // all is well, this is exactly what should happen! } } } /* * lookup without result */ @Test public void optionalBeanLookup() { NoBean result = BeanProvider.getContextualReference(NoBean.class, true); Assert.assertNull(result); } /* * lookup of all beans of a given type */ @Test public void multiBeanLookupWithDependentBean() throws Exception { List result = BeanProvider.getContextualReferences(MultiBean.class, false); Assert.assertNotNull(result); Assert.assertEquals(2, result.size()); } /* * lookup of all beans of a given type which aren't dependent scoped */ @Test public void multiBeanLookupWithoutDependentBean() throws Exception { List result = BeanProvider.getContextualReferences(MultiBean.class, false, false); Assert.assertNotNull(result); Assert.assertEquals(1, result.size()); } /* * create a manual instance, inject dependencies, set values of the dependencies and check the referenced cdi bean */ @Test public void injectBeansInNonManagedInstance() throws Exception { ManualBean manualBean = new ManualBean(); Assert.assertNull(manualBean.getTestBean()); BeanProvider.injectFields(manualBean); Assert.assertNotNull(manualBean.getTestBean()); Assert.assertEquals(4711, manualBean.getTestBean().getI()); int newValue = 14; manualBean.getTestBean().setI(newValue); Assert.assertEquals(newValue, manualBean.getTestBean().getI()); TestBean testBean = BeanProvider.getContextualReference(TestBean.class); Assert.assertEquals(newValue, testBean.getI()); testBean.setI(4711); // reset the value if this test is executed first } @Test public void testDependentBeanResolving() throws Exception { DependentProvider dependentTestBeanProvider = BeanProvider.getDependent(DependentTestBean.class); checkDependentProvider(dependentTestBeanProvider); } @Test public void testNamedDependentBeanResolving() throws Exception { DependentProvider dependentTestBeanProvider = BeanProvider.getDependent("dependentTestBean"); checkDependentProvider(dependentTestBeanProvider); } @Test public void testDependentBeanSerialization() throws Exception { DependentProvider dependentTestBeanProvider = BeanProvider.getDependent(DependentTestBean.class); Serializer> serializer = new Serializer>(); DependentProvider provider2 = serializer.roundTrip(dependentTestBeanProvider); Assert.assertNotNull(provider2); } private void checkDependentProvider(DependentProvider dependentTestBeanProvider) { Assert.assertNotNull(dependentTestBeanProvider); DependentTestBean instance = dependentTestBeanProvider.get(); Assert.assertNotNull(instance); Assert.assertEquals(42, instance.getI()); instance.setI(21); Assert.assertEquals(21, instance.getI()); Assert.assertFalse(instance.isDestroyed()); dependentTestBeanProvider.destroy(); Assert.assertTrue(instance.isDestroyed()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/DependentTestBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Named; import java.io.Serializable; @Dependent @Named public class DependentTestBean implements Serializable { private int i = 42; private boolean destroyed = false; public int getI() { return i; } public void setI(int i) { this.i = i; } public boolean isDestroyed() { return destroyed; } @PreDestroy public void cleanUp() { destroyed = true; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/MBean01.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import jakarta.enterprise.context.ApplicationScoped; /** * Impl #1 */ @ApplicationScoped public class MBean01 implements MultiBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/MBean02.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import jakarta.enterprise.context.Dependent; /** * Impl #2 */ @Dependent public class MBean02 implements MultiBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/ManualBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; @Vetoed class ManualBean { @Inject private TestBean testBean; TestBean getTestBean() { return testBean; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/MultiBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; /** * Interface for multiple beans */ public interface MultiBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/NoBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; /** * Interface without implementation */ public interface NoBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/provider/TestBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.provider; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Named; @Named("extraNameBean") @ApplicationScoped public class TestBean { private int i = 4711; public int getI() { return i; } public void setI(int i) { this.i = i; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/explicit/ExplicitTestGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.explicit; public interface ExplicitTestGroup { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/explicit/ExplicitlyGroupedBeanX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.explicit; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversation; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import jakarta.inject.Inject; import java.io.Serializable; @GroupedConversationScoped @ConversationGroup(ExplicitTestGroup.class) public class ExplicitlyGroupedBeanX implements Serializable { private static final long serialVersionUID = -1291355584482007178L; private String value; @Inject private GroupedConversation conversation; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void done() { this.conversation.close(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/explicit/ExplicitlyGroupedBeanY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.explicit; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversation; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import jakarta.inject.Inject; import java.io.Serializable; @GroupedConversationScoped @ConversationGroup(ExplicitTestGroup.class) public class ExplicitlyGroupedBeanY implements Serializable { private static final long serialVersionUID = -1291355584482007178L; private String value; @Inject private GroupedConversation conversation; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void done() { this.conversation.close(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/explicit/ExplicitlyGroupedConversationsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.explicit; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ExplicitlyGroupedConversationsTest { @Deployment public static WebArchive deploy() { String simpleName = ExplicitlyGroupedConversationsTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ExplicitlyGroupedConversationsTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject @ConversationGroup(ExplicitTestGroup.class) private ExplicitlyGroupedBeanX explicitlyGroupedBeanX; @Inject @ConversationGroup(ExplicitTestGroup.class) private ExplicitlyGroupedBeanY explicitlyGroupedBeanY; @Inject private GroupedConversationManager conversationManager; @Test public void parallelConversationsTest() { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); windowContext.activateWindow("w2"); Assert.assertNull(explicitlyGroupedBeanX.getValue()); Assert.assertNull(explicitlyGroupedBeanY.getValue()); explicitlyGroupedBeanX.setValue("y1"); explicitlyGroupedBeanY.setValue("y2"); Assert.assertEquals("y1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("y2", explicitlyGroupedBeanY.getValue()); } @Test public void immediatelyClosedConversationTest() { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); explicitlyGroupedBeanX.done(); Assert.assertNull(explicitlyGroupedBeanX.getValue()); Assert.assertNull(explicitlyGroupedBeanY.getValue()); } @Test public void immediatelyClosedConversationViaConversationManagerTest() { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); this.conversationManager.closeConversationGroup(ExplicitTestGroup.class); Assert.assertNull(explicitlyGroupedBeanX.getValue()); Assert.assertNull(explicitlyGroupedBeanY.getValue()); } @Test public void immediatelyClosedConversationsTest() { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); this.conversationManager.closeConversations(); Assert.assertNull(explicitlyGroupedBeanX.getValue()); Assert.assertNull(explicitlyGroupedBeanY.getValue()); } @Test public void immediatelyClosedConversationsViaWindowContextTest() { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); Assert.assertTrue(this.windowContext.closeWindow("w1")); windowContext.activateWindow("w1"); Assert.assertNull(explicitlyGroupedBeanX.getValue()); Assert.assertNull(explicitlyGroupedBeanY.getValue()); } @Test(expected = ContextNotActiveException.class) public void noWindowTest() { try { windowContext.activateWindow("w1"); explicitlyGroupedBeanX.setValue("x1"); explicitlyGroupedBeanY.setValue("x2"); Assert.assertEquals("x1", explicitlyGroupedBeanX.getValue()); Assert.assertEquals("x2", explicitlyGroupedBeanY.getValue()); this.windowContext.closeWindow("w1"); } catch (ContextNotActiveException e) { Assert.fail(); } explicitlyGroupedBeanX.getValue(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/implicit/ImplicitlyGroupedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.implicit; import org.apache.deltaspike.core.api.scope.GroupedConversation; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import jakarta.inject.Inject; import java.io.Serializable; @GroupedConversationScoped public class ImplicitlyGroupedBean implements Serializable { private static final long serialVersionUID = -4722854711870629520L; private String value; @Inject private GroupedConversation conversation; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void done() { this.conversation.close(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/grouped/implicit/ImplicitlyGroupedConversationsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.grouped.implicit; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ImplicitlyGroupedConversationsTest { @Deployment public static WebArchive deploy() { String simpleName = ImplicitlyGroupedConversationsTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ImplicitlyGroupedConversationsTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject private ImplicitlyGroupedBean implicitlyGroupedBean; @Inject private GroupedConversationManager conversationManager; @Test public void parallelConversationsTest() { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); windowContext.activateWindow("w2"); Assert.assertNull(implicitlyGroupedBean.getValue()); implicitlyGroupedBean.setValue("y"); Assert.assertEquals("y", implicitlyGroupedBean.getValue()); windowContext.activateWindow("w1"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); } @Test public void immediatelyClosedConversationTest() { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); implicitlyGroupedBean.done(); Assert.assertNull(implicitlyGroupedBean.getValue()); } @Test public void immediatelyClosedConversationViaConversationManagerTest() { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); this.conversationManager.closeConversation(ImplicitlyGroupedBean.class); Assert.assertNull(implicitlyGroupedBean.getValue()); implicitlyGroupedBean.setValue("y"); Assert.assertEquals("y", implicitlyGroupedBean.getValue()); this.conversationManager.closeConversationGroup(ImplicitlyGroupedBean.class); Assert.assertNull(implicitlyGroupedBean.getValue()); } @Test public void immediatelyClosedConversationsTest() { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); this.conversationManager.closeConversations(); Assert.assertNull(implicitlyGroupedBean.getValue()); } @Test public void immediatelyClosedConversationsViaWindowContextTest() { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); Assert.assertTrue(this.windowContext.closeWindow("w1")); windowContext.activateWindow("w1"); Assert.assertNull(implicitlyGroupedBean.getValue()); } @Test(expected = ContextNotActiveException.class) public void noWindowTest() { try { windowContext.activateWindow("w1"); implicitlyGroupedBean.setValue("x"); Assert.assertEquals("x", implicitlyGroupedBean.getValue()); this.windowContext.closeWindow("w1"); } catch (ContextNotActiveException e) { Assert.fail(); } implicitlyGroupedBean.getValue(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/shared/TestBaseBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared; import org.apache.deltaspike.core.api.scope.GroupedConversation; import jakarta.inject.Inject; import java.io.Serializable; public abstract class TestBaseBean implements Serializable { private String value; @Inject private GroupedConversation conversation; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void done() { this.conversation.close(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/shared/TestBeanA.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanA extends TestBaseBean { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/shared/TestBeanB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanB extends TestBaseBean { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/shared/TestBeanC.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanC extends TestBaseBean { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/shared/TestGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared; public interface TestGroup { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc001/GroupedConversationSubGroupTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc001; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.*; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class GroupedConversationSubGroupTest { @Deployment public static WebArchive deploy() { String simpleName = GroupedConversationSubGroupTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(GroupedConversationSubGroupTest.class.getPackage()) .addPackage(TestBaseBean.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject @ConversationGroup(TestGroup.class) private TestBeanA testBeanA; @Inject @ConversationGroup(TestGroup.class) private TestBeanB testBeanB; @Inject @ConversationGroup(TestGroup.class) private TestBeanC testBeanC; @Inject private GroupedConversationManager conversationManager; @Test public void closedSubGroupTest() { windowContext.activateWindow("w1"); testBeanA.setValue("x1"); testBeanB.setValue("x2"); testBeanC.setValue("x3"); Assert.assertEquals("x1", testBeanA.getValue()); Assert.assertEquals("x2", testBeanB.getValue()); Assert.assertEquals("x3", testBeanC.getValue()); this.conversationManager.closeConversationGroup(TestSubGroup.class); Assert.assertNull(testBeanA.getValue()); Assert.assertEquals("x2", testBeanB.getValue()); //not part of the sub-group Assert.assertNull(testBeanC.getValue()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc001/TestSubGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc001; import org.apache.deltaspike.core.api.scope.ConversationSubGroup; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanA; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanC; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @ConversationSubGroup(of = TestGroup.class, subGroup = {TestBeanA.class, TestBeanC.class}) public interface TestSubGroup { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc002/GroupedConversationSubGroupTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc002; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBaseBean; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanA; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanB; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanC; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class GroupedConversationSubGroupTest { @Deployment public static WebArchive deploy() { String simpleName = GroupedConversationSubGroupTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(GroupedConversationSubGroupTest.class.getPackage()) .addPackage(TestBaseBean.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject @ConversationGroup(TestGroup.class) private TestBeanA testBeanA; @Inject @ConversationGroup(TestGroup.class) private TestBeanB testBeanB; @Inject @ConversationGroup(TestGroup.class) private TestBeanC testBeanC; @Inject private GroupedConversationManager conversationManager; @Test public void closedSubGroupTest() { windowContext.activateWindow("w1"); testBeanA.setValue("x1"); testBeanB.setValue("x2"); testBeanC.setValue("x3"); Assert.assertEquals("x1", testBeanA.getValue()); Assert.assertEquals("x2", testBeanB.getValue()); Assert.assertEquals("x3", testBeanC.getValue()); this.conversationManager.closeConversationGroup(TestSubGroup.class); Assert.assertNull(testBeanA.getValue()); Assert.assertEquals("x2", testBeanB.getValue()); //not part of the sub-group Assert.assertNull(testBeanC.getValue()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc002/TestSubGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc002; import org.apache.deltaspike.core.api.scope.ConversationSubGroup; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanA; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBeanC; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @ConversationSubGroup(subGroup = {TestBeanA.class, TestBeanC.class}) public interface TestSubGroup extends TestGroup { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/GroupedConversationSubGroupTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.spi.scope.conversation.GroupedConversationManager; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBaseBean; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class GroupedConversationSubGroupTest { @Deployment public static WebArchive deploy() { String simpleName = GroupedConversationSubGroupTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(GroupedConversationSubGroupTest.class.getPackage()) .addPackage(TestBaseBean.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject @ConversationGroup(TestGroup.class) private TestBeanX testBeanX; @Inject @ConversationGroup(TestGroup.class) private TestBeanY testBeanY; @Inject @ConversationGroup(TestGroup.class) private TestBeanZ testBeanZ; @Inject private GroupedConversationManager conversationManager; @Test public void closedSubGroupTest() { windowContext.activateWindow("w1"); testBeanX.setValue("x1"); testBeanY.setValue("x2"); testBeanZ.setValue("x3"); Assert.assertEquals("x1", testBeanX.getValue()); Assert.assertEquals("x2", testBeanY.getValue()); Assert.assertEquals("x3", testBeanZ.getValue()); this.conversationManager.closeConversationGroup(TestImplicitSubGroup.class); Assert.assertNull(testBeanX.getValue()); Assert.assertEquals("x2", testBeanY.getValue()); //not part of the sub-group Assert.assertNull(testBeanZ.getValue()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/TestBeanX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBaseBean; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanX extends TestBaseBean implements TestSubGroupContract { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/TestBeanY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBaseBean; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanY extends TestBaseBean { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/TestBeanZ.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; import org.apache.deltaspike.core.api.scope.ConversationGroup; import org.apache.deltaspike.core.api.scope.GroupedConversationScoped; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestBaseBean; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @GroupedConversationScoped @ConversationGroup(TestGroup.class) public class TestBeanZ extends TestBaseBean implements TestSubGroupContract { private static final long serialVersionUID = -1291355584482007178L; } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/TestImplicitSubGroup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; import org.apache.deltaspike.core.api.scope.ConversationSubGroup; import org.apache.deltaspike.test.core.api.scope.conversation.subgroup.shared.TestGroup; @ConversationSubGroup(of = TestGroup.class, subGroup = {TestSubGroupContract.class}) public interface TestImplicitSubGroup { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/conversation/subgroup/uc003/TestSubGroupContract.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.conversation.subgroup.uc003; public interface TestSubGroupContract { String getValue(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/viewaccess/ViewAccessScopedBeanX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.viewaccess; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; import java.io.Serializable; @ViewAccessScoped public class ViewAccessScopedBeanX implements Serializable { private static final long serialVersionUID = -1291355584482007178L; private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/viewaccess/ViewAccessScopedBeanY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.viewaccess; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; import java.io.Serializable; @ViewAccessScoped public class ViewAccessScopedBeanY implements Serializable { private static final long serialVersionUID = -1291355584482007178L; private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/scope/viewaccess/ViewAccessScopedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.scope.viewaccess; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ViewAccessScopedTest { @Deployment public static WebArchive deploy() { String simpleName = ViewAccessScopedTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ViewAccessScopedTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject private ViewAccessScopedBeanX viewAccessScopedBeanX; @Inject private ViewAccessScopedBeanY viewAccessScopedBeanY; @Inject private DeltaSpikeContextExtension contextExtension; @Test public void usageOnOnePageTest() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); viewAccessScopedBeanY.setValue("y1"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); //no access contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } @Test public void usageOnOnePageTestAndNavigationAfterwards() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); viewAccessScopedBeanY.setValue("y1"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewB"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); } @Test public void usageOnTwoPagesTest1() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); viewAccessScopedBeanY.setValue("y1"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewB"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } @Test public void usageOnTwoPagesTest2() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); viewAccessScopedBeanY.setValue("y1"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewB"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } @Test public void usageOnOnePageDifferentRequests() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); viewAccessScopedBeanY.setValue("y1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); //no access contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } @Test public void usageOnOnePageDifferentRequestsAndNavigationAfterwards1() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); viewAccessScopedBeanY.setValue("y1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewB"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } @Test public void usageOnOnePageDifferentRequestsAndNavigationAfterwards2() { windowContext.activateWindow("w1"); viewAccessScopedBeanX.setValue("x1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("x1", viewAccessScopedBeanX.getValue()); viewAccessScopedBeanY.setValue("y1"); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewA"); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); contextExtension.getViewAccessScopedContext().onProcessingViewFinished("viewB"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertEquals("y1", viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w1"); windowContext.activateWindow("w2"); Assert.assertNull(viewAccessScopedBeanX.getValue()); Assert.assertNull(viewAccessScopedBeanY.getValue()); windowContext.closeWindow("w2"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util; public class MyBean { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/MyInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util; public interface MyInterface { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/MyInterfaceImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class MyInterfaceImpl implements MyInterface { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/ProxyUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util; import jakarta.inject.Inject; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.List; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ProxyUtilsTest { @Inject private MyBean myDependentScopedBean; @Inject private MyInterface myInterface; @Deployment public static Archive createTestArchive() { return ShrinkWrap .create(WebArchive.class, "proxyUtil.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addClasses(ProxyUtilsTest.class, MyBean.class, MyInterface.class, MyInterfaceImpl.class); } @Test public void testIsIntefaceProxy() { Object proxy = Proxy.newProxyInstance(myDependentScopedBean.getClass().getClassLoader(), new Class[] { MyInterface.class }, new InvocationHandler() { @Override public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { return null; } }); Assert.assertTrue(ProxyUtils.isInterfaceProxy(proxy.getClass())); } @Test public void testIsNotIntefaceProxy() { Assert.assertFalse(ProxyUtils.isInterfaceProxy(myDependentScopedBean.getClass())); } @Test public void testIsProxiedClass() { Assert.assertTrue(ProxyUtils.isProxiedClass(myInterface.getClass())); } @Test public void testIsNotProxiedClass() { Assert.assertFalse(ProxyUtils.isProxiedClass(myDependentScopedBean.getClass())); } @Test public void testGetUnproxiedClass() { Class clazz = ProxyUtils.getUnproxiedClass(myInterface.getClass()); Assert.assertEquals(clazz, MyInterfaceImpl.class); } @Test public void testGetProxyAndBaseTypes() { List> list = ProxyUtils.getProxyAndBaseTypes(myInterface.getClass()); Assert.assertEquals(list.size(), 2); Assert.assertTrue(ProxyUtils.isProxiedClass(list.get(0))); Assert.assertEquals(MyInterfaceImpl.class, list.get(1)); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/context/AbstractContextTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.context; import jakarta.enterprise.inject.spi.Extension; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * We test the AbstractContext by implementing a simple dummy context. */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class AbstractContextTest { /** * X TODO creating a WebArchive is only a workaround because JavaArchive * cannot contain other archives. */ @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap .create(JavaArchive.class, "abstractContextTest.jar") .addClass(AbstractContextTest.class) .addClass(DummyBean.class) .addAsManifestResource(BEANS_XML_ALL, "beans.xml") .addAsServiceProvider(Extension.class, DummyScopeExtension.class); return ShrinkWrap .create(WebArchive.class, "abstractContextTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } // This test is a hack yet due to a bug in the owb-arquillian and weld-arquillian containers // which needs to get fixed first. All tested containers so far do NOT respect the Extensions // from the ShrinkWrap archive but only the ones from the classpath. // Thus we had to add the Extension on the test-classpath. This means it will also // be available for all other tests (but only for 'embedded' containers. @Test public void testDummyContext() { DummyBean dummyBean = BeanProvider.getContextualReference(DummyBean.class); Assert.assertEquals(4711, dummyBean.getI()); dummyBean.setI(4712); DummyBean dummyBean2 = BeanProvider.getContextualReference(DummyBean.class); Assert.assertEquals(4712, dummyBean.getI()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/context/DummyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.context; import java.io.Serializable; /** */ @DummyScoped public class DummyBean implements Serializable { private int i = 4711; public int getI() { return i; } public void setI(int i) { this.i = i; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/context/DummyContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.context; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import org.apache.deltaspike.core.util.context.AbstractContext; import org.apache.deltaspike.core.util.context.ContextualStorage; /** * Non passivating scoped test context */ public class DummyContext extends AbstractContext { private boolean active = true; private boolean concurrent; private ContextualStorage storage = null; private BeanManager beanManager; public DummyContext(BeanManager beanManager, boolean concurrent) { super(beanManager); this.concurrent = concurrent; this.beanManager = beanManager; } @Override protected ContextualStorage getContextualStorage(Contextual contextual, boolean createIfNotExists) { if (storage == null && createIfNotExists) { storage = new ContextualStorage(beanManager, concurrent, isPassivatingScope()); } return storage; } @Override public Class getScope() { return DummyScoped.class; } @Override public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/context/DummyScopeExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.context; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.Extension; /** * Registers the {@link DummyContext} */ public class DummyScopeExtension implements Extension { private DummyContext context; public void registerDummyContext(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { context = new DummyContext(beanManager, true); afterBeanDiscovery.addContext(context); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/util/context/DummyScoped.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.util.context; import jakarta.enterprise.context.NormalScope; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Just a dummy test scope */ @Target( { TYPE, METHOD, FIELD }) @Retention(RUNTIME) @Documented @NormalScope(passivating = true) @Inherited public @interface DummyScoped { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/ActivatedClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.core.spi.activation.Deactivatable; /** * Class which isn't deactivated */ public class ActivatedClass implements Deactivatable { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/ClassDeactivationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.junit.Assert; import org.junit.Test; /** * Test for {@link org.apache.deltaspike.core.spi.activation.ClassDeactivator} */ public abstract class ClassDeactivationTest { /** * Tests if a class of the added package is active */ @Test public void testActivatedClass() { Assert.assertTrue(ClassDeactivationUtils.isActivated(ActivatedClass.class)); } /** * Tests if the class deactivated by {@link TestClassDeactivator} is recognized as such */ @Test public void testDeactivatedClass() { Assert.assertFalse(ClassDeactivationUtils.isActivated(DeactivatedClass.class)); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/ClassDeactivationWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ClassDeactivationWarFileTest extends ClassDeactivationTest { /** * NOTE: creating a WebArchive is only a workaround because JavaArchive cannot contain other archives. */ @Deployment public static WebArchive deploy() { String simpleName = ClassDeactivationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); URL fileUrl = ClassDeactivationWarFileTest.class.getClassLoader() .getResource(DeltaSpikeTest.DELTASPIKE_PROPERTIES); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "testClassDeactivationTest.jar") .addPackage(ClassDeactivationWarFileTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsResource(FileUtils.getFileForURL(fileUrl.toString()), DeltaSpikeTest.DELTASPIKE_PROPERTIES) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/DeactivatedClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.core.spi.activation.Deactivatable; /** * Class which is deactivated */ public class DeactivatedClass implements Deactivatable { } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/DefaultClassDeactivatorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.core.impl.activation.DefaultClassDeactivator; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @RunWith(Arquillian.class) public class DefaultClassDeactivatorTest extends ClassDeactivationTest { @Deployment public static WebArchive deploy() { String simpleName = DefaultClassDeactivatorTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); StringBuilder dsPropsBuilder = new StringBuilder(); dsPropsBuilder.append(ClassDeactivator.class.getName()).append("=") .append(DefaultClassDeactivator.class.getName()).append("\n") // this gets picked up on app servers, not when using an embedded impl .append(DefaultClassDeactivator.KEY_PREFIX).append(DeactivatedClass.class.getName()).append("=true").append("\n"); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "testClassDeactivationTest.jar") .addPackage(ClassDeactivationWarFileTest.class.getPackage()) .addClass(DefaultClassDeactivator.class) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsResource(new StringAsset(dsPropsBuilder.toString()), DeltaSpikeTest.DELTASPIKE_PROPERTIES) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test public void testViaInstantiatedCopyTheyAreDeactivated() { DefaultClassDeactivator defaultClassDeactivator = new DefaultClassDeactivator(); Boolean activated = defaultClassDeactivator.isActivated(ActivatedClass.class); assertNull(activated); Boolean deactivated = defaultClassDeactivator.isActivated(DeactivatedClass.class); assertFalse(deactivated); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/activation/TestClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.activation; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; /** * Test {@link org.apache.deltaspike.core.spi.activation.ClassDeactivator} * which is needed to test {@link org.apache.deltaspike.core.util.ClassDeactivationUtils} */ public class TestClassDeactivator implements ClassDeactivator { private static final long serialVersionUID = -3403907272881821406L; @Override public Boolean isActivated(Class targetClass) { if (targetClass.equals(DeactivatedClass.class)) { return Boolean.FALSE; } return null; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/cipher/DefaultCipherServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.cipher; import org.apache.deltaspike.core.impl.crypto.DefaultCipherService; import org.junit.Assert; import org.junit.Test; /** * Internal test for the DefaultCipherService. * Not intended to be a TCK for other CipherServices nor integration. */ public class DefaultCipherServiceTest { @Test public void testMasterPwdEncryption() throws Exception { DefaultCipherService cipherService = new DefaultCipherService(); String masterSalt = "deltaspike-test-salt"; cipherService.setMasterHash("newMasterPwd", masterSalt, true); String cleartext = "my cleartext sentence"; String encrypted = cipherService.encrypt(cleartext, masterSalt); String decrypted = cipherService.decrypt(encrypted, masterSalt); Assert.assertEquals(cleartext, decrypted); } @Test public void testMasterKeyOverwrite() throws Exception { DefaultCipherService cipherService = new DefaultCipherService(); String masterSalt = "deltaspike-test-salt"; cipherService.setMasterHash("newMasterPwd", masterSalt, true); try { cipherService.setMasterHash("newMasterPwd", masterSalt, false); Assert.fail(); } catch (Exception e) { // todo: how to log exception properly // System.out.println("expected: " + e); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/custom/spi/MyImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.custom.spi; public class MyImpl implements MyInterface { @Override public String getValue() { return "test"; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/custom/spi/MyInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.custom.spi; public interface MyInterface { String getValue(); } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/custom/spi/ServiceUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.custom.spi; import org.apache.deltaspike.core.util.ServiceUtils; import org.junit.Assert; import org.junit.Test; public abstract class ServiceUtilsTest { @Test public void lookupOfSpiImplementations() { Assert.assertTrue(ServiceUtils.loadServiceImplementations(MyInterface.class).iterator().hasNext()); Assert.assertNotNull(ServiceUtils.loadServiceImplementations(MyInterface.class)); Assert.assertFalse(ServiceUtils.loadServiceImplementations(MyInterface.class).isEmpty()); Assert.assertEquals(1, ServiceUtils.loadServiceImplementations(MyInterface.class).size()); Assert.assertEquals( "test", ServiceUtils.loadServiceImplementations(MyInterface.class).iterator().next().getValue()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/custom/spi/ServiceUtilsWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.custom.spi; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ServiceUtilsWarFileTest extends ServiceUtilsTest { @Deployment public static WebArchive deploy() { String simpleName = ServiceUtilsWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ServiceUtilsWarFileTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) //due to an issue with arquillian we can just add it to the web-archive (and not the jar) .addAsServiceProvider(MyInterface.class, MyImpl.class) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/future/FutureableTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.future; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.apache.deltaspike.core.impl.future.FutureableInterceptor; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.descriptor.api.Descriptors; import org.jboss.shrinkwrap.descriptor.api.beans10.BeansDescriptor; @RunWith(Arquillian.class) public class FutureableTest { @Deployment public static WebArchive deploy() { // create beans.xml with added interceptor BeansDescriptor beans = Descriptors.create(BeansDescriptor.class); beans.getOrCreateInterceptors().clazz(FutureableInterceptor.class.getName()); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "FutureableTest.jar") .addPackage(Service.class.getPackage().getName()) .addAsManifestResource(new StringAsset(beans.exportAsString()), "beans.xml"); return ShrinkWrap.create(WebArchive.class, "FutureableTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private Service service; @Test public void voidTest() { CountDownLatch latch = new CountDownLatch(1); service.thatSLong(1000, latch); try { if (!latch.await(2000, TimeUnit.MILLISECONDS)) { fail("Asynchronous call should have terminated"); } } catch (final InterruptedException e) { Thread.interrupted(); fail(); } } @Test public void future() { final Future future = service.thatSLong(1000); int count = 0; for (int i = 0; i < 1000; i++) { if (future.isDone()) { break; } count++; } try { assertEquals("done", future.get()); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } catch (final ExecutionException e) { fail(e.getMessage()); } assertEquals(1000, count); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/future/Service.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.future; import org.apache.deltaspike.core.api.future.Futureable; import jakarta.enterprise.context.ApplicationScoped; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @ApplicationScoped public class Service { @Futureable public void thatSLong(final long sleep, CountDownLatch latch) { try { Thread.sleep(sleep); latch.countDown(); } catch (final InterruptedException e) { Thread.interrupted(); throw new IllegalStateException(e); } } @Futureable // or CompletableFuture public Future thatSLong(final long sleep) { try { Thread.sleep(sleep); // return CompletableFuture.completedFuture("done"); return new Future() // EE will have AsyncFuture but more designed for j8 ^^ { @Override public boolean cancel(final boolean mayInterruptIfRunning) { return false; } @Override public boolean isCancelled() { return false; } @Override public boolean isDone() { return true; } @Override public String get() throws InterruptedException, ExecutionException { return "done"; } @Override public String get(final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return "done"; } }; } catch (final InterruptedException e) { Thread.interrupted(); throw new IllegalStateException(e); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/future/ThreadPoolManagerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.future; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.impl.config.PropertiesConfigSource; import org.apache.deltaspike.core.impl.future.ThreadPoolManager; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.util.Collections; import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import org.apache.deltaspike.test.util.ArchiveUtils; @RunWith(Arquillian.class) public class ThreadPoolManagerTest { @Deployment public static WebArchive deploy() { return ShrinkWrap.create(WebArchive.class, "ThreadPoolManagerTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private ThreadPoolManager manager; @Test public void defaultPool() throws ExecutionException, InterruptedException { final ExecutorService auto = manager.find("auto"); assertEquals(auto, auto); assertSame(auto, auto); assertEquals(Runtime.getRuntime().availableProcessors(), ThreadPoolExecutor.class.cast(auto).getCorePoolSize()); assertUsable(auto); } @Test // this test validates we read the config properly but also it is lazy public void configuredPool() throws ExecutionException, InterruptedException { ConfigResolver.addConfigSources(Collections.singletonList(new PropertiesConfigSource(new Properties() {{ setProperty("futureable.pool.custom.coreSize", "5"); }}) { @Override public String getConfigName() { return "configuredPool"; } })); final ExecutorService custom = manager.find("custom"); assertEquals(custom, custom); assertSame(custom, custom); assertEquals(5, ThreadPoolExecutor.class.cast(custom).getCorePoolSize()); assertUsable(custom); } private void assertUsable(final ExecutorService pool) throws InterruptedException, ExecutionException { assertEquals("ok", pool.submit(new Callable() { @Override public String call() throws Exception { return "ok"; } }).get()); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/interdyn/InterDynTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.interdyn; import org.apache.deltaspike.core.impl.monitoring.InvocationMonitorInterceptor; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class InterDynTest { /** * We need to configure this in META-INF/apache-deltaspike.properties in the test classpath * for in-process Arquillian containers like OWB and Weld, * and additionally via @Deployment for container based Arquillians */ private final static String CONFIG = "# InterDynTest\n" + "deltaspike.interdyn.enabled=true\n" + "deltaspike.interdyn.rule.1.match=org\\\\.apache\\\\.deltaspike\\\\.test\\\\.core\\\\.impl\\\\.interdyn\\\\.Some.*Service\n" + "deltaspike.interdyn.rule.1.annotation=org.apache.deltaspike.core.api.monitoring.InvocationMonitored\n"; private final static String BEANS_XML = "" + InvocationMonitorInterceptor.class.getName() + ""; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "InterDynTest.jar") .addPackage(SomeTestService.class.getPackage().getName()) .addAsManifestResource(new StringAsset(BEANS_XML), "beans.xml") .addAsManifestResource(new StringAsset(CONFIG), "apache-deltaspike.properties"); return ShrinkWrap.create(WebArchive.class, "InterDynTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private SomeTestService service; @Test public void invokeServiceMethods() { service.enableChecking(); service.pingA(); service.pingB(); service.pingA(); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/interdyn/SomeTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.interdyn; import org.apache.deltaspike.core.api.monitoring.MonitorResultEvent; import org.junit.Assert; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; @ApplicationScoped public class SomeTestService { private boolean check = false; private MonitorResultEvent mre; public String pingA() { return "a"; } public String pingB() { try { Thread.sleep(30L); } catch (InterruptedException e) { // all fine } return "b"; } public void enableChecking() { this.check = true; } public MonitorResultEvent getMonitorResultEvent() { return mre; } public void observer(@Observes MonitorResultEvent mre) { this.mre = mre; if (check) { Assert.assertTrue(mre.getClassInvocations().keySet().contains(SomeTestService.class.getName())); check = false; } } @PreDestroy public void verifyMonitorResultEvent() { Assert.assertNotNull(mre); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/CustomProperties.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxManaged; import org.apache.deltaspike.core.api.jmx.MBean; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @MBean(category = "cat", type = "and", name = "", properties = "foo=bar,dummy=empty") public class CustomProperties { @JmxManaged private int counter; public int getCounter() { return counter; } public void setCounter(final int counter) { this.counter = counter; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/CustomProperties2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxManaged; import org.apache.deltaspike.core.api.jmx.MBean; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @MBean(category = "cat", type = "and", name = "nom", properties = "foo=bar,dummy=empty") public class CustomProperties2 { @JmxManaged private int counter; public int getCounter() { return counter; } public void setCounter(final int counter) { this.counter = counter; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/CustomPropertiesTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class CustomPropertiesTest { @Deployment public static Archive war() { return ShrinkWrap.create(WebArchive.class, "CustomPropertiesTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addClasses(CustomProperties.class, CustomProperties2.class); } @Inject private CustomProperties myMBean; @Test public void checkMBean() throws Exception { assertTrue(ManagementFactory.getPlatformMBeanServer().isRegistered( new ObjectName("cat:type=and,foo=bar,dummy=empty"))); assertTrue(ManagementFactory.getPlatformMBeanServer().isRegistered( new ObjectName("cat:type=and,name=nom,foo=bar,dummy=empty"))); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/CustomType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxManaged; import org.apache.deltaspike.core.api.jmx.MBean; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @MBean(category = "cat", type = "and", name = "fish") public class CustomType { @JmxManaged private int counter; public int getCounter() { return counter; } public void setCounter(final int counter) { this.counter = counter; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/CustomTypeTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import javax.management.MBeanServer; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @RunWith(Arquillian.class) public class CustomTypeTest { @Deployment public static Archive war() { return ShrinkWrap.create(WebArchive.class, "CustomTypeTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml") .addClasses(CustomType.class); } @Inject private CustomType myMBean; @Test public void checkMBean() throws Exception { final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); myMBean.setCounter(0); assertEquals(0, myMBean.getCounter()); myMBean.setCounter(2); final ObjectName on = new ObjectName("cat:type=and,name=fish"); assertTrue(server.isRegistered(on)); assertEquals(2, server.getAttribute(on, "counter")); myMBean.setCounter(5); assertEquals(5, server.getAttribute(on, "counter")); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/MyMBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.core.api.jmx.JmxBroadcaster; import org.apache.deltaspike.core.api.jmx.JmxManaged; import org.apache.deltaspike.core.api.jmx.JmxParameter; import org.apache.deltaspike.core.api.jmx.MBean; import org.apache.deltaspike.core.api.jmx.Table; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import javax.management.Notification; import java.util.HashMap; import java.util.Map; @ApplicationScoped @MBean(description = "my mbean") public class MyMBean { @JmxManaged(description = "get counter") private int counter = 0; @Inject private JmxBroadcaster broadcaster; @JmxManaged private Map table; @JmxManaged // just a marker to expose it as an attribute, will call the getter private Table table2; public Map getTable() { return table != null ? table : (table = new HashMap() {{ put("key1", "value1"); put("key2", "value2"); }}); } @JmxManaged public Table getTable2() { return new Table().withColumns("a", "b", "c").withLine("1", "2", "3").withLine("alpha", "beta", "gamma"); } public int getCounter() { return counter; } public void setCounter(final int v) { counter = v; } public void resetTo(final int value) { counter = value; } @JmxManaged(description = "multiply counter") public int multiply(@JmxParameter(name = "multiplier", description = "the multiplier") final int n) { return counter * n; } public void broadcast() { broadcaster.send(new Notification(String.class.getName(), this, 10L)); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.junit.Assert; import org.junit.Test; import jakarta.inject.Inject; import javax.management.Attribute; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.MBeanServer; import javax.management.Notification; import javax.management.NotificationListener; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; public abstract class SimpleRegistrationTest { private static MBeanServer server = ManagementFactory.getPlatformMBeanServer(); @Inject private MyMBean myMBean; @Test public void checkMBean() throws Exception { assertEquals(0, myMBean.getCounter()); myMBean.resetTo(2); final ObjectName on = new ObjectName("org.apache.deltaspike:type=MBeans,name=" + MyMBean.class.getName()); assertTrue(server.isRegistered(on)); assertEquals(2, server.getAttribute(on, "counter")); assertEquals(6, server.invoke(on, "multiply", new Object[]{3}, new String[0])); myMBean.resetTo(5); assertEquals(5, server.getAttribute(on, "counter")); assertEquals(20, server.invoke(on, "multiply", new Object[]{4}, new String[0])); server.setAttribute(on, new Attribute("counter", 10)); assertEquals(10, myMBean.getCounter()); final Collection notifications = new ArrayList(); server.addNotificationListener(on, new NotificationListener() { @Override public void handleNotification(final Notification notification, final Object handback) { notifications.add(notification); } }, null, null); myMBean.broadcast(); assertEquals(1, notifications.size()); assertEquals(10L, notifications.iterator().next().getSequenceNumber()); MBeanInfo mBeanInfo = server.getMBeanInfo(on); Assert.assertNotNull(mBeanInfo); MBeanOperationInfo[] operations = mBeanInfo.getOperations(); Assert.assertNotNull(operations); Assert.assertTrue(operations.length > 0); Assert.assertTrue("Empty Signature on operation: " + operations[1], operations[1].getSignature().length > 0); MBeanParameterInfo parameterInfo = operations[1].getSignature()[0]; assertEquals("multiplier", parameterInfo.getName()); assertEquals("the multiplier", parameterInfo.getDescription()); { // table support - through map Object table = server.getAttribute(on, "table"); assertTrue(TabularData.class.isInstance(table)); final TabularData data = TabularData.class.cast(table); assertEquals(1, data.size()); final CompositeData compositeData = CompositeData.class.cast(data.values().iterator().next()); assertEquals(2, compositeData.values().size()); assertEquals("value1", compositeData.get("key1")); assertEquals("value2", compositeData.get("key2")); } { // table support - through Table Object table = server.getAttribute(on, "table2"); assertTrue(TabularData.class.isInstance(table)); final TabularData data = TabularData.class.cast(table); assertEquals(2, data.size()); final Iterator iterator = data.values().iterator(); { final CompositeData compositeData = CompositeData.class.cast(iterator.next()); assertEquals(3, compositeData.values().size()); assertEquals("1", compositeData.get("a")); assertEquals("2", compositeData.get("b")); assertEquals("3", compositeData.get("c")); } { final CompositeData compositeData = CompositeData.class.cast(iterator.next()); assertEquals(3, compositeData.values().size()); assertEquals("alpha", compositeData.get("a")); assertEquals("beta", compositeData.get("b")); assertEquals("gamma", compositeData.get("c")); } } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/jmx/SimpleRegistrationWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.jmx; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class SimpleRegistrationWarFileTest extends SimpleRegistrationTest { @Deployment public static WebArchive deploy() { String simpleName = SimpleRegistrationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "simpleRegistrationTest.jar") .addPackage(SimpleRegistrationWarFileTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/lock/LockedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.lock; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import org.apache.deltaspike.core.impl.lock.LockedInterceptor; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.descriptor.api.Descriptors; import org.jboss.shrinkwrap.descriptor.api.beans10.BeansDescriptor; @RunWith(Arquillian.class) public class LockedTest { @Deployment public static WebArchive deploy() { // create beans.xml with added interceptor BeansDescriptor beans = Descriptors.create(BeansDescriptor.class); beans.getOrCreateInterceptors().clazz(LockedInterceptor.class.getName()); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "LockedTest.jar") .addPackage(Service.class.getPackage().getName()) .addAsManifestResource(new StringAsset(beans.exportAsString()), "beans.xml"); return ShrinkWrap.create(WebArchive.class, "LockedTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(new StringAsset(beans.exportAsString()), "beans.xml"); } @Inject private Service service; @Test public void simpleNotConcurrent() { final CountDownLatch synchro = new CountDownLatch(1); final Thread writer = new Thread() { @Override public void run() { service.write("test", "value"); synchro.countDown(); } }; final CountDownLatch end = new CountDownLatch(1); final AtomicReference val = new AtomicReference(); final Thread reader = new Thread() { @Override public void run() { try { synchro.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } val.set(service.read("test")); end.countDown(); } }; reader.start(); writer.start(); try { end.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } assertEquals("value", val.get()); } @Test public void concurrentTimeout() { final AtomicBoolean doAgain = new AtomicBoolean(true); final CountDownLatch endWriter = new CountDownLatch(1); final Thread writer = new Thread() { @Override public void run() { while (doAgain.get()) { service.write("test", "value"); service.force(); } endWriter.countDown(); } }; final CountDownLatch endReader = new CountDownLatch(1); final Thread reader = new Thread() { @Override public void run() { while (doAgain.get()) { try { service.read("test"); } catch (final IllegalStateException e) { doAgain.set(false); } } endReader.countDown(); } }; reader.start(); writer.start(); try { endReader.await(1, TimeUnit.MINUTES); endWriter.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } assertEquals("value", service.read("test")); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/lock/Service.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.lock; import org.apache.deltaspike.core.api.lock.Locked; import jakarta.enterprise.context.ApplicationScoped; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import static org.apache.deltaspike.core.api.lock.Locked.Operation.WRITE; import static org.junit.Assert.fail; @ApplicationScoped public class Service { private final Map entries = new HashMap(); @Locked(timeout = 1, timeoutUnit = TimeUnit.SECONDS) public String read(final String k) { return entries.get(k); } @Locked(timeout = 1, timeoutUnit = TimeUnit.SECONDS, operation = WRITE) public void write(final String k, final String v) { entries.put(k, v); } @Locked(operation = WRITE) public void force() { try { Thread.sleep(TimeUnit.SECONDS.toMillis(5)); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/scope/window/DefaultWindowContextTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.scope.window; import jakarta.inject.Inject; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.Assert; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class DefaultWindowContextTest { @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultWindowContextTest.jar") .addPackage(DefaultWindowContextTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "defaultWindowContextTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private WindowContext windowContext; @Inject private SomeWindowScopedBean someWindowScopedBean; /** * Tests {@link org.apache.deltaspike.core.impl.util.JndiUtils#lookup(String, Class)} by looking up the {@link jakarta.enterprise.inject.spi.BeanManager} */ @Test public void testWindowScoedBean() { Assert.assertNotNull(windowContext); Assert.assertNotNull(someWindowScopedBean); { windowContext.activateWindow("window1"); someWindowScopedBean.setValue("Hans"); Assert.assertEquals("Hans", someWindowScopedBean.getValue()); } // now we switch it away to another 'window' { windowContext.activateWindow("window2"); Assert.assertNull(someWindowScopedBean.getValue()); someWindowScopedBean.setValue("Karl"); Assert.assertEquals("Karl", someWindowScopedBean.getValue()); } // and now back to the first window { windowContext.activateWindow("window1"); // which must still contain the old value Assert.assertEquals("Hans", someWindowScopedBean.getValue()); } // and again back to the second window { windowContext.activateWindow("window2"); // which must still contain the old value of the 2nd window Assert.assertEquals("Karl", someWindowScopedBean.getValue()); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/scope/window/SomeWindowScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.scope.window; import java.io.Serializable; import org.apache.deltaspike.core.api.scope.WindowScoped; /** * example bean for @WindowScoped */ @WindowScoped public class SomeWindowScopedBean implements Serializable { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/throttling/Service.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.throttling; import org.apache.deltaspike.core.api.throttling.Throttled; import jakarta.enterprise.context.ApplicationScoped; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; import static org.junit.Assert.fail; @ApplicationScoped public class Service { private final Map entries = new HashMap(); @Throttled(timeout = 1, timeoutUnit = TimeUnit.SECONDS) public String read(final String k) { return entries.get(k); } @Throttled(timeout = 1, timeoutUnit = TimeUnit.SECONDS) public void write(final String k, final String v) { entries.put(k, v); } @Throttled public void force() { try { Thread.sleep(TimeUnit.SECONDS.toMillis(5)); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/throttling/Service2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.throttling; import org.apache.deltaspike.core.api.throttling.Throttled; import org.apache.deltaspike.core.api.throttling.Throttling; import jakarta.enterprise.context.ApplicationScoped; import java.util.ArrayList; import java.util.Collection; @Throttling(permits = 2) @ApplicationScoped public class Service2 { private final Collection called = new ArrayList(); @Throttled(timeout = 750) public void call(final String k) { synchronized (called) { called.add(k); } try { Thread.sleep(1000); } catch (final InterruptedException e) { Thread.interrupted(); } } @Throttled(weight = 2) public void heavy(final Runnable inTask) { inTask.run(); try { Thread.sleep(5000); } catch (final InterruptedException e) { Thread.interrupted(); } } public Collection getCalled() { return called; } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/throttling/ThrottledTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.throttling; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.util.HashSet; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import static java.util.Arrays.asList; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ThrottledTest { @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "ThrottledTest.jar") .addPackage(Service.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, "ThrottledTest.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Inject private Service service; @Inject private Service2 service2; @Test public void permits() { {// failling case now final AtomicReference failed = new AtomicReference(); final CountDownLatch latch = new CountDownLatch(2); final Thread[] concurrents = new Thread[] { new Thread() { @Override public void run() { service2.heavy(new Runnable() { @Override public void run() { latch.countDown(); } }); } }, new Thread() { @Override public void run() { try { latch.await(); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } try { service2.call("failed"); fail(); } catch (final IllegalStateException ise) { failed.set(ise); } } } }; for (final Thread t : concurrents) { t.start(); } latch.countDown(); waitForThreads(concurrents); assertNotNull(failed.get()); assertThat(failed.get(), instanceOf(IllegalStateException.class)); } { // passing final CountDownLatch latch = new CountDownLatch(1); final Thread[] concurrents = new Thread[] { new Thread() { @Override public void run() { try { latch.await(); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } service2.call("1"); } }, new Thread() { @Override public void run() { try { latch.await(); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } service2.call("2"); } } }; for (final Thread t : concurrents) { t.start(); } latch.countDown(); waitForThreads(concurrents); assertEquals(new HashSet(asList("1", "2")), new HashSet(service2.getCalled())); } } private void waitForThreads(final Thread[] concurrents) { for (final Thread t : concurrents) { try { t.join(); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } } } @Test public void simpleNotConcurrent() { // ~lock case final CountDownLatch synchro = new CountDownLatch(1); final Thread writer = new Thread() { @Override public void run() { service.write("test", "value"); synchro.countDown(); } }; final CountDownLatch end = new CountDownLatch(1); final AtomicReference val = new AtomicReference(); final Thread reader = new Thread() { @Override public void run() { try { synchro.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } val.set(service.read("test")); end.countDown(); } }; reader.start(); writer.start(); try { end.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } assertEquals("value", val.get()); } @Test public void concurrentTimeout() { final AtomicBoolean doAgain = new AtomicBoolean(true); final CountDownLatch endWriter = new CountDownLatch(1); final Thread writer = new Thread() { @Override public void run() { while (doAgain.get()) { service.write("test", "value"); service.force(); } endWriter.countDown(); } }; final CountDownLatch endReader = new CountDownLatch(1); final Thread reader = new Thread() { @Override public void run() { while (doAgain.get()) { try { service.read("test"); } catch (final IllegalStateException e) { doAgain.set(false); } } endReader.countDown(); } }; reader.start(); writer.start(); try { endReader.await(1, TimeUnit.MINUTES); endWriter.await(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { Thread.interrupted(); fail(); } assertEquals("value", service.read("test")); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/util/JndiUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.util; import org.apache.deltaspike.core.impl.util.JndiUtils; import org.junit.Test; import jakarta.enterprise.inject.spi.BeanManager; import java.util.Map; import static org.junit.Assert.assertNotNull; public abstract class JndiUtilsTest { /** * Tests {@link JndiUtils#lookup(String, Class)} by looking up the {@link BeanManager} */ @Test public void testLookup() { BeanManager beanManager = JndiUtils.lookup("java:comp/BeanManager", BeanManager.class); assertNotNull("JNDI lookup failed", beanManager); } /** * Tests {@link JndiUtils#list(String, Class)} by digging in java:comp namespace */ @Test public void testList() { Map beanManager = JndiUtils.list("java:comp", BeanManager.class); assertNotNull("JNDI lookup failed", beanManager); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/impl/util/JndiUtilsWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.impl.util; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class JndiUtilsWarFileTest extends JndiUtilsTest { @Deployment public static WebArchive deploy() { String simpleName = JndiUtilsWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "jndiTest.jar") .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addPackage(JndiUtilsWarFileTest.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.core.api.util.context.DummyContext; import org.apache.deltaspike.test.core.api.util.context.DummyScopeExtension; import org.apache.deltaspike.test.core.api.util.context.DummyScoped; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * This class contains helpers for building frequently used archives */ public class ArchiveUtils { public static JavaArchive[] getDeltaSpikeCoreArchive() { return getDeltaSpikeCoreArchive(null); } public static JavaArchive[] getDeltaSpikeCoreArchive(String[] excludedPackagesOrFiles) { // we also need quite some internal Arquillian classes on the client side // this JAR has NO beans.xml to prevent class scanning! JavaArchive extensionsJar = ShrinkWrap .create(JavaArchive.class, "testExtensions.jar") .addClass(ArchiveUtils.class) .addClass(DummyScopeExtension.class) .addClass(DummyScoped.class) .addClass(DummyContext.class) .addPackage(WebProfileCategory.class.getPackage()); JavaArchive[] coreArchives = ShrinkWrapArchiveUtil.getArchives(null, "META-INF/beans.xml", new String[]{"org.apache.deltaspike.core", "org.apache.deltaspike.test.category"}, excludedPackagesOrFiles, "ds-core"); List archives = new ArrayList(Arrays.asList(coreArchives)); archives.add(extensionsJar); return archives.toArray(new JavaArchive[archives.size()]); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/FileUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util; import java.io.File; import java.net.MalformedURLException; import java.net.URL; /** * Some basic utils */ public class FileUtils { private FileUtils() { // prevent instantiation } /** * @param url the target URL * @return a file created based on the given URL */ public static File getFileForURL(String url) { //fix for wls if(!url.startsWith("file:/")) { url = "file:/" + url; } url = url.replaceAll("%20", " "); try { return new File( (new URL(url)).getFile()); } catch (MalformedURLException e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/EditableTestDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util.activation; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import java.util.HashMap; import java.util.Map; public class EditableTestDeactivator implements ClassDeactivator { private static Map, Boolean> result = new HashMap, Boolean>(); @Override public Boolean isActivated(Class targetClass) { return result.get(targetClass); } public static void activate(Class classToActivate) { result.put(classToActivate, true); } public static void deactivate(Class classToActivate) { result.put(classToActivate, false); } } ================================================ FILE: deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/util/activation/ProjectStageDependentClassDeactivationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util.activation; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.junit.Assert; import org.junit.Test; public class ProjectStageDependentClassDeactivationTest { @Test public void deactivationResultInProjectStageUnitTest() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck)); } @Test public void deactivationResultInProjectStageDevelopment() { ProjectStageProducer.setProjectStage(ProjectStage.Development); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck)); } @Test public void deactivationResultInProjectStageProduction() { ProjectStageProducer.setProjectStage(ProjectStage.Production); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result } @Test public void deactivationResultInProjectStageIntegrationTest() { ProjectStageProducer.setProjectStage(ProjectStage.IntegrationTest); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result } @Test public void deactivationResultInProjectStageStaging() { ProjectStageProducer.setProjectStage(ProjectStage.Staging); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result } @Test public void deactivationResultInProjectStageSystemTest() { ProjectStageProducer.setProjectStage(ProjectStage.SystemTest); final Class classToCheck = TestDeactivatable.class; EditableTestDeactivator.activate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); EditableTestDeactivator.deactivate(classToCheck); Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result } private static class TestDeactivatable implements Deactivatable { } } ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # by providing an application name we trigger the JMX registration! deltaspike.application.name=ds-config-core-impl-tests testProperty03=test_value_03 org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.test.core.impl.activation.TestClassDeactivator testProperty02=test_value_02 db=prodDB testDbConfig=some setting for ${db} globalAlternatives.org.apache.deltaspike.test.core.api.alternative.global.BaseBean1=org.apache.deltaspike.test.core.api.alternative.global.SubBaseBean2 globalAlternatives.org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1=org.apache.deltaspike.test.core.api.alternative.global.BaseInterface1AlternativeImplementation globalAlternatives.org.apache.deltaspike.test.core.api.alternative.global.qualifier.BaseInterface=org.apache.deltaspike.test.core.api.alternative.global.qualifier.AlternativeBaseBeanB configProperty1=14 configProperty2=7 configPropertyTrue1=Yes configPropertyTrue2=yes configPropertyTrue3=YES configPropertyTrue4=Y configPropertyTrue5=JA configPropertyTrue6=OUI configPropertyTrue7=True configPropertyTrue8=1 # NumberConfig propertyFloat=123.45 my.very.secret=onlyIDoKnowIt deactivate.org.apache.deltaspike.test.core.impl.activation.DeactivatedClass=true urlListFromProperties = http://127.0.0.2 prefix.suffix = done # test project stage aware replacement mechanism # Attention: Depending on whether another test did already run we might get # ProjectStage Production or UnitTest. So we set the same value for both now myapp.login.hostname=http://myapp myapp.login.hostname.Production=https://myapp myapp.login.hostname.UnitTest=https://myapp myapp.login.url=${myapp.login.hostname}/login.xhtml # tree based configuration myapp.some.server.host=myserver myapp.some.server.port=80 myapp.some.server.path=/myapp/endpoint1 myapp.other.server.host=otherserver myapp.other.server.port=443 myapp.other.server.path=/otherapp/endpoint2 # for InterDynTest # We need to configure this here for in-process Arquillian containers like OWB and Weld, # and additionally via @Deployment for container based Arquillians deltaspike.interdyn.enabled=true deltaspike.interdyn.rule.1.match=org\\.apache\\.deltaspike\\.test\\.core\\.impl\\.interdyn\\.Some.*Service deltaspike.interdyn.rule.1.annotation=org.apache.deltaspike.core.api.monitoring.InvocationMonitored ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # registers the DummyScope for the AbstractContextTest org.apache.deltaspike.test.core.api.util.context.DummyScopeExtension ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.api.config.PropertyFileConfig ================================================ # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # dummy PropertyFileConfig which gets picked up at boot time org.apache.deltaspike.test.core.api.config.propertyconfigsource.MyCustomBootTimePropertyFileConfig ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.api.projectstage.ProjectStageHolder ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # Test file to register a test ProjectStageHolder which contains # a few additional ProjectStages org.apache.deltaspike.test.core.api.projectstage.TestProjectStages ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigFilter ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.core.api.config.SecretTestConfigFilter ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource ================================================ ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.test.core.api.config.TestConfigSource org.apache.deltaspike.test.core.api.config.ConfigurableTestConfigSource ================================================ FILE: deltaspike/core/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSourceProvider ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.core.api.config.TestConfigSourceProvider ================================================ FILE: deltaspike/core/impl/src/test/resources/application.xml ================================================ ejb-jar.jar test.war test lib ================================================ FILE: deltaspike/core/impl/src/test/resources/customMinimalMessage_en.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # sayHello=Hello %s text=Text ================================================ FILE: deltaspike/core/impl/src/test/resources/myboottimeconfig.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # a user defined property file which is available during container boot already deltaspike_ordinal = 120 some.boottimekey = correctvalue ================================================ FILE: deltaspike/core/impl/src/test/resources/myconfig.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # a user defined property file some.propertykey = somevalue some.boottimekey = wrongvalue configproperty.test.string = stringValue configproperty.test.string.UnitTest = psAwareStringValue configproperty.test.string.paramvalue.UnitTest = parameterizedPsAwareStringValue configproperty.test.param = paramvalue configproperty.test.boolean = false configproperty.test.class = org.apache.deltaspike.test.core.api.config.propertyconfigsource.MyBean configproperty.test.int = 5 configproperty.test.long = 8589934592 configproperty.test.float = -1.1 configproperty.test.double = 4e40 ================================================ FILE: deltaspike/core/impl/src/test/resources/mynotpickedupconfig.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # a user defined property file which is not being activated at all deltaspike_ordinal = 130 some.boottimekey = this value should not get picked up at all! ================================================ FILE: deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/MessageFormattedMessage.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # welcomeTo = Welcome to {0} incomeSinceDays = The income since {0} days is {1} commitsInProject = At {0,time} on {0,date}, project {1} had {2,number,integer} commits. ================================================ FILE: deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/MinimalMessages_en.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # sayHello=Hello %s ================================================ FILE: deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages_de.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # hello=Test Nachricht an %s ================================================ FILE: deltaspike/core/impl/src/test/resources/org/apache/deltaspike/test/core/api/message/TestMessages_en.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # welcome_to=Welcome to %s welcome_to_deltaspike=Welcome to DeltaSpike hello=test message to %s categoryMessage=Value %s was set categoryMessage_longText=The value of the property has been set to %s. ================================================ FILE: deltaspike/core/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent-code 2.0.2-SNAPSHOT ../parent/code/pom.xml org.apache.deltaspike.core core-project pom Apache DeltaSpike Core api impl ================================================ FILE: deltaspike/dist/bom/pom.xml ================================================ 4.0.0 org.apache.deltaspike.distribution distributions-project 2.0.2-SNAPSHOT org.apache.deltaspike.distribution distributions-bom 2.0.2-SNAPSHOT pom Apache DeltaSpike Distribution Bill of Materials UTF-8 UTF-8 11 11 org.apache.deltaspike.core deltaspike-core-api ${project.version} compile org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-security-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-security-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-jpa-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jsf-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-jsf-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-data-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-data-module-impl ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} compile org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-openejb ${project.version} runtime org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-partial-bean-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-test-control-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-test-control-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-scheduler-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-scheduler-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-proxy-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-proxy-module-impl-asm ${project.version} runtime ================================================ FILE: deltaspike/dist/full/pom.xml ================================================ 4.0.0 org.apache.deltaspike.distribution distributions-project 2.0.2-SNAPSHOT distribution-full pom Apache DeltaSpike Full Distribution true org.apache.deltaspike.core deltaspike-core-api ${project.version} compile org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-security-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-security-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-jpa-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jsf-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-jsf-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-data-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-data-module-impl ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} compile org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-openejb ${project.version} runtime org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-partial-bean-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-test-control-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-test-control-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-scheduler-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-scheduler-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-proxy-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-proxy-module-impl-asm ${project.version} runtime org.apache.maven.plugins maven-assembly-plugin 3.2.0 assemble package single ${noAssembly} src/main/distribution/assembly.xml false deltaspike-full-${project.version} distribution false apache-release false org.apache.maven.plugins maven-install-plugin true org.apache.maven.plugins maven-gpg-plugin sign-artifacts verify sign ================================================ FILE: deltaspike/dist/full/src/main/distribution/assembly.xml ================================================ distribution zip tar.gz ${project.basedir}/../.. README* LICENSE* NOTICE* . true org.apache.deltaspike.modules:* ${artifact.artifactId}-${project.version}.${artifact.extension} modules org.apache.deltaspike.core:* ${artifact.artifactId}-${project.version}.${artifact.extension} core org.apache.deltaspike.cdictrl:* ${artifact.artifactId}-${project.version}.${artifact.extension} cdictrl src/main/distribution/core-module.xml core module.xml true src/main/distribution/cdictrl-module.xml cdictrl module.xml true src/main/distribution/modules-module.xml modules module.xml true ================================================ FILE: deltaspike/dist/full/src/main/distribution/cdictrl-module.xml ================================================ ================================================ FILE: deltaspike/dist/full/src/main/distribution/core-module.xml ================================================ ================================================ FILE: deltaspike/dist/full/src/main/distribution/modules-module.xml ================================================ ================================================ FILE: deltaspike/dist/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.distribution distributions-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Distribution bom full ================================================ FILE: deltaspike/examples/data-examples/README.md ================================================ Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Data Module for DeltaSpike ========================== This example shows: 1, how to use JPA in deltaspike; 2, how to use the Data module for repositories; 3, the function of @Transactional, how @Transactional save entity automatically. ================================================ FILE: deltaspike/examples/data-examples/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-data-examples Apache DeltaSpike Data Examples war true org.apache.deltaspike.core deltaspike-core-api org.apache.deltaspike.core deltaspike-core-impl org.apache.deltaspike.modules deltaspike-jsf-module-api org.apache.deltaspike.modules deltaspike-jsf-module-impl org.apache.deltaspike.modules deltaspike-jpa-module-api org.apache.deltaspike.modules deltaspike-jpa-module-impl org.apache.deltaspike.modules deltaspike-data-module-api org.apache.deltaspike.modules deltaspike-data-module-impl org.apache.tomee jakartaee-api org.apache.myfaces.core myfaces-api compile ${project.artifactId} ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/Article.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.io.Serializable; import java.util.Date; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; @Entity @Table(name = "articles") public class Article implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; private String title; private String content; @Temporal(TemporalType.TIMESTAMP) @Column(name = "time_created") private Date date; // A must have! public Article() { // this form used by Hibernate } public Article(String title, Date date) { // for application use, to create new articles this.title = title; this.date = date; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "Article{" + "id=" + id + ", title=" + title + ", content=" + content + ", date=" + date + '}'; } } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/ArticleController.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.logging.Logger; import jakarta.faces.application.FacesMessage; import jakarta.faces.view.ViewScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.transaction.Transactional; @Named @ViewScoped @Transactional public class ArticleController implements Serializable { private Article article = new Article(); @Inject private Logger log; @Inject private ArticleRepository articleRepository; @Inject private FacesContext facesContext; @HttpParam("aid") @Inject private String aid; // article id public Article getArticle() { return article; } public void setArticle(Article article) { this.article = article; } public Article findArticleById(Long id) { article = articleRepository.findBy(id); return article; } public String persist() { article.setDate(new Date()); articleRepository.save(this.article); facesContext.addMessage(null, new FacesMessage("article:" + article.getTitle() + " persisted")); return "persisted"; } public String delete(Article article) { articleRepository.remove(article); facesContext.addMessage(null, new FacesMessage("article:" + article.getTitle() + " deleted")); return "deleted"; } public List
getAllArticles() { return articleRepository.findAll(); } public void loadArticle() { if (aid != null) { this.article = findArticleById(Long.valueOf(aid)); } } } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/ArticleRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; @Repository public interface ArticleRepository extends EntityRepository { } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/HttpParam.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({ METHOD, FIELD, PARAMETER, TYPE }) public @interface HttpParam { @Nonbinding String value(); } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/HttpParams.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.faces.context.FacesContext; import jakarta.servlet.ServletRequest; public class HttpParams { @Produces @HttpParam("") String getParamValue(InjectionPoint ip) { ServletRequest request = (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); return request.getParameter(ip.getAnnotated().getAnnotation(HttpParam.class).value()); } } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/LogProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.util.logging.Logger; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; public class LogProducer { @Produces Logger createLogger(final InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } } ================================================ FILE: deltaspike/examples/data-examples/src/main/java/org/apache/deltaspike/example/Resources.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.faces.context.FacesContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.PersistenceUnit; @ApplicationScoped public class Resources { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @Default @RequestScoped public EntityManager create() { return this.entityManagerFactory.createEntityManager(); } public void dispose(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); } } ================================================ FILE: deltaspike/examples/data-examples/src/main/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy=org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy ================================================ FILE: deltaspike/examples/data-examples/src/main/resources/META-INF/persistence.xml ================================================ java:jboss/datasources/ExampleDS org.apache.deltaspike.example.Article ================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/WEB-INF/faces-config.xml ================================================ /add.xhtml persisted /list.xhtml /list.xhtml deleted /list.xhtml ================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.xhtml ================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/add.xhtml ================================================ Simple JPA page

#{empty(articleController.article.id) ? 'Add New ' : 'Edit '}Article

================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/index.xhtml ================================================ Simple Data Module page

Deltaspike Data module examples



================================================ FILE: deltaspike/examples/data-examples/src/main/webapp/list.xhtml ================================================ Simple JPA page

Article List

ID title date operation #{' '}
================================================ FILE: deltaspike/examples/jpa-examples/README.md ================================================ Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. JPA support in deltaspike ========================= This example shows: 1, how to use JPA in deltaspike; 2, the function of @Transactional, how @Transactional save entity automatically. BUT, this example is not involved in deltaspike Data module, please see data-playground example for deltaspike data module. ================================================ FILE: deltaspike/examples/jpa-examples/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-jpa-examples Apache DeltaSpike JPA Examples war true org.apache.deltaspike.core deltaspike-core-api org.apache.deltaspike.core deltaspike-core-impl org.apache.deltaspike.modules deltaspike-jsf-module-api org.apache.deltaspike.modules deltaspike-jsf-module-impl org.apache.deltaspike.modules deltaspike-jpa-module-api org.apache.deltaspike.modules deltaspike-jpa-module-impl org.apache.tomee jakartaee-api org.apache.myfaces.core myfaces-api compile ${project.artifactId} ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/Article.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.io.Serializable; import java.util.Date; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; @Entity @Table(name = "articles") public class Article implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; private String title; private String content; @Temporal(TemporalType.TIMESTAMP) @Column(name = "time_created") private Date date; // A must have! public Article() { // this form used by Hibernate } public Article(String title, Date date) { // for application use, to create new articles this.title = title; this.date = date; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "Article{" + "id=" + id + ", title=" + title + ", content=" + content + ", date=" + date + '}'; } } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/ArticleController.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.logging.Logger; import jakarta.faces.application.FacesMessage; import jakarta.faces.view.ViewScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.persistence.EntityManager; import jakarta.transaction.Transactional; @Named @ViewScoped @Transactional public class ArticleController implements Serializable { private Article article = new Article(); @Inject private Logger log; @Inject private EntityManager em; @Inject private FacesContext facesContext; @HttpParam("aid") @Inject private String aid; // article id public Article getArticle() { return article; } public void setArticle(Article article) { this.article = article; } public Article findArticleById(Long id) { article = em.find(Article.class, id); return article; } public String persist() { article.setDate(new Date()); em.merge(this.article); facesContext.addMessage(null, new FacesMessage("article:" + article.getTitle() + " persisted")); return "persisted"; } public String delete(Article article) { em.remove(article); facesContext.addMessage(null, new FacesMessage("article:" + article.getTitle() + " deleted")); return "deleted"; } public List
getAllArticles() { return em.createQuery("from Article a order by a.id desc").getResultList(); } public void loadArticle() { if (aid != null) { this.article = findArticleById(Long.valueOf(aid)); } } } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/HttpParam.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; @Qualifier @Retention(RUNTIME) @Target({ METHOD, FIELD, PARAMETER, TYPE }) public @interface HttpParam { @Nonbinding String value(); } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/HttpParams.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.faces.context.FacesContext; import jakarta.servlet.ServletRequest; public class HttpParams { @Produces @HttpParam("") String getParamValue(InjectionPoint ip) { ServletRequest request = (ServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); return request.getParameter(ip.getAnnotated().getAnnotation(HttpParam.class).value()); } } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/LogProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import java.util.logging.Logger; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; public class LogProducer { @Produces Logger createLogger(final InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); } } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/java/org/apache/deltaspike/example/Resources.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.faces.context.FacesContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.PersistenceUnit; @ApplicationScoped public class Resources { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @Default @RequestScoped public EntityManager create() { return this.entityManagerFactory.createEntityManager(); } public void dispose(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); } } ================================================ FILE: deltaspike/examples/jpa-examples/src/main/resources/META-INF/persistence.xml ================================================ java:jboss/datasources/ExampleDS org.apache.deltaspike.example.Article ================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/WEB-INF/faces-config.xml ================================================ /add.xhtml persisted /list.xhtml /list.xhtml deleted /list.xhtml ================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.xhtml ================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/add.xhtml ================================================ Simple JPA page

#{empty(articleController.article.id) ? 'Add New ' : 'Edit '}Article

================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/index.xhtml ================================================ Simple JPA page

Deltaspike JPA module examples



================================================ FILE: deltaspike/examples/jpa-examples/src/main/webapp/list.xhtml ================================================ Simple JPA page

Article List

ID title date operation #{' '}
================================================ FILE: deltaspike/examples/jse-examples/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT org.apache.deltaspike.examples deltaspike-jse-example Apache DeltaSpike Java-SE Examples jar true OWB true org.apache.openwebbeans openwebbeans-impl ${owb.version} runtime org.apache.openwebbeans openwebbeans-spi ${owb.version} compile org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb runtime Weld org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld runtime org.jboss.weld.se weld-se-core ${weld.version} runtime org.apache.deltaspike.core deltaspike-core-api org.apache.deltaspike.core deltaspike-core-impl compile org.apache.deltaspike.modules deltaspike-security-module-api org.apache.deltaspike.modules deltaspike-security-module-impl org.apache.deltaspike.cdictrl deltaspike-cdictrl-api compile ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/beanmanagement/SimpleBeanLookupExample.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.beanmanagement; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.example.echo.DefaultEchoService; import org.apache.deltaspike.example.echo.EchoService; import org.apache.deltaspike.example.optional.OptionalService; import jakarta.enterprise.context.ApplicationScoped; import java.util.List; import java.util.logging.Logger; /** * Example which illustrates the usage of {@inheritDoc BeanProvider} */ public class SimpleBeanLookupExample { private static final Logger LOG = Logger.getLogger(SimpleBeanLookupExample.class.getName()); private SimpleBeanLookupExample() { } /** * Entry point * * @param args currently not used */ public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); //containerControl.startContexts(); //or: //cdiContainer.start(); List echoServiceList = BeanProvider.getContextualReferences(EchoService.class, false); for (EchoService echoService : echoServiceList) { LOG.info(echoService.echo("Hello CDI bean!")); } LOG.info("---"); echoServiceList = BeanProvider.getContextualReferences(EchoService.class, false, false); for (EchoService echoService : echoServiceList) { LOG.info(echoService.echo("Hello non dependent CDI scoped bean!")); } LOG.info("---"); EchoService defaultEchoService = BeanProvider.getContextualReference(DefaultEchoService.class, false); LOG.info(defaultEchoService.echo("Hello explicitly resolved CDI bean!")); defaultEchoService = BeanProvider.getContextualReference("defaultEchoService", false, EchoService.class); LOG.info(defaultEchoService.echo("Hello CDI bean resolved by name!")); OptionalService optionalService = BeanProvider.getContextualReference(OptionalService.class, true); if (optionalService == null) { LOG.info("No (optional) implementation found for " + OptionalService.class.getName()); } else { LOG.severe("Unexpected implementation found: " + optionalService.getClass().getName()); } contextControl.stopContext(ApplicationScoped.class); cdiContainer.shutdown(); //or: //containerControl.stopContexts(); //cdiContainer.shutdownContainer(); //cdiContainer.stopContext(ApplicationScoped.class); //doesn't work with weld right now - see WELD-1072 } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/ConfigExample.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.provider.BeanProvider; import jakarta.enterprise.context.ApplicationScoped; import java.util.logging.Logger; public class ConfigExample { private static final Logger LOG = Logger.getLogger(ConfigExample.class.getName()); private ConfigExample() { } public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); SettingsBean settingsBean = BeanProvider.getContextualReference(SettingsBean.class, false); LOG.info("configured int-value #1: " + settingsBean.getIntProperty1()); LOG.info("configured long-value #2: " + settingsBean.getProperty2()); LOG.info("configured inverse-value #2: " + settingsBean.getInverseProperty()); LOG.info("configured location (custom config): " + settingsBean.getLocationId().name()); cdiContainer.shutdown(); } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomConfigPropertyProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.spi.config.BaseConfigPropertyProducer; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import java.util.logging.Logger; /** * Equivalent to a custom converter */ @ApplicationScoped @SuppressWarnings("UnusedDeclaration") public class CustomConfigPropertyProducer extends BaseConfigPropertyProducer { private static final Logger LOG = Logger.getLogger(CustomConfigPropertyProducer.class.getName()); @Produces @Dependent @Property2 public Long produceProperty2(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); if (configuredValue == null) { return null; } Property2 metaData = getAnnotation(injectionPoint, Property2.class); if (metaData.logValue()) { LOG.info("value of property 2: " + configuredValue); } //X TODO integrate with the HandledHandler of DeltaSpike return Long.parseLong(configuredValue); } @Produces @Dependent @Property2WithInverseSupport public Long produceInverseProperty2(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); if (configuredValue == null) { return null; } //X TODO integrate with the HandledHandler of DeltaSpike Long result = Long.parseLong(configuredValue); Property2WithInverseSupport metaData = getAnnotation(injectionPoint, Property2WithInverseSupport.class); if (metaData.inverseConvert()) { return result * -1; } return result; } @Produces @Dependent @Location public LocationId produceLocationId(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); /* //alternative to @ConfigProperty#defaultValue if (configuredValue == null) { return LocationId.LOCATION_X; } */ return LocationId.valueOf(configuredValue.trim().toUpperCase()); } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/CustomPropertyFileConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.api.config.PropertyFileConfig; import jakarta.enterprise.context.ApplicationScoped; /** * Allows to use a different file than apache-deltaspike.properties */ @ApplicationScoped public class CustomPropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "META-INF/location.properties"; } @Override public boolean isOptional() { return false; } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Location.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.api.config.ConfigProperty; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ FIELD, METHOD }) @Retention(RUNTIME) @Documented @ConfigProperty(name = "locationId", defaultValue = "LOCATION_X" /*as an alternative to a null check in the producer*/) @Qualifier public @interface Location { } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/LocationId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; /** * Enum as an example for a type-safe config with * {@link org.apache.deltaspike.core.api.config.ConfigProperty} */ public enum LocationId { LOCATION_X, LOCATION_Y, LOCATION_Z } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.api.config.ConfigProperty; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; 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.RetentionPolicy.RUNTIME; @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @ConfigProperty(name = "property2") @Qualifier public @interface Property2 { @Nonbinding boolean logValue() default true; } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/Property2WithInverseSupport.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.api.config.ConfigProperty; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; 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.RetentionPolicy.RUNTIME; @Target({ PARAMETER, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented @ConfigProperty(name = "property2") @Qualifier public @interface Property2WithInverseSupport { @Nonbinding boolean inverseConvert() default false; } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/config/SettingsBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.config; import org.apache.deltaspike.core.api.config.ConfigProperty; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class SettingsBean { @Inject @ConfigProperty(name = "property1") private Integer intProperty1; @Inject @Location private LocationId locationId; private Long property2; private Long inverseProperty; protected SettingsBean() { } @Inject public SettingsBean(@Property2 Long property2) { this.property2 = property2; } @Inject protected void init(@Property2WithInverseSupport(inverseConvert = true) Long inverseProperty) { this.inverseProperty = inverseProperty; } public Integer getIntProperty1() { return intProperty1; } public Long getProperty2() { return property2; } public Long getInverseProperty() { return inverseProperty; } public LocationId getLocationId() { return locationId; } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/echo/DefaultEchoService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.echo; import jakarta.enterprise.context.Dependent; import jakarta.inject.Named; /** * Default implementation */ @Dependent @Named("DefaultEchoService") //will be changed to defaultEchoService by org.apache.deltaspike.example.metadata.NamingConventionAwareMetadataFilter public class DefaultEchoService implements EchoService { /** * {@inheritDoc} */ @Override public String echo(String message) { return message; } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/echo/EchoService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.echo; /** * Interface for the different kinds of echo-services */ public interface EchoService { /** * Returns the given text again - the format might change * * @param message given message * @return message text */ String echo(String message); } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/echo/NoEchoService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.echo; import org.apache.deltaspike.core.api.exclude.Exclude; /** * This implementation can't be used as CDI bean */ @Exclude public class NoEchoService implements EchoService { /** * {@inheritDoc} */ @Override public String echo(String message) { return message; } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/echo/ToLowerCaseEchoService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.echo; import jakarta.enterprise.context.ApplicationScoped; /** * Implementation of {@link EchoService} which returns the given text in lower-case format */ @ApplicationScoped public class ToLowerCaseEchoService implements EchoService { /** * {@inheritDoc} */ @Override public String echo(String message) { return message.toLowerCase(); } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/echo/ToUpperCaseEchoService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.echo; import jakarta.enterprise.context.ApplicationScoped; /** * Implementation of {@link EchoService} which returns the given text in upper-case format */ @ApplicationScoped public class ToUpperCaseEchoService implements EchoService { /** * {@inheritDoc} */ @Override public String echo(String message) { return message.toUpperCase(); } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/metadata/NamingConventionAwareMetadataFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.metadata; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; /** * Just a test filter to show the basic functionality provided by {@link AnnotatedTypeBuilder} */ public class NamingConventionAwareMetadataFilter implements Extension { public void ensureNamingConvention(@Observes ProcessAnnotatedType processAnnotatedType) { Class beanClass = processAnnotatedType.getAnnotatedType().getJavaClass(); // Named namedAnnotation = beanClass.getAnnotation(Named.class); // if (namedAnnotation != null && // namedAnnotation.value().length() > 0 && // Character.isUpperCase(namedAnnotation.value().charAt(0))) // { // AnnotatedTypeBuilder builder = new AnnotatedTypeBuilder(); // builder.readFromType(beanClass); // // String beanName = namedAnnotation.value(); // String newBeanName = beanName.substring(0, 1).toLowerCase() + beanName.substring(1); // // builder.removeFromClass(Named.class) // .addToClass(new NamedLiteral(newBeanName)); // // processAnnotatedType.setAnnotatedType(builder.create()); // } } } ================================================ FILE: deltaspike/examples/jse-examples/src/main/java/org/apache/deltaspike/example/optional/OptionalService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.optional; /** * Interface without implementation to show the lookup of optional implementations */ public interface OptionalService { } ================================================ FILE: deltaspike/examples/jse-examples/src/main/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # property1=14 property2=7 ================================================ FILE: deltaspike/examples/jse-examples/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/jse-examples/src/main/resources/META-INF/location.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # locationId=location_z ================================================ FILE: deltaspike/examples/jse-examples/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.example.metadata.NamingConventionAwareMetadataFilter ================================================ FILE: deltaspike/examples/jsf-examples/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-jsf-example Apache DeltaSpike JSF Examples war true tomeeConfig install org.apache.tomee.maven tomee-maven-plugin 1.0.1 ${tomee.version} org.apache.tomee jakartaee-api org.apache.myfaces.core myfaces-api org.apache.deltaspike.core deltaspike-core-api compile org.apache.deltaspike.core deltaspike-core-impl compile org.apache.deltaspike.modules deltaspike-jsf-module-api compile org.apache.deltaspike.modules deltaspike-jsf-module-impl compile ds ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/ApplicationMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import org.apache.deltaspike.core.api.message.MessageBundle; /** * */ @MessageBundle public interface ApplicationMessages { String helloWorld(String name); } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/ControllerView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import org.apache.deltaspike.jsf.api.message.JsfMessage; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import java.util.Date; /** * */ @Named @RequestScoped public class ControllerView { private String name; @Inject private JsfMessage msg; @Inject private JsfMessage custom; public void doGreeting() { msg.addInfo().helloWorld(name); } public String getName() { return name; } public void setName(String someName) { name = someName; } public String getNow() { // getTimestampMessage return a Message where you could do some customizations before calling toString(). return custom.get().getTimestampMessage(new Date()).toString(); } public String getCustomMessage() { return custom.get().fromFacesMessageBundle(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/Custom.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * */ @Qualifier @Documented @Retention(RUNTIME) public @interface Custom { } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/CustomMessageResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.jsf.impl.message.JsfMessageResolver; import jakarta.enterprise.inject.Specializes; import jakarta.faces.context.FacesContext; @Specializes public class CustomMessageResolver extends JsfMessageResolver { private static final long serialVersionUID = -7566133260553818285L; @Override public String getMessage(MessageContext messageContext, String messageTemplate, String category) { addMessageBundleFromFacesConfig(messageContext); return super.getMessage(messageContext, messageTemplate, category); } private void addMessageBundleFromFacesConfig(MessageContext someMessageContext) { String messageBundle = FacesContext.getCurrentInstance().getApplication().getMessageBundle(); if (messageBundle != null && messageBundle.length() > 0) { someMessageContext.messageSource(messageBundle); } } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/CustomizedMessages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; import org.apache.deltaspike.core.api.message.MessageTemplate; import java.util.Date; /** * */ @MessageBundle @MessageContextConfig(messageSource = {"org.apache.deltaspike.example.message.ApplicationMessages" }, messageInterpolator = MessageFormatMessageInterpolator.class) public interface CustomizedMessages { @MessageTemplate(value = "{nowMessage}") Message getTimestampMessage(Date now); String fromFacesMessageBundle(); } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/LanguageView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Named; import java.io.Serializable; import java.util.Locale; /** * */ @Named @SessionScoped public class LanguageView implements Serializable { private static final Locale ENGLISH = Locale.ENGLISH; private static final Locale FRENCH = Locale.FRENCH; private static final Locale DUTCH = new Locale("nl"); private Locale selectedLanguage = new Locale("en"); public boolean isEnglish() { return ENGLISH.equals(selectedLanguage); } public boolean isFrench() { return FRENCH.equals(selectedLanguage); } public boolean isDutch() { return DUTCH.equals(selectedLanguage); } public void setEnglish() { selectedLanguage = ENGLISH; } public void setFrench() { selectedLanguage = FRENCH; } public void setDutch() { selectedLanguage = DUTCH; } public Locale getSelectedLanguage() { return selectedLanguage; } public void setSelectedLanguage(Locale someSelectedLanguage) { selectedLanguage = someSelectedLanguage; } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/message/MessageFormatMessageInterpolator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.message; import org.apache.deltaspike.core.api.message.MessageInterpolator; import java.io.Serializable; import java.text.MessageFormat; import java.util.Locale; /** * */ @Custom public class MessageFormatMessageInterpolator implements MessageInterpolator { @Override public String interpolate(String messageText, Serializable[] arguments, Locale locale) { return MessageFormat.format(messageText, arguments); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/ApplicationScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Named; /** * */ @Named @ApplicationScoped public class ApplicationScopedBean extends ScopedBean { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/RequestScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; /** * */ @Named @RequestScoped public class RequestScopedBean extends ScopedBean { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/ScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import java.util.Date; /** * */ public class ScopedBean { private Date creationDate; public Date getCreationDate() { return creationDate; } public void init() { creationDate = new Date(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/SessionScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Named; import java.io.Serializable; /** * */ @Named @SessionScoped public class SessionScopedBean extends ScopedBean implements Serializable { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/ViewAccessScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import java.io.Serializable; import jakarta.annotation.PostConstruct; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; @ViewAccessScoped @Named public class ViewAccessScopedBean extends ScopedBean implements Serializable { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/ViewScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import jakarta.annotation.PostConstruct; import jakarta.faces.view.ViewScoped; import jakarta.inject.Named; import java.io.Serializable; /** * */ @ViewScoped @Named public class ViewScopedBean extends ScopedBean implements Serializable { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/scope/WindowScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scope; import java.io.Serializable; import jakarta.annotation.PostConstruct; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.WindowScoped; @WindowScoped @Named public class WindowScopedBean extends ScopedBean implements Serializable { @PostConstruct public void init() { super.init(); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/viewconfig/DenyAllAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.viewconfig; import java.util.HashSet; import java.util.Set; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; public class DenyAllAccessDecisionVoter implements AccessDecisionVoter { @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { Set violations = new HashSet(); violations.add(new SecurityViolation() { @Override public String getReason() { return "This is a deny all AccessDecisionVoter"; } }); return violations; } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/viewconfig/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.viewconfig; import jakarta.enterprise.inject.Model; @Model public class MyBean { private String aValue = "My bean value"; public String getaValue() { return aValue; } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/viewconfig/PageController.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.viewconfig; import jakarta.enterprise.inject.Model; import jakarta.inject.Inject; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import org.apache.deltaspike.example.viewconfig.Pages.SecuredPages; import org.apache.deltaspike.example.viewconfig.Pages.ViewConfigFolder.AllowedPage; import org.apache.deltaspike.example.viewconfig.Pages.ViewConfigFolder.NavigationParameterPage; import org.apache.deltaspike.example.viewconfig.Pages.ViewConfigFolder.RedirectedPage; import org.apache.deltaspike.example.viewconfig.Pages.ViewConfigFolder.SecuredPage; import org.apache.deltaspike.example.viewconfig.Pages.ViewConfigFolder.ViewConfigPage; @Model public class PageController { @Inject private NavigationParameterContext navigationParameterContext; @Inject private ViewNavigationHandler viewNavigationHandler; public Class toRedirectedPage() { return RedirectedPage.class; } public Class returnToMainPage() { return ViewConfigPage.class; } @NavigationParameter(key = "param4", value = "Parameter from the Controller class") public Class toNavigationParameterPage() { this.navigationParameterContext.addPageParameter("param3", "I also come from a navigation parameter using Dynamic Configuration via NavigationParameterContext"); return NavigationParameterPage.class; } public Class toSecuredPage() { return SecuredPage.class; } public void doAnyActionAndProceeed() { // action is performed this.viewNavigationHandler.navigateTo(AllowedPage.class); } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/viewconfig/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.viewconfig; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.config.view.View.NavigationMode; import org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode; import org.apache.deltaspike.security.api.authorization.Secured; public interface Pages extends ViewConfig { @View(navigation = NavigationMode.REDIRECT, viewParams = ViewParameterMode.INCLUDE) interface RedirectedPages extends ViewConfig { } @Secured(DenyAllAccessDecisionVoter.class) interface SecuredPages extends ViewConfig { } @Folder(name = "./viewconfig/") interface ViewConfigFolder extends ViewConfig { class RedirectedPage implements RedirectedPages { } class ViewConfigPage implements RedirectedPages { } @NavigationParameter.List({ @NavigationParameter(key = "param1", value = "Hey, I come from a navigation parameter"), @NavigationParameter(key = "param2", value = "Hey, It's an interpolated value: #{myBean.aValue}") }) class NavigationParameterPage implements RedirectedPages { } class SecuredPage implements SecuredPages { } class AllowedPage implements ViewConfig { } } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/java/org/apache/deltaspike/example/window/SampleClientWindowConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.window; import jakarta.enterprise.inject.Specializes; import jakarta.faces.context.FacesContext; import org.apache.deltaspike.jsf.spi.scope.window.DefaultClientWindowConfig; /** * A sample ClientWindowConfig */ @Specializes public class SampleClientWindowConfig extends DefaultClientWindowConfig { @Override public ClientWindowRenderMode getClientWindowRenderMode(FacesContext facesContext) { return ClientWindowRenderMode.CLIENTWINDOW; } } ================================================ FILE: deltaspike/examples/jsf-examples/src/main/resources/org/apache/deltaspike/example/message/ApplicationMessages_en.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # helloWorld=Hello %s nowMessage=Current time is {0} ================================================ FILE: deltaspike/examples/jsf-examples/src/main/resources/org/apache/deltaspike/example/message/ApplicationMessages_fr.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # helloWorld=Bonjour %s nowMessage=L'heure actuelle est {0} ================================================ FILE: deltaspike/examples/jsf-examples/src/main/resources/org/apache/deltaspike/example/message/ApplicationMessages_nl.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # helloWorld=Hallo %s nowMessage=Huidige tijd is {0} ================================================ FILE: deltaspike/examples/jsf-examples/src/main/resources/org/apache/deltaspike/example/message/FacesMessages.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # fromFacesMessageBundle=Text resolved from Faces config resource bundle. ================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/WEB-INF/faces-config.xml ================================================ org.apache.deltaspike.example.message.FacesMessages ================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.xhtml ================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/index.xhtml ================================================ Simple JSF Facelets page

Deltaspike JSF module examples



================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/message/jsfMessage.xhtml ================================================ JsfMessage example

JsfMessage example

   


#{controllerView.now}
following text is revolved by CustomMessageResolver: [#{controllerView.customMessage}]
================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/scopes/scopePage1.xhtml ================================================ Simple JSF Facelets page

JSF 2/CDI Scope testing

Page 1

================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/scopes/scopePage2.xhtml ================================================ Simple JSF Facelets page

JSF 2/CDI Scope testing

Page 2

================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/viewconfig/allowedPage.xhtml ================================================ Simple JSF Facelets page

Allowed Page

================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/viewconfig/navigationParameterPage.xhtml ================================================ Simple JSF Facelets page

Parameters Page





================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/viewconfig/redirectedPage.xhtml ================================================ Simple JSF Facelets page

Redirected Page

================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/viewconfig/securedPage.xhtml ================================================ Simple JSF Facelets page

Secured Page

================================================ FILE: deltaspike/examples/jsf-examples/src/main/webapp/pages/viewconfig/viewConfigPage.xhtml ================================================ Simple JSF Facelets page

JSF 2/CDI Type-safe View-Config




================================================ FILE: deltaspike/examples/jsf-playground/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-jsf-playground Apache DeltaSpike JSF Playground war true org.apache.deltaspike.core deltaspike-core-api org.apache.deltaspike.core deltaspike-core-impl compile org.apache.deltaspike.modules deltaspike-jsf-module-api org.apache.deltaspike.modules deltaspike-jsf-module-impl compile org.apache.tomee jakartaee-api org.apache.myfaces.core myfaces-api compile org.apache.tomee.maven tomee-embedded-maven-plugin 9.1.2 / ================================================ FILE: deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/playground/PlaygroundClientWindowConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.playground; import org.apache.deltaspike.jsf.spi.scope.window.DefaultClientWindowConfig; import jakarta.enterprise.inject.Specializes; import jakarta.faces.context.FacesContext; @Specializes public class PlaygroundClientWindowConfig extends DefaultClientWindowConfig { @Override public ClientWindowRenderMode getClientWindowRenderMode(FacesContext facesContext) { String path = facesContext.getExternalContext().getRequestPathInfo(); if (path == null) { path = facesContext.getExternalContext().getRequestServletPath(); } ClientWindowRenderMode mode; if (path.contains("/windowhandling/clientwindow/")) { mode = ClientWindowRenderMode.CLIENTWINDOW; } else if (path.contains("/windowhandling/lazy/")) { mode = ClientWindowRenderMode.LAZY; } else if (path.contains("/windowhandling/none/")) { mode = ClientWindowRenderMode.NONE; } else if (path.contains("/windowhandling/delegated/")) { mode = ClientWindowRenderMode.DELEGATED; } else { mode = ClientWindowRenderMode.CLIENTWINDOW; } return mode; } } ================================================ FILE: deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/playground/scope/viewaccess/ViewAccessScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.playground.scope.viewaccess; import java.io.Serializable; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; @Named @ViewAccessScoped public class ViewAccessScopedBean implements Serializable { private String value; @PostConstruct public void postConstruct() { System.err.println("postConstruct"); } @PreDestroy public void preDestroy() { System.err.println("preDestroy"); } public void touch() { System.err.println("touch"); } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ================================================ FILE: deltaspike/examples/jsf-playground/src/main/java/org/apache/deltaspike/playground/windowhandling/ViewActionController.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.playground.windowhandling; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; import jakarta.faces.context.FacesContext; import jakarta.faces.lifecycle.ClientWindow; import jakarta.inject.Inject; import jakarta.inject.Named; import java.util.Date; @Named @RequestScoped public class ViewActionController { @Inject private ClientWindow clientWindow; private Date lastTimeLinkAction; @PostConstruct public void init() { System.out.println("@PostConstruct ViewActionController"); } public void action() { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("ViewActionController#action with windowId: " + clientWindow.getId()); } public Date getLastTimeLinkAction() { return lastTimeLinkAction; } public void linkAction() { FacesContext context = FacesContext.getCurrentInstance(); System.out.println("ViewActionController#linkAction with windowId: " + clientWindow.getId()); lastTimeLinkAction = new Date(); } } ================================================ FILE: deltaspike/examples/jsf-playground/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/WEB-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/WEB-INF/faces-config.xml ================================================ ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml jakarta.faces.PROJECT_STAGE Development Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml Faces Servlet /faces/* index.xhtml ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/index.xhtml ================================================ DeltaSpike JSF Playground

Deltaspike JSF Playground


ExceptionHandling:


Scope:




WindowHandling:






'window.name':
================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/scope/viewaccess/test1.xhtml ================================================ DeltaSpike JSF Playground ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/scope/viewaccess/test2.xhtml ================================================ DeltaSpike JSF Playground Value: #{viewAccessScopedBean.value} ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/scope/viewaccess/test3.xhtml ================================================ DeltaSpike JSF Playground ================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/windowhandling/clientwindow/test.xhtml ================================================ DeltaSpike JSF Playground DS WindowId: #{dsWindowContext.currentWindowId}











Last time linkAction: #{viewActionController.lastTimeLinkAction}
================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/windowhandling/lazy/test.xhtml ================================================ DeltaSpike JSF Playground DS WindowId: #{dsWindowContext.currentWindowId}











================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/windowhandling/lazy/testWithoutJS.xhtml ================================================ DeltaSpike JSF Playground DS WindowId: #{dsWindowContext.currentWindowId}











================================================ FILE: deltaspike/examples/jsf-playground/src/main/webapp/views/windowhandling/lazy/viewAction.xhtml ================================================ DeltaSpike JSF Playground DS WindowId: #{dsWindowContext.currentWindowId}











================================================ FILE: deltaspike/examples/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent-code 2.0.2-SNAPSHOT ../parent/code/pom.xml org.apache.deltaspike.examples examples-project pom Apache DeltaSpike Examples jse-examples jsf-examples jsf-playground security-requested-page-after-login-cdi security-requested-page-after-login-picketlink scheduler-playground jpa-examples data-examples false org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-security-module-api ${project.version} org.apache.deltaspike.modules deltaspike-security-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jsf-module-api ${project.version} org.apache.deltaspike.modules deltaspike-jsf-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} org.apache.deltaspike.modules deltaspike-jpa-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-data-module-api ${project.version} org.apache.deltaspike.modules deltaspike-data-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-scheduler-module-api ${project.version} org.apache.deltaspike.modules deltaspike-scheduler-module-impl ${project.version} runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-openejb ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} org.apache.tomee jakartaee-api ${tomee-api.version} provided org.apache.myfaces.core myfaces-api ${myfaces.version} provided org.apache.maven.plugins maven-deploy-plugin 3.1.1 ${deploy.skip} ================================================ FILE: deltaspike/examples/scheduler-playground/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT org.apache.deltaspike.examples deltaspike-scheduler-example Apache DeltaSpike Java-SE Scheduler Examples jar true OWB true org.apache.openwebbeans openwebbeans-impl ${owb.version} runtime org.apache.openwebbeans openwebbeans-spi ${owb.version} compile org.javassist javassist 3.17.1-GA org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb runtime Weld org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld runtime org.jboss.weld.se weld-se-core ${weld.version} runtime org.apache.deltaspike.core deltaspike-core-api compile org.apache.deltaspike.core deltaspike-core-impl runtime org.apache.deltaspike.modules deltaspike-scheduler-module-api compile org.apache.deltaspike.modules deltaspike-scheduler-module-impl runtime org.apache.deltaspike.cdictrl deltaspike-cdictrl-api compile org.quartz-scheduler quartz 2.3.2 ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/java/org/apache/deltaspike/example/scheduler/GlobalResultHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scheduler; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.util.concurrent.atomic.AtomicInteger; @ApplicationScoped public class GlobalResultHolder { private AtomicInteger count = new AtomicInteger(); @Inject private RequestScopedNumberProvider numberProvider; @PostConstruct protected void init() { count.set(0); } public void increase() { count.addAndGet(numberProvider.getNumber()); } public int getCount() { return count.get(); } } ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/java/org/apache/deltaspike/example/scheduler/RequestScopedNumberProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scheduler; import jakarta.enterprise.context.RequestScoped; import java.math.BigDecimal; @RequestScoped public class RequestScopedNumberProvider { public int getNumber() { int result = new BigDecimal(Math.random() % 10).intValue(); return result != 0 ? result : 1; } } ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/java/org/apache/deltaspike/example/scheduler/SimpleSchedulerExample.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scheduler; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.provider.BeanProvider; import jakarta.enterprise.context.ApplicationScoped; import java.util.logging.Logger; public class SimpleSchedulerExample { private static final Logger LOG = Logger.getLogger(SimpleSchedulerExample.class.getName()); private SimpleSchedulerExample() { } public static void main(String[] args) throws InterruptedException { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); GlobalResultHolder globalResultHolder = BeanProvider.getContextualReference(GlobalResultHolder.class); while (globalResultHolder.getCount() < 100) { Thread.sleep(500); LOG.info("current count: " + globalResultHolder.getCount()); } LOG.info("completed!"); contextControl.stopContext(ApplicationScoped.class); cdiContainer.shutdown(); } } ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/java/org/apache/deltaspike/example/scheduler/SimpleSchedulerJob1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scheduler; import org.apache.deltaspike.scheduler.api.Scheduled; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import jakarta.inject.Inject; import java.util.logging.Logger; @Scheduled(cronExpression = "0/2 * * * * ?") public class SimpleSchedulerJob1 implements Job { private static final Logger LOG = Logger.getLogger(SimpleSchedulerJob1.class.getName()); @Inject private GlobalResultHolder globalResultHolder; @Override public void execute(JobExecutionContext context) throws JobExecutionException { LOG.info("#increase called by " + getClass().getName()); globalResultHolder.increase(); } } ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/java/org/apache/deltaspike/example/scheduler/SimpleSchedulerJob2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.scheduler; import org.apache.deltaspike.scheduler.api.Scheduled; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import jakarta.inject.Inject; import java.util.logging.Logger; @Scheduled(cronExpression = "0/1 * * * * ?") public class SimpleSchedulerJob2 implements Job { private static final Logger LOG = Logger.getLogger(SimpleSchedulerJob2.class.getName()); @Inject private GlobalResultHolder globalResultHolder; @Override public void execute(JobExecutionContext context) throws JobExecutionException { LOG.info("#increase called by " + getClass().getName()); globalResultHolder.increase(); } } ================================================ FILE: deltaspike/examples/scheduler-playground/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/README.md ================================================ Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Making initially requested secured page available for redirect after login with CDI =================================================================================== The following scenario is commonly seen in web applications: 1. User requests a web page 2. The web page is restricted to logged in users so the browser is redirected to login page 3. After successful login, the user is redirected back to the originally requested page This example shows pure CDI implementation of this technique. ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-security-requested-page-after-login-cdi war Apache DeltaSpike Security Example CDI DeltaSpike Example: Show requested page after login with CDI true 2.7.0.Final org.apache.myfaces.core myfaces-api ${myfaces.version} provided org.apache.deltaspike.core deltaspike-core-api compile org.apache.deltaspike.core deltaspike-core-impl runtime org.apache.deltaspike.modules deltaspike-jsf-module-api compile org.apache.deltaspike.modules deltaspike-jsf-module-impl runtime org.apache.deltaspike.modules deltaspike-security-module-api compile org.apache.deltaspike.modules deltaspike-security-module-impl runtime org.apache.tomee jakartaee-api ${project.artifactId} ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/java/org/apache/deltaspike/example/security/requestedpage/cdi/AuthenticationListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.cdi; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; public class AuthenticationListener { @Inject private ViewNavigationHandler viewNavigationHandler; @Inject private LoggedInAccessDecisionVoter loggedInAccessDecisionVoter; public void handleLoggedIn(@Observes UserEvent.LoggedIn event) { this.viewNavigationHandler.navigateTo(loggedInAccessDecisionVoter.getDeniedPage()); System.err.println("handling loggedin"); } public void handleFailed(@Observes UserEvent.LoginFailed event) { this.viewNavigationHandler.navigateTo(Pages.Login.class); System.err.println("handling failed"); } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/java/org/apache/deltaspike/example/security/requestedpage/cdi/LoggedInAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.cdi; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.security.api.authorization.AbstractAccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import jakarta.enterprise.context.SessionScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import java.util.Set; @SessionScoped //or @WindowScoped public class LoggedInAccessDecisionVoter extends AbstractAccessDecisionVoter { @Inject private ViewConfigResolver viewConfigResolver; @Inject private LoginController loginController; private Class deniedPage = Pages.Secure.Home.class; @Override protected void checkPermission(AccessDecisionVoterContext context, Set violations) { if (loginController.isLoggedIn()) { // no violations, pass } else { violations.add(new SecurityViolation() { @Override public String getReason() { return "User must be logged in to access this resource"; } }); // remember the requested page deniedPage = viewConfigResolver .getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId()) .getConfigClass(); } } public Class getDeniedPage() { return deniedPage; } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/java/org/apache/deltaspike/example/security/requestedpage/cdi/LoginController.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.cdi; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.event.Event; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @RequestScoped public class LoginController { public static final String DEFAULT_USER = "john"; public static final String DEFAULT_PASSWORD = "123456"; public static final String DEFAULT_NAME = "John User"; private String username; private String password; private boolean loggedIn = false; @Inject private Event evtLoggedIn; @Inject private Event evtLoginFailed; public void login() { if (DEFAULT_USER.equals(username) && DEFAULT_PASSWORD.equals(password)) { loggedIn = true; evtLoggedIn.fire(new UserEvent.LoggedIn()); System.err.println("logged in"); } else { evtLoginFailed.fire(new UserEvent.LoginFailed()); System.err.println("failed"); } } public void logout() { loggedIn = false; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getName() { return DEFAULT_NAME; } public boolean isLoggedIn() { return loggedIn; } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/java/org/apache/deltaspike/example/security/requestedpage/cdi/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.cdi; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.security.api.authorization.Secured; @Folder(name = "/") public interface Pages { class Login extends DefaultErrorView { } @Folder(name = "/secured") interface Secure extends ViewConfig { @Secured(LoggedInAccessDecisionVoter.class) class Home implements Secure { } } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/java/org/apache/deltaspike/example/security/requestedpage/cdi/UserEvent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.cdi; public class UserEvent { public static class LoggedIn { } public static class LoginFailed { } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/WEB-INF/beans.xml ================================================ org.apache.deltaspike.security.impl.extension.SecurityInterceptor ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/WEB-INF/faces-config.xml ================================================ ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.html ================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/index.html ================================================ Index

Index

This link points to a secured page and should redirect to login page:
Go Home

================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/login.xhtml ================================================ Login

Log in






Hint: log in as john / 123456


================================================ FILE: deltaspike/examples/security-requested-page-after-login-cdi/src/main/webapp/secured/home.xhtml ================================================ Login

Log in






Hint: log in as john / 123456


================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/README.md ================================================ Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Making initially requested secured page available for redirect after login with PicketLink ========================================================================================== The following scenario is commonly seen in web applications: 1. User requests a web page 2. The web page is restricted to logged in users so the browser is redirected to login page 3. After successful login, the user is redirected back to the originally requested page This example shows an implementation of this technique using PicketLink. ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/pom.xml ================================================ 4.0.0 org.apache.deltaspike.examples examples-project 2.0.2-SNAPSHOT deltaspike-security-requested-page-after-login-picketlink war Apache DeltaSpike Security Example PicketLink DeltaSpike Example: Show requested page after login with PicketLink true 2.7.0.Final org.apache.myfaces.core myfaces-api provided org.apache.deltaspike.core deltaspike-core-api compile org.apache.deltaspike.core deltaspike-core-impl runtime org.apache.deltaspike.modules deltaspike-jsf-module-api compile org.apache.deltaspike.modules deltaspike-jsf-module-impl runtime org.apache.deltaspike.modules deltaspike-security-module-api compile org.apache.deltaspike.modules deltaspike-security-module-impl runtime org.picketlink picketlink-api compile ${picketlink.version} org.picketlink picketlink-impl compile ${picketlink.version} org.apache.tomee jakartaee-api ${project.artifactId} ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/java/org/apache/deltaspike/example/security/requestedpage/picketlink/AuthenticationListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.picketlink; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import org.picketlink.authentication.event.LoggedInEvent; import org.picketlink.authentication.event.LoginFailedEvent; import org.picketlink.authentication.event.PostLoggedOutEvent; import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; public class AuthenticationListener { @Inject private ViewNavigationHandler viewNavigationHandler; @Inject private LoggedInAccessDecisionVoter loggedInAccessDecisionVoter; public void handleLoggedIn(@Observes LoggedInEvent event) { this.viewNavigationHandler.navigateTo(loggedInAccessDecisionVoter.getDeniedPage()); } public void handleFailed(@Observes LoginFailedEvent event) { this.viewNavigationHandler.navigateTo(Pages.Login.class); } public void handleLogout(@Observes PostLoggedOutEvent event) { this.viewNavigationHandler.navigateTo(Pages.Login.class); } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/java/org/apache/deltaspike/example/security/requestedpage/picketlink/Initializer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.picketlink; import org.picketlink.idm.IdentityManager; import org.picketlink.idm.PartitionManager; import org.picketlink.idm.credential.Password; import org.picketlink.idm.model.basic.User; import jakarta.annotation.PostConstruct; import jakarta.ejb.Singleton; import jakarta.ejb.Startup; import jakarta.inject.Inject; /** * This startup bean creates the default users, groups and roles when the application is started. */ @Singleton @Startup public class Initializer { @Inject private PartitionManager partitionManager; @PostConstruct public void create() { // Create user john User john = new User("john"); john.setEmail("john@acme.com"); john.setFirstName("John"); john.setLastName("User"); IdentityManager identityManager = this.partitionManager.createIdentityManager(); identityManager.add(john); identityManager.updateCredential(john, new Password("123456")); } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/java/org/apache/deltaspike/example/security/requestedpage/picketlink/LoggedInAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.picketlink; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.security.api.authorization.AbstractAccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import org.picketlink.Identity; import jakarta.enterprise.context.SessionScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import java.util.Set; @SessionScoped //or @WindowScoped public class LoggedInAccessDecisionVoter extends AbstractAccessDecisionVoter { @Inject private ViewConfigResolver viewConfigResolver; @Inject private Identity identity; // set a default private Class deniedPage = Pages.Secure.Home.class; @Override protected void checkPermission(AccessDecisionVoterContext context, Set violations) { if (identity.isLoggedIn()) { // no violations, pass } else { violations.add(new SecurityViolation() { @Override public String getReason() { return "User must be logged in to access this resource"; } }); // remember the requested page deniedPage = viewConfigResolver .getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId()) .getConfigClass(); } } public Class getDeniedPage() { return deniedPage; } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/java/org/apache/deltaspike/example/security/requestedpage/picketlink/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.example.security.requestedpage.picketlink; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.security.api.authorization.Secured; @Folder(name = "/") public interface Pages { class Login extends DefaultErrorView { } @Folder(name = "/secured") @Secured(LoggedInAccessDecisionVoter.class) interface Secure { class Home implements ViewConfig { } class Test implements ViewConfig { } } } ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/WEB-INF/beans.xml ================================================ org.apache.deltaspike.security.impl.extension.SecurityInterceptor ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/WEB-INF/faces-config.xml ================================================ ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/WEB-INF/web.xml ================================================ jakarta.faces.DEFAULT_SUFFIX .xhtml Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml index.html ================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/index.html ================================================ Index

Index

These link points to secured pages and should redirect to login page:
Go Home
Go Test Page

================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/login.xhtml ================================================ Login

Log in






Hint: log in as john / 123456


================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/secured/home.xhtml ================================================ Home Page

Hello!

Welcome Home

================================================ FILE: deltaspike/examples/security-requested-page-after-login-picketlink/src/main/webapp/secured/test.xhtml ================================================ Test Page

Hello!

Welcome to Secured Test Page

================================================ FILE: deltaspike/javadoc.sh ================================================ #!/bin/sh ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### mvn clean javadoc:aggregate scm-publish:publish-scm -Dmdep.skip=true ================================================ FILE: deltaspike/modules/data/README.adoc ================================================ = DeltaSpike Data /////////// Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. /////////// == DeltaSpike Data Please refer to the module documentation on the http://deltaspike.apache.org/data.html[DeltaSpike website]. ================================================ FILE: deltaspike/modules/data/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules data-module-project 2.0.2-SNAPSHOT deltaspike-data-module-api jar Apache DeltaSpike Data-Module API org.apache.deltaspike.data.* jakarta.persistence.*, !org.apache.deltaspike.data.*, * jakarta.persistence jakarta.persistence-api org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${project.version} org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/AbstractEntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.io.Serializable; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaQuery; /** * Base Repository class to be extended by concrete implementations * (abstract classes with implementation methods). * * @param Entity type. * @param Primary key type. */ @Repository public abstract class AbstractEntityRepository implements EntityRepository, EntityPersistenceRepository, EntityCountRepository { /** * Utility method to get hold of the entity manager for this Repository. * @return Entity manager instance. */ protected abstract EntityManager entityManager(); /** * Utility method to create a criteria query. * @return Criteria query */ protected abstract CriteriaQuery criteriaQuery(); /** * Utility method to create a typed query. * @param qlString Query string * @return Typed query */ protected abstract TypedQuery typedQuery(String qlString); /** * Get the entity class this Repository is related to. * @return Repository entity class. */ protected abstract Class entityClass(); /** * Get the entity table name this Repository is related to. * @return Repository entity table name. */ protected abstract String tableName(); /** * Get the entity name this Repository is related to. * @return Repository entity name. */ protected abstract String entityName(); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/AbstractFullEntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.io.Serializable; /** * Full repository base class to be extended by concrete implementations. A convenience class * combining {@code AbstractEntityRepository}, {@code EntityManagerDelegate} and * {@code CriteriaSupport}. * * @param * Entity type. * @param * Primary key type. */ public abstract class AbstractFullEntityRepository extends AbstractEntityRepository implements FullEntityRepository { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityCountRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import jakarta.persistence.metamodel.SingularAttribute; public interface EntityCountRepository { /** * Count all existing entities of entity class {@code }. * @return Counter. */ Long count(); /** * Count existing entities of entity class {@code } * with for a given object and a specific set of properties.. * @param example Sample entity. Query all like. * @param attributes Which attributes to consider for the query. * * @return Counter. */ Long count(E example, SingularAttribute... attributes); /** * Count existing entities of entity class using the like operator for String attributes {@code } * with for a given object and a specific set of properties.. * @param example Sample entity. Query all like. * @param attributes Which attributes to consider for the query. * * @return Counter. */ Long countLike(E example, SingularAttribute... attributes); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraph.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Defines an entity graph to be applied to a query. This annotation can be added to any query * method of a repository class. *

* The arguments {@code value} and {@code paths} are mutually exclusive. If {@code value} is set, it * references a named entity graph defined by JPA metadata. *

* If {@code paths} is set, an entity graph is constructed programmatically from the list of * attribute paths. * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface EntityGraph { /** * Name of a named entity graph. * @return graph name */ String value() default ""; /** * Type of entity graph (fetch or load). * @return graph type */ EntityGraphType type() default EntityGraphType.FETCH; /** * List of attribute paths. Each path may have multiple components, separated * by dots. A single component path adds an attribute node to the entity graph. * A path {@code foo.bar.baz} adds an attribute node {@code baz} to a subgraph * {@code bar} for the subgraph {@code foo}. * * @return list of paths */ String[] paths() default { }; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityGraphType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; /** * Entity graph type (fetch graph or load graph). The type determines * the query hint name used to pass the entity graph to a query. */ public enum EntityGraphType { /** Fetch graph. */ FETCH("jakarta.persistence.fetchgraph"), /** Load graph. */ LOAD("jakarta.persistence.loadgraph"); private String hintName; private EntityGraphType(String hintName) { this.hintName = hintName; } /** * Gets the query hint name corresponding to this type. * @return hint name */ public String getHintName() { return hintName; } } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityManagerConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import jakarta.persistence.FlushModeType; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; /** * Configure the EntityManager for a specific repository. * * This class is deprecated, instead use {@link org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig} */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Deprecated public @interface EntityManagerConfig { /** * References the type which provides the EntityManager for a specific repository. * Must be resolvable over the BeanManager. */ Class entityManagerResolver() default EntityManagerResolver.class; /** * Set the flush mode for the repository EntityManager. */ FlushModeType flushMode() default FlushModeType.AUTO; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityManagerDelegate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.util.Map; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.metamodel.Metamodel; /** * Expose {@link jakarta.persistence.EntityManager} methods not present on repository base interfaces. * Calls the corresponding method on the repository EntityManager. * * @param The Entity type. */ public interface EntityManagerDelegate { /** * See {@link jakarta.persistence.EntityManager#persist(Object)}. */ void persist(E entity); /** * See {@link jakarta.persistence.EntityManager#merge(Object)}. */ E merge(E entity); /** * See {@link jakarta.persistence.EntityManager#find(Class, Object, java.util.Map)}. */ E find(Object primaryKey, Map properties); /** * See {@link jakarta.persistence.EntityManager#find(Class, Object, LockModeType)}. */ E find(Object primaryKey, LockModeType lockMode); /** * See {@link jakarta.persistence.EntityManager#find(Class, Object, LockModeType, Map)}. */ E find(Object primaryKey, LockModeType lockMode, Map properties); /** * See {@link jakarta.persistence.EntityManager#getReference(Class, Object)}. */ E getReference(Object primaryKey); /** * See {@link jakarta.persistence.EntityManager#setFlushMode(FlushModeType)}. */ void setFlushMode(FlushModeType flushMode); /** * See {@link jakarta.persistence.EntityManager#getFlushMode()}. */ FlushModeType getFlushMode(); /** * See {@link jakarta.persistence.EntityManager#lock(Object, LockModeType)}. */ void lock(Object entity, LockModeType lockMode); /** * See {@link jakarta.persistence.EntityManager#lock(Object, LockModeType, Map)}. */ void lock(Object entity, LockModeType lockMode, Map properties); /** * See {@link jakarta.persistence.EntityManager#refresh(Object, Map)}. */ void refresh(E entity, Map properties); /** * See {@link jakarta.persistence.EntityManager#refresh(Object, LockModeType)}. */ void refresh(E entity, LockModeType lockMode); /** * See {@link jakarta.persistence.EntityManager#refresh(Object, LockModeType, Map)}. */ void refresh(E entity, LockModeType lockMode, Map properties); /** * See {@link jakarta.persistence.EntityManager#clear()}. */ void clear(); /** * See {@link jakarta.persistence.EntityManager#detach(Object)}. */ void detach(E entity); /** * See {@link jakarta.persistence.EntityManager#contains(Object)}. */ boolean contains(E entity); /** * See {@link jakarta.persistence.EntityManager#getLockMode(Object)}. */ LockModeType getLockMode(E entity); /** * See {@link jakarta.persistence.EntityManager#setProperty(String, Object)}. */ void setProperty(String propertyName, Object value); /** * See {@link jakarta.persistence.EntityManager#getProperties()}. */ Map getProperties(); /** * See {@link jakarta.persistence.EntityManager#joinTransaction()}. */ void joinTransaction(); /** * See {@link jakarta.persistence.EntityManager#unwrap(Class)}. */ T unwrap(Class cls); /** * See {@link jakarta.persistence.EntityManager#getDelegate()}. */ Object getDelegate(); /** * See {@link jakarta.persistence.EntityManager#close()}. */ void close(); /** * See {@link jakarta.persistence.EntityManager#isOpen()}. */ boolean isOpen(); /** * See {@link jakarta.persistence.EntityManager#getTransaction()}. */ EntityTransaction getTransaction(); /** * See {@link jakarta.persistence.EntityManager#getEntityManagerFactory()}. */ EntityManagerFactory getEntityManagerFactory(); /** * See {@link jakarta.persistence.EntityManager#getCriteriaBuilder()}. */ CriteriaBuilder getCriteriaBuilder(); /** * See {@link jakarta.persistence.EntityManager#getMetamodel()}. */ Metamodel getMetamodel(); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; /** * Resolve the EntityManager used for a specific repository. * Only necessary if there is more than one persistence unit. * * This interface is deprecated and instead you should use the version from JPA module */ @Deprecated public interface EntityManagerResolver extends org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityPersistenceRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import org.apache.deltaspike.core.spi.activation.Deactivatable; import java.io.Serializable; public interface EntityPersistenceRepository extends Deactivatable { /** * Persist (new entity) or merge the given entity. The distinction on calling either * method is done based on the primary key field being null or not. * If this results in wrong behavior for a specific case, consider using the * {@link org.apache.deltaspike.data.api.EntityManagerDelegate} which offers both * {@code persist} and {@code merge}. * @param entity Entity to save. * @return Returns the modified entity. */ E save(E entity); /** * {@link #save(Object)}s the given entity and flushes the persistence context afterwards. * @param entity Entity to save. * @return Returns the modified entity. */ E saveAndFlush(E entity); /** * {@link #save(Object)}s the given entity and flushes the persistence context afterwards, * followed by a refresh (e.g. to load DB trigger modifications). * @param entity Entity to save. * @return Returns the modified entity. */ E saveAndFlushAndRefresh(E entity); /** * Convenience access to {@link jakarta.persistence.EntityManager#remove(Object)}. * @param entity Entity to remove. */ void remove(E entity); /** * Convenience access to {@link jakarta.persistence.EntityManager#remove(Object)} * with a following flush. * @param entity Entity to remove. */ void removeAndFlush(E entity); /** * Convenience access to {@link jakarta.persistence.EntityManager#remove(Object)} * with an detached entity. * @param entity Entity to remove. */ void attachAndRemove(E entity); /** * Convenience access to {@link jakarta.persistence.EntityManager#refresh(Object)}. * @param entity Entity to refresh. */ void refresh(E entity); /** * Convenience access to {@link jakarta.persistence.EntityManager#flush()}. */ void flush(); /** * Return the id of the entity. Returns null if the entity does not yet have an id. * @param example Sample entity. * @return id of the entity */ PK getPrimaryKey(E example); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/EntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.io.Serializable; import java.util.List; import java.util.Optional; import jakarta.persistence.metamodel.SingularAttribute; /** * Base Repository interface. All methods are implemented by the CDI extension. * * @param Entity type. * @param Primary key type. */ public interface EntityRepository extends EntityPersistenceRepository, EntityCountRepository { /** * Entity lookup by primary key. Convenicence method around * {@link jakarta.persistence.EntityManager#find(Class, Object)}. * @param primaryKey DB primary key. * @return Entity identified by primary or null if it does not exist. */ E findBy(PK primaryKey); /** * Entity lookup by primary key. Convenicence method around * {@link jakarta.persistence.EntityManager#find(Class, Object)}. * @param primaryKey DB primary key. * @return Entity identified by primary or null if it does not exist, wrapped by Optional. */ Optional findOptionalBy(PK primaryKey); /** * Lookup all existing entities of entity class {@code }. * @return List of entities, empty if none found. */ List findAll(); /** * Lookup a range of existing entities of entity class {@code } with support for pagination. * @param start The starting position. * @param max The maximum number of results to return * @return List of entities, empty if none found. */ List findAll(int start, int max); /** * Query by example - for a given object and a specific set of properties. * @param example Sample entity. Query all like. * @param attributes Which attributes to consider for the query. * @return List of entities matching the example, or empty if none found. */ List findBy(E example, SingularAttribute... attributes); /** * Query by example - for a given object and a specific set of properties with support for pagination. * @param example Sample entity. Query all like. * @param start The starting position. * @param max The maximum number of results to return * @param attributes Which attributes to consider for the query. * @return List of entities matching the example, or empty if none found. */ List findBy(E example, int start, int max, SingularAttribute... attributes); /** * Query by example - for a given object and a specific set of properties using a like operator for Strings. * @param example Sample entity. Query all like. * @param attributes Which attributes to consider for the query. * @return List of entities matching the example, or empty if none found. */ List findByLike(E example, SingularAttribute... attributes); /** * Query by example - for a given object and a specific set of properties * using a like operator for Strings with support for pagination. * @param example Sample entity. Query all like. * @param start The starting position. * @param max The maximum number of results to return * @param attributes Which attributes to consider for the query. * @return List of entities matching the example, or empty if none found. */ List findByLike(E example, int start, int max, SingularAttribute... attributes); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/FirstResult.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Use paging for the query. Must be applied to an Integer parameter. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface FirstResult { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/FullEntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.io.Serializable; import org.apache.deltaspike.data.api.criteria.CriteriaSupport; /** * Full repository interface. A convenience class combining {@code EntityRepository}, * {@code EntityManagerDelegate} and {@code CriteriaSupport}. * * @param Entity type. * @param Primary key type. */ public interface FullEntityRepository extends EntityRepository, EntityManagerDelegate, CriteriaSupport { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/MaxResults.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Limit the size of the result set. Must be applied to an Integer parameter. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface MaxResults { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Modifying.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a query method to be modifying. This will execute the * {@link jakarta.persistence.Query#executeUpdate()} method instead of * {@link jakarta.persistence.Query#getResultList()} (or the corresponding single result method). */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Modifying { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Query.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import jakarta.persistence.LockModeType; import jakarta.persistence.QueryHint; /** * Supply query meta data to a method with this annotation.
* Currently supports: *

  • JPQL queries as part of the annotation value
  • *
  • Execute named queries referenced by the named value
  • *
  • Execute native SQL queries
  • *
  • Restrict the result size to a static value
  • *
  • Provide a lock mode
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Inherited public @interface Query { /** * Defines the Query to execute. Can be left empty for method expression queries * or when referencing a {@link #named()} query. */ String value() default ""; /** * References a named query. */ String named() default ""; /** * Defines a native SQL query. */ boolean isNative() default false; /** * Limits the number of results the query returns. */ int max() default 0; /** * Defines a lock mode for the query. */ LockModeType lock() default LockModeType.NONE; /** * (Optional) Query properties and hints. May include vendor-specific query hints. */ QueryHint[] hints() default { }; /** * Defines how a single result query is fetched. Defaults to the JPA way with * Exceptions thrown on non-single result queries. */ SingleResultType singleResult() default SingleResultType.JPA; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryInvocationException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.reflect.Method; import org.apache.deltaspike.data.spi.QueryInvocationContext; public class QueryInvocationException extends RuntimeException { private static final long serialVersionUID = 1L; public QueryInvocationException(Throwable t, QueryInvocationContext context) { super(createMessage(context, t), t); } public QueryInvocationException(String message, QueryInvocationContext context) { super(createMessage(context)); } public QueryInvocationException(Throwable t, Class proxy, Method method) { super(createMessage(proxy, method, t), t); } private static String createMessage(QueryInvocationContext context) { StringBuilder builder = new StringBuilder(); builder.append("Failed calling Repository: ["); builder.append("Repository=").append(context.getRepositoryClass().getName()).append(","); builder.append("entity=").append(context.getEntityClass().getName()).append(","); builder.append("method=").append(context.getMethod().getName()).append(","); return builder.toString(); } private static String createMessage(QueryInvocationContext context, Throwable t) { StringBuilder builder = new StringBuilder(createMessage(context)); builder.append("exception=").append(t.getClass()).append(",message=").append(t.getMessage()); return builder.toString(); } private static String createMessage(Class repoClass, Method method, Throwable t) { StringBuilder builder = new StringBuilder(); builder.append("Exception calling Repository: ["); builder.append("Repository=").append(repoClass).append(","); builder.append("method=").append(method.getName()).append("],"); builder.append("exception=").append(t.getClass()).append(",message=").append(t.getMessage()); return builder.toString(); } } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryParam.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Mark a method parameter as a query parameter. * Can be named by the annotation value. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface QueryParam { String value() default ""; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/QueryResult.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.util.List; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.metamodel.SingularAttribute; /** * Can be used as query result type, which will not execute the query immediately. * Allows some post processing like defining query ordering. * * @param Entity type */ public interface QueryResult { /** * Sort the query result ascending by the given entity singular attribute. * This is the typesafe version, alternatively a {@link #orderAsc(String)} * String can be used. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult orderAsc(SingularAttribute attribute); /** * Sort the query result ascending by the given entity singular attribute. * This is the typesafe version, alternatively a {@link #orderAsc(String)} * String can be used. * * @param attribute Sort attribute. * @param appendEntityName whether the entity name 'e' should be appended to this attribute * @return Fluent API: the result instance. */ QueryResult orderAsc(SingularAttribute attribute, boolean appendEntityName); /** * Sort the query result ascending by the given entity attribute. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult orderAsc(String attribute); /** * Sort the query result ascending by the given entity attribute. * * @param attribute Sort attribute. * @param appendEntityName whether the entity name 'e' should be appended to this attribute * @return Fluent API: the result instance. */ QueryResult orderAsc(String attribute, boolean appendEntityName); /** * Sort the query result descending by the given entity singular attribute. * This is the typesafe version, alternatively a {@link #orderDesc(String)} * String can be used. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult orderDesc(SingularAttribute attribute); /** * Sort the query result descending by the given entity singular attribute. * This is the typesafe version, alternatively a {@link #orderDesc(String)} * String can be used. * * @param attribute Sort attribute. * @param appendEntityName whether the entity name 'e' should be appended to this attribute * @return Fluent API: the result instance. */ QueryResult orderDesc(SingularAttribute attribute, boolean appendEntityName); /** * Sort the query result descending by the given entity attribute. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult orderDesc(String attribute); /** * Sort the query result descending by the given entity attribute. * * @param attribute Sort attribute. * @param appendEntityName whether the entity name 'e' should be appended to this attribute * @return Fluent API: the result instance. */ QueryResult orderDesc(String attribute, boolean appendEntityName); /** * Revert an existing order attribute sort direction. Defaults to ascending * order if the sort attribute was not used before. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult changeOrder(SingularAttribute attribute); /** * Remove any ordering from the query result object. * * @return Fluent API: the result instance. */ QueryResult clearOrder(); /** * Revert an existing order attribute sort direction. Defaults to ascending * order if the sort attribute was not used before. * * @param attribute Sort attribute. * @return Fluent API: the result instance. */ QueryResult changeOrder(String attribute); /** * Limit the number of results returned by the query. * * @param max Max number of results. * @return Fluent API: the result instance. */ QueryResult maxResults(int max); /** * Pagination: Set the result start position. * * @param first Result start position. * @return Fluent API: the result instance. */ QueryResult firstResult(int first); /** * Sets the query lock mode. * * @param lockMode Query lock mode to use in the query. * @return Fluent API: the result instance. */ QueryResult lockMode(LockModeType lockMode); /** * Sets the query flush mode. * * @param flushMode Query flush mode to use in the query. * @return Fluent API: the result instance. */ QueryResult flushMode(FlushModeType flushMode); /** * Apply a query hint to the query to execute. * * @param hint Hint name. * @param value Hint value. * @return Fluent API: the result instance. */ QueryResult hint(String hint, Object value); /** * Fetch the result set. * * @return List of entities retrieved by the query. */ List getResultList(); /** * Fetch a single result entity. * * @return Entity retrieved by the query. */ E getSingleResult(); /** * Fetch a single result entity. Returns {@code null} if no result is found. * * @return Entity retrieved by the query, or {@code null} if no result. */ E getOptionalResult(); /** * Fetch a single result entity. Returns {@code null} if no result is found. If the * query finds multiple results, it simply returns the first one found. * * @return First Entity retrieved by the query, or {@code null} if no result. */ E getAnyResult(); /** * Count the result set. * * @return Result count. */ long count(); /** * Set a page size on the query result. Defaults to 10 or takes the value of a * previous {@link #maxResults(int)} call. * * @param pageSize Page size for further queries. * @return Fluent API: the result instance. */ QueryResult withPageSize(int pageSize); /** * Move the page cursor to a specific page. * * @param page Page to move to for the next query. * @return Fluent API: the result instance. */ QueryResult toPage(int page); /** * Move to the next page. * * @return Fluent API: the result instance. */ QueryResult nextPage(); /** * Move to the previous page. * * @return Fluent API: the result instance. */ QueryResult previousPage(); /** * Count the number of pages. * * @return Page count. */ int countPages(); /** * Return the actual page. * * @return Page position. */ int currentPage(); /** * Return the actual page size. * * @return Page size. */ int pageSize(); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/Repository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Stereotype; /** * The Repository annotation needs to be present in order to have the * interface or class to be processed by the CDI extension. */ @Stereotype @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Inherited @Dependent @PartialBeanBinding public @interface Repository { /** * Relates the repository to a specific Entity. Can be left to * default when the Entity is determined by one of the base * repository classes. */ Class forEntity() default Object.class; /** * The method prefix for method expressions. Can be adapted to * domain specific conventions. */ String methodPrefix() default ""; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/SingleResultType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api; /** * Defines the way a single result query is fetched. */ public enum SingleResultType { /** * Expects a single result, throws a {@link jakarta.persistence.NoResultException} or * {@link jakarta.persistence.NonUniqueResultException} otherwise. This is the JPA * default behavior. */ JPA, /** * Expects a single result. Other than {@link SingleResultType#JPA} it returns {@code null} * if no result is found. */ OPTIONAL, /** * Returns any result, or {@code null} if nothing is found. If more than one result is found, * it returns the first one from the result list. */ ANY } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CreatedBy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.audit; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a property which should be updated with the current when the entity gets persisted. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface CreatedBy { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CreatedOn.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.audit; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a property which should be updated with a timestamp when the entity gets persisted. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface CreatedOn { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/CurrentUser.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.audit; 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 static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.inject.Qualifier; /** * Identifies the current user responsible for entity creation or modification. */ @Qualifier @Target({ TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented public @interface CurrentUser { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedBy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.audit; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a property which should keep track on the last changing user. * By setting {@link #onCreate()} to {@code false}, the property gets NOT set when * the entity is persisted. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface ModifiedBy { boolean onCreate() default true; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/audit/ModifiedOn.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.audit; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a property which should be updated with a timestamp when the entity gets updated. * By setting {@link #onCreate()} to {@code true}, the property gets also set when * the entity is persisted. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD, ElementType.METHOD }) public @interface ModifiedOn { /** * Tells whether or not the property shall be set when the entity is first persisted. * @deprecated If the property shall be set when the entity is first persisted, use {@link CreatedOn}. * @return set this to {@code true} if the property shall be set when the entity is first persisted. */ boolean onCreate() default false; } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/Criteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.criteria; import java.util.Collection; import java.util.List; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.CollectionAttribute; import jakarta.persistence.metamodel.ListAttribute; import jakarta.persistence.metamodel.MapAttribute; import jakarta.persistence.metamodel.PluralAttribute; import jakarta.persistence.metamodel.SetAttribute; import jakarta.persistence.metamodel.SingularAttribute; /** * Criteria API utilities. * * @param Entity type. * @param Result type. */ public interface Criteria { /** * Executes the query and returns the result list. * @return List of entities matching the query. */ List getResultList(); /** * Executes the query which has a single result. * @return Entity matching the search query. */ R getSingleResult(); /** * Executes the query which has a single result. Returns {@code null} * if there is no result. * @return Entity matching the search query, or {@code null} if there is none. */ R getOptionalResult(); /** * Executes the query and returns a single result. If there are * multiple results, the first received is returned. * @return Entity matching the search query. */ R getAnyResult(); /** * Creates a JPA query object to be executed. * @return A {@link TypedQuery} object ready to return results. */ TypedQuery createQuery(); /** * Boolean OR with another Criteria. * @param criteria The right side of the boolean OR. * @return Fluent API: Criteria instance. */ Criteria or(Criteria... criteria); /** * Boolean OR with another Criteria. * @param criteria The right side of the boolean OR. * @return Fluent API: Criteria instance. */ Criteria or(Collection> criteria); /** * Join an attribute with another Criteria. * @param att The attribute to join. * @param criteria The join criteria. * @return Fluent API: Criteria instance. */ Criteria join(SingularAttribute att, Criteria criteria); /** * Join a collection attribute with another Criteria. * @param att The attribute to join. * @param criteria The join criteria. * @return Fluent API: Criteria instance. */ Criteria join(ListAttribute att, Criteria criteria); /** * Join a collection attribute with another Criteria. * @param att The attribute to join. * @param criteria The join criteria. * @return Fluent API: Criteria instance. */ Criteria join(CollectionAttribute att, Criteria criteria); /** * Join a collection attribute with another Criteria. * @param att The attribute to join. * @param criteria The join criteria. * @return Fluent API: Criteria instance. */ Criteria join(SetAttribute att, Criteria criteria); /** * Join a collection attribute with another Criteria. * @param att The attribute to join. * @param criteria The join criteria. * @return Fluent API: Criteria instance. */ Criteria join(MapAttribute att, Criteria criteria); /** * Fetch join an attribute. * @param att The attribute to fetch. * @return Fluent API: Criteria instance. */ Criteria fetch(SingularAttribute att); /** * Fetch join an attribute. * @param att The attribute to fetch. * @param joinType The JoinType to use. * @return Fluent API: Criteria instance. */ Criteria fetch(SingularAttribute att, JoinType joinType); /** * Fetch join an attribute. * @param att The attribute to fetch. * @return Fluent API: Criteria instance. */ Criteria fetch(PluralAttribute att); /** * Fetch join an attribute. * @param att The attribute to fetch. * @param joinType The JoinType to use. * @return Fluent API: Criteria instance. */ Criteria fetch(PluralAttribute att, JoinType joinType); /** * Apply sorting by an attribute, ascending direction. * @param att The attribute to order for. * @return Fluent API: Criteria instance. */

Criteria orderAsc(SingularAttribute att); /** * Apply sorting by an attribute, descending direction. * @param att The attribute to order for. * @return Fluent API: Criteria instance. */

Criteria orderDesc(SingularAttribute att); /** * Create a select query. * @param resultClass The query result class. * @param selection List of selects (attributes, scalars...) * @return Fluent API: Criteria instance. */ Criteria select(Class resultClass, QuerySelection... selection); /** * Create a select query. * @param selection List of selects (attributes, scalars...) * @return Fluent API: Criteria instance. */ Criteria select(QuerySelection... selection); /** * Apply a distinct on the query. * @return Fluent API: Criteria instance. */ Criteria distinct(); /** * Equals predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria eq(SingularAttribute att, P value); /** * Equals predicate, case insensitive. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria eqIgnoreCase(SingularAttribute att, String value); /** * Not Equals predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria notEq(SingularAttribute att, P value); /** * Not Equals predicate, case insensitive. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria notEqIgnoreCase(SingularAttribute att, String value); /** * Like predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria like(SingularAttribute att, String value); /** * Like predicate, case insensitive. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria likeIgnoreCase(SingularAttribute att, String value); /** * Not like predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria notLike(SingularAttribute att, String value); /** * Not like predicate, case insensitive. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

Criteria notLikeIgnoreCase(SingularAttribute att, String value); /** * Less than predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

> Criteria lt(SingularAttribute att, P value); /** * Less than or equals predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

> Criteria ltOrEq(SingularAttribute att, P value); /** * Greater than predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

> Criteria gt(SingularAttribute att, P value); /** * Greater than or equals predicate. * @param att The attribute to compare with. * @param value The comparison value. * @return Fluent API: Criteria instance. */

> Criteria gtOrEq(SingularAttribute att, P value); /** * Between predicate. * @param att The attribute to compare with. * @param lower The lower bound comparison value. * @param upper The upper bound comparison value. * @return Fluent API: Criteria instance. */

> Criteria between(SingularAttribute att, P lower, P upper); /** * IsNull predicate. * @param att The null attribute. * @return Fluent API: Criteria instance. */

Criteria isNull(SingularAttribute att); /** * NotNull predicate. * @param att The non-null attribute. * @return Fluent API: Criteria instance. */

Criteria notNull(SingularAttribute att); /** * Empty predicate. * @param att The collection attribute to check for emptyness. * @return Fluent API: Criteria instance. */

> Criteria empty(SingularAttribute att); /** * Not empty predicate. * @param att The collection attribute to check for non-emptyness. * @return Fluent API: Criteria instance. */

> Criteria notEmpty(SingularAttribute att); /** * In predicte. * @param att The attribute to check for. * @param values The values for the in predicate. * @return */

Criteria in(SingularAttribute att, P... values); /** * Return the list of predicates applicable for this Criteria instance. * @param builder A CriteriaBuilder used to instantiate the Predicates. * @param path Current path. * @return List of predicates applicable to this Criteria. */ List predicates(CriteriaBuilder builder, Path path); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/CriteriaSupport.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.criteria; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.metamodel.SingularAttribute; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; /** * Interface to be added to a repository for criteria support. * * @param Entity type. */ public interface CriteriaSupport { /** * Create a {@link Criteria} instance. * * @return Criteria instance related to the Repository entity class. */ Criteria criteria(); /** * Create a {@link Criteria} instance. * * @param Type related to the current criteria class. * @param clazz Class other than the current entity class. * @return Criteria instance related to a join type of the current entity class. */ Criteria where(Class clazz); /** * Create a {@link Criteria} instance with a join type. * * @param Type related to the current criteria class. * @param clazz Class other than the current entity class. * @param joinType Join type to apply. * @return Criteria instance related to a join type of the current entity class. */ Criteria where(Class clazz, JoinType joinType); /** * Create a query selection for an Entity attribute. * * @param attribute Attribute to show up in the result selection * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection attribute(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#abs(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection abs(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#avg(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection avg(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#count(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection count(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#countDistinct(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection countDistinct(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#max(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection max(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#min(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection min(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#neg(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection neg(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#sum(jakarta.persistence.criteria.Expression)} * over an attribute. * * @param attribute Attribute to use in the aggregate. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection sum(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#mod(jakarta.persistence.criteria.Expression, Integer)} * for an attribute. * * @param attribute Attribute to use in the aggregate. * @param modulo Modulo what. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection modulo(SingularAttribute attribute, Integer modulo); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#upper(jakarta.persistence.criteria.Expression)} * over a String attribute. * * @param attribute Attribute to uppercase. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection upper(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#lower(jakarta.persistence.criteria.Expression)} * over a String attribute. * * @param attribute Attribute to lowercase. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection lower(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#substring(jakarta.persistence.criteria.Expression, int)} * over a String attribute. * * @param attribute Attribute to create a substring from. * @param from Substring start. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection substring(SingularAttribute attribute, int from); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#substring(jakarta.persistence.criteria.Expression, int, int)} * over a String attribute. * * @param attribute Attribute to create a substring from. * @param from Substring start. * @param length Substring length. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection substring(SingularAttribute attribute, int from, int length); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#trim(jakarta.persistence.criteria.Expression)} * over a String attribute. * * @param attribute Attribute to apply trim. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection trim(SingularAttribute attribute); /** * Create a query selection for the * {@link jakarta.persistence.criteria.CriteriaBuilder#trim(jakarta.persistence.criteria.CriteriaBuilder.Trimspec, * jakarta.persistence.criteria.Expression)} * over a String attribute. * * @param trimspec Used to specify how strings are trimmed. * @param attribute Attribute to apply trim. * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection trim(CriteriaBuilder.Trimspec trimspec, SingularAttribute attribute); /** * Create a query selection for the {@link jakarta.persistence.criteria.CriteriaBuilder#currentDate()}. * * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection currDate(); /** * Create a query selection for the {@link jakarta.persistence.criteria.CriteriaBuilder#currentTime()}. * * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection currTime(); /** * Create a query selection for the {@link jakarta.persistence.criteria.CriteriaBuilder#currentTimestamp()}. * * @return {@link QuerySelection} part of a {@link Criteria#select(Class, QuerySelection...)} call. */ QuerySelection currTStamp(); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/criteria/QuerySelection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.criteria; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; /** * Used for selection queries with the simplified Criteria API. * * @param

Entity type. * @param Result type. */ public interface QuerySelection { /** * Convert the instance to a criteria selection. * @param query The current criteria query. * @param builder The query builder used to instantiate the selection. * @param path Current path. * @return Criteria API selection instance corresponding to the * QuerySelection implementation. */ Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/mapping/MappingConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.mapping; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Defines mapping configuration for query result and input parameters. */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MappingConfig { Class> value(); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/mapping/QueryInOutMapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.mapping; import java.util.List; /** * Handles concrete mapping of query results and * query input parameters. */ public interface QueryInOutMapper { /** * Map a single result query. * @param result The query result to map. * @return The mapped result object. */ Object mapResult(E result); /** * Map a query result list. * @param result The query result list to map. * @return The mapped result. Does not have to be a collection. */ Object mapResultList(List result); /** * Check if this mapper handles a specific input parameter. * @param parameter The parameter candidate for mapping. * @return {@code true} if the mapper handles the parameter. */ boolean mapsParameter(Object parameter); /** * Map a query parameter. * @param parameter The parameter to map. It can be assumed that the * {@link #mapsParameter(Object)} method has been * called before with this parameter. * @return The mapped result. */ Object mapParameter(Object parameter); } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/api/mapping/SimpleQueryInOutMapperBase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.mapping; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; import jakarta.inject.Inject; import org.apache.deltaspike.data.spi.QueryInvocationContext; /** * A base mapper to map from Dto to Entity and vice versa. This should be sufficient * for most mapping cases and simplify the implementation of a mapper. * * @param The Entity type. * @param The Dto type. */ public abstract class SimpleQueryInOutMapperBase implements QueryInOutMapper { @Inject private QueryInvocationContext context; /** * Return the primary key of the Entity corresponding to the Dto. If this is a new * Entity, return {@code null}. * @param dto The Dto to map to an Entity. * @return The Entity primary key, or {@code null} for a new Entity. */ protected abstract Object getPrimaryKey(Dto dto); protected abstract Dto toDto(Entity entity); /** * Map a Dto to an Entity. In case the Dto contains a valid primary key, * the Entity will be retrieved first and used as method parameter. Otherwise * Entity is a unmanaged new instance. * * @param entity Either a managed Entity looked up by the primary key, * or a new Entity instance. * @param dto The Dto to map. * @return Mapped Entity. */ protected abstract Entity toEntity(Entity entity, Dto dto); @Override public Object mapResult(final Entity result) { if (result == null) { return null; } return toDto(result); } @Override public Object mapResultList(final List result) { if (result != null) { final List mapped = new ArrayList(result.size()); for (final Entity a : result) { mapped.add(mapResult(a)); } return mapped; } return new ArrayList(); } @Override public boolean mapsParameter(final Object parameter) { if (parameter == null) { return false; } final String name = parameter.getClass().getName(); return Object.class.isInstance(parameter) && !(name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("jakarta.")); } @Override public Object mapParameter(final Object parameter) { Dto dto = (Dto) parameter; Object primaryKey = getPrimaryKey(dto); if (primaryKey != null) { Entity entity = findEntity(primaryKey); return toEntity(entity, dto); } return toEntity(newEntity(), dto); } @SuppressWarnings("unchecked") protected Entity newEntity() { try { Class entityClass = context.getEntityClass(); Constructor constructor = entityClass.getDeclaredConstructor(); constructor.setAccessible(true); return (Entity) constructor.newInstance(); } catch (Exception e) { throw new RuntimeException("Failed instantiating new Entity", e); } } @SuppressWarnings("unchecked") protected Entity findEntity(Object primaryKey) { return (Entity) context.getEntityManager().find(context.getEntityClass(), primaryKey); } } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/DelegateQueryHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.spi; /** * A marker interface. Used for writing custom query methods: *
 * public interface RepositoryExtension {
 *     E saveAndFlushAndRefresh(E entity);
 * }
 *
 * public class DelegateRepositoryExtension implements RepositoryExtension, DelegateQueryHandler {
 *    @Inject
 *    private QueryInvocationContext context;
 *
 *    @Override
 *    public E saveAndFlushAndRefresh(E entity) {
 *        ...
 *    }
 * }
 * 
* * The extension is now usable with: *
 * @Repository
 * public interface MySimpleRepository
 *         extends RepositoryExtension, EntityRepository {
 * }
 * 
*/ public interface DelegateQueryHandler { } ================================================ FILE: deltaspike/modules/data/api/src/main/java/org/apache/deltaspike/data/spi/QueryInvocationContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.spi; import jakarta.persistence.EntityManager; import java.lang.reflect.Method; /** * Expose the current query invocation to extensions. */ public interface QueryInvocationContext { /** * Entity Manager used for the query. */ EntityManager getEntityManager(); /** * The class of the Entity related to the invoked Repository. */ Class getEntityClass(); /** * Given the object parameter is an entity, checks if the entity is * persisted or not. * * @param entity Entity object, non nullable. * @return true if the entity is not persisted, false otherwise and if no entity. */ boolean isNew(Object entity); /** * The type of the repository currently accessed. */ Class getRepositoryClass(); /** * The repository method currently executed. */ Method getMethod(); } ================================================ FILE: deltaspike/modules/data/api/src/test/java/org/apache/deltaspike/data/api/mapping/SimpleQueryInOutMapperBaseTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.api.mapping; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.List; import org.junit.Test; public class SimpleQueryInOutMapperBaseTest { @Test public void checkDefault() { final SimpleQueryInOutMapperBase mapper = new SimpleQueryInOutMapperBase() { @Override public Integer toDto(final String result) { return result.length(); } @Override protected String toEntity(String entity, Integer b) { return entity; } @Override protected Object getPrimaryKey(Integer dto) { return null; } @Override protected String newEntity() { return "ok"; } }; assertNull(mapper.mapResult(null)); assertEquals(2, mapper.mapResult("ab")); final List collection = List.class.cast(mapper.mapResultList(Arrays.asList(null, "a", "bc"))); assertEquals(3, collection.size()); assertEquals(Arrays.asList(null, 1, 2), collection); assertFalse(mapper.mapsParameter(null)); assertFalse(mapper.mapsParameter("foo")); assertFalse(mapper.mapsParameter(true)); assertFalse(mapper.mapsParameter(2)); assertTrue(mapper.mapsParameter(new Object() { })); // this test is particular cause we refuse String but forcing call to it we having the mapper behavior // but at least we test what is expected! assertEquals("ok", mapper.mapParameter(2)); } } ================================================ FILE: deltaspike/modules/data/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules data-module-project 2.0.2-SNAPSHOT deltaspike-data-module-impl jar Apache DeltaSpike Data-Module Impl org.apache.deltaspike.data.impl.* jakarta.persistence.*, org.apache.deltaspike.jpa.impl.transaction, !org.apache.deltaspike.data.impl.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.ops4j.pax.cdi.extension; extension=deltaspike-data-module-impl org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${project.version} org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} org.apache.deltaspike.modules deltaspike-data-module-api ${project.version} org.apache.deltaspike.modules deltaspike-data-module-impl ${project.version} runtime org.apache.maven.plugins maven-surefire-plugin -Xms128m -Xmx1024m org.bsc.maven maven-processor-plugin 2.0.7 process-test process-test generate-test-sources org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor org.hibernate hibernate-jpamodelgen 6.2.0.CR4 jakarta.persistence jakarta.persistence-api jakarta.transaction jakarta.transaction-api org.apache.deltaspike.modules deltaspike-data-module-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-partial-bean-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jpa-module-impl ${project.version} compile org.jboss.shrinkwrap.resolver shrinkwrap-resolver-impl-maven test org.jboss.shrinkwrap.descriptors shrinkwrap-descriptors-impl-javaee test wildfly-build-managed src/test/resources src/test/resources-wildfly wildfly-managed src/test/resources src/test/resources-wildfly wildfly-remote src/test/resources src/test/resources-wildfly glassfish-remote src/test/resources src/test/resources-payara payara-build-managed src/test/resources src/test/resources-payara tomee-build-managed src/test/resources src/test/resources-openejb wls-remote-12c src/test/resources src/test/resources-weblogic wls-managed-12c src/test/resources src/test/resources-weblogic ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/RepositoryExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl; import java.lang.reflect.InvocationHandler; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.BeforeShutdown; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.AbstractFullEntityRepository; import org.apache.deltaspike.data.api.Repository; /** * The main extension class for Repositories, based on PartialBeans. Handles following events:
*
* {@code @Observes BeforeBeanDiscovery}: * Scans the classpath for persistence.xml and extracts relevant information out of it. * This includes mainly entity definitions (type, primary keys) which are not declared with annotations.
*
* {@code @Observes ProcessAnnotatedType}: * Looks for types annotated with {@link Repository}. Repositories are validated and preprocessed - * all the methods on the repository are checked and analyzed for better runtime performance.
*
* {@code @Observes AfterBeanDiscovery}: * Raises any definition errors discovered before. */ public class RepositoryExtension implements Extension, Deactivatable { private static final Logger LOG = Logger.getLogger(RepositoryExtension.class.getName()); // TODO: Hack still required? private static final ArrayList> REPOSITORY_CLASSES = new ArrayList>(); private final ArrayList> repositoryClasses = new ArrayList>(); private Boolean isActivated = true; void beforeBeanDiscovery(@Observes BeforeBeanDiscovery before) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } @SuppressWarnings("unchecked") void processAnnotatedType(@Observes ProcessAnnotatedType event) { if (!isActivated) { return; } if (isVetoed(event.getAnnotatedType())) { event.veto(); } else if (isRepository(event.getAnnotatedType())) { Class repositoryClass = event.getAnnotatedType().getJavaClass(); LOG.log(Level.FINER, "getHandlerClass: Repository annotation detected on {0}", event.getAnnotatedType()); if (Deactivatable.class.isAssignableFrom(repositoryClass) && !ClassDeactivationUtils.isActivated((Class) repositoryClass)) { LOG.log(Level.FINER, "Class {0} is Deactivated", repositoryClass); return; } repositoryClasses.add(repositoryClass); REPOSITORY_CLASSES.add(repositoryClass); } } private boolean isRepository(AnnotatedType annotatedType) { return (annotatedType.isAnnotationPresent(Repository.class) || annotatedType.getJavaClass().isAnnotationPresent(Repository.class)) && !InvocationHandler.class.isAssignableFrom(annotatedType.getJavaClass()); } private boolean isVetoed(AnnotatedType annotated) { Class javaClass = annotated.getJavaClass(); return javaClass.equals(AbstractEntityRepository.class) || javaClass.equals(AbstractFullEntityRepository.class); } public ArrayList> getRepositoryClasses() { ArrayList> result = new ArrayList>(); if (repositoryClasses.isEmpty() && !REPOSITORY_CLASSES.isEmpty()) { result.addAll(REPOSITORY_CLASSES); } if (!repositoryClasses.isEmpty()) { result.addAll(repositoryClasses); } return result; } protected void cleanup(@Observes BeforeShutdown beforeShutdown) { //we can reset it in any case, //because every application produced a copy as application-scoped bean (see RepositoryComponentsFactory) REPOSITORY_CLASSES.clear(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditEntityListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import java.util.Set; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.persistence.PrePersist; import jakarta.persistence.PreUpdate; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; public class AuditEntityListener { @PrePersist public void persist(Object entity) { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Set> beans = beanManager.getBeans(PrePersistAuditListener.class); for (Bean bean : beans) { PrePersistAuditListener result = (PrePersistAuditListener) beanManager.getReference( bean, PrePersistAuditListener.class, beanManager.createCreationalContext(bean)); result.prePersist(entity); } } @PreUpdate public void update(Object entity) { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Set> beans = beanManager.getBeans(PreUpdateAuditListener.class); for (Bean bean : beans) { PreUpdateAuditListener result = (PreUpdateAuditListener) beanManager.getReference( bean, PreUpdateAuditListener.class, beanManager.createCreationalContext(bean)); result.preUpdate(entity); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditPropertyException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; public class AuditPropertyException extends RuntimeException { private static final long serialVersionUID = -8725707870578473975L; public AuditPropertyException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/AuditProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import java.lang.annotation.Annotation; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.property.query.AnnotatedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyQueries; import org.apache.deltaspike.data.impl.property.query.PropertyQuery; abstract class AuditProvider implements PrePersistAuditListener, PreUpdateAuditListener { protected static final Logger log = Logger.getLogger(AuditProvider.class.getName()); String propertyName(Object entity, Property property) { return entity.getClass().getSimpleName() + "." + property.getName(); } List> getProperties( Object entity, Class createdAnnotation, Class modifiedAnnotation, boolean create) { List> properties = new LinkedList<>(); PropertyQuery query = PropertyQueries.createQuery(entity.getClass()) .addCriteria(new AnnotatedPropertyCriteria(modifiedAnnotation)); properties.addAll(query.getWritableResultList()); if (create) { query = PropertyQueries. createQuery(entity.getClass()) .addCriteria(new AnnotatedPropertyCriteria(createdAnnotation)); properties.addAll(query.getWritableResultList()); } return properties; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrePersistAuditListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; public interface PrePersistAuditListener { void prePersist(Object entity); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PreUpdateAuditListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; public interface PreUpdateAuditListener { void preUpdate(Object entity); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/PrincipalProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import java.util.Set; import java.util.logging.Level; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.data.api.audit.CreatedBy; import org.apache.deltaspike.data.api.audit.CurrentUser; import org.apache.deltaspike.data.api.audit.ModifiedBy; import org.apache.deltaspike.data.impl.property.Property; @Dependent class PrincipalProvider extends AuditProvider { @Inject private BeanManager manager; @Override public void prePersist(Object entity) { updatePrincipal(entity, true); } @Override public void preUpdate(Object entity) { updatePrincipal(entity, false); } private void updatePrincipal(Object entity, boolean create) { for (Property property : getProperties(entity, CreatedBy.class, ModifiedBy.class, create)) { setProperty(entity, property, create); } } private void setProperty(Object entity, Property property, boolean create) { try { if (!isCorrectContext(property, create)) { return; } Object value = resolvePrincipal(entity, property); property.setValue(entity, value); log.log(Level.FINER, "Updated {0} with {1}", new Object[] { propertyName(entity, property), value }); } catch (Exception e) { throw new AuditPropertyException("Failed to write principal to " + propertyName(entity, property), e); } } private boolean isCorrectContext(Property property, boolean create) { if (create && property.getAnnotatedElement().isAnnotationPresent(ModifiedBy.class)) { ModifiedBy annotation = property.getAnnotatedElement().getAnnotation(ModifiedBy.class); if (!annotation.onCreate()) { return false; } } return true; } protected Object resolvePrincipal(Object entity, Property property) { CurrentUser principal = AnnotationInstanceProvider.of(CurrentUser.class); Class propertyClass = property.getJavaClass(); Set> beans = manager.getBeans(propertyClass, principal); if (!beans.isEmpty() && beans.size() == 1) { Bean bean = beans.iterator().next(); Object result = manager.getReference(bean, propertyClass, manager.createCreationalContext(bean)); return result; } throw new IllegalArgumentException("Principal " + (beans.isEmpty() ? "not found" : "not unique") + " for " + propertyName(entity, property)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/audit/TimestampsProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import java.util.Calendar; import java.util.Date; import java.util.logging.Level; import jakarta.enterprise.context.Dependent; import org.apache.deltaspike.data.api.audit.CreatedOn; import org.apache.deltaspike.data.api.audit.ModifiedOn; import org.apache.deltaspike.data.impl.property.Property; /** * Set timestamps on marked properties. */ @Dependent class TimestampsProvider extends AuditProvider { @Override public void prePersist(Object entity) { updateTimestamps(entity, true); } @Override public void preUpdate(Object entity) { updateTimestamps(entity, false); } private void updateTimestamps(Object entity, boolean create) { long systime = System.currentTimeMillis(); for (Property property : getProperties(entity, CreatedOn.class, ModifiedOn.class, create)) { setProperty(entity, property, systime, create); } } private void setProperty(Object entity, Property property, long systime, boolean create) { try { if (!isCorrectContext(property, create)) { return; } Object now = now(property.getJavaClass(), systime); property.setValue(entity, now); log.log(Level.FINER, "Updated property {0} with {1}", new Object[] { propertyName(entity, property), now }); } catch (Exception e) { String message = "Failed to set property " + propertyName(entity, property) + ", is this a temporal type?"; throw new AuditPropertyException(message, e); } } private boolean isCorrectContext(Property property, boolean create) { if (create && property.getAnnotatedElement().isAnnotationPresent(ModifiedOn.class)) { ModifiedOn annotation = property.getAnnotatedElement().getAnnotation(ModifiedOn.class); if (!annotation.onCreate()) { return false; } } return true; } private Object now(Class field, long systime) throws Exception { if (isCalendarClass(field)) { Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(systime); return cal; } else if (isDateClass(field)) { return field.getConstructor(Long.TYPE).newInstance(systime); } throw new IllegalArgumentException("Annotated field is not a date class: " + field); } private boolean isCalendarClass(Class field) { return Calendar.class.isAssignableFrom(field); } private boolean isDateClass(Class field) { return Date.class.isAssignableFrom(field); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/AnnotatedQueryBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.param.Parameters; import org.apache.deltaspike.data.impl.util.jpa.QueryStringExtractorFactory; import jakarta.persistence.Entity; import jakarta.persistence.EntityManager; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.List; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.core.util.ClassUtils; import static org.apache.deltaspike.core.util.StringUtils.isNotEmpty; /** * Create the query based on method annotations. */ @ApplicationScoped public class AnnotatedQueryBuilder extends QueryBuilder { private final QueryStringExtractorFactory factory = new QueryStringExtractorFactory(); @Override public Object execute(CdiQueryInvocationContext context) { Method method = context.getMethod(); Query query = method.getAnnotation(Query.class); jakarta.persistence.Query jpaQuery = createJpaQuery(query, context); return context.executeQuery(jpaQuery); } private jakarta.persistence.Query createJpaQuery(Query query, CdiQueryInvocationContext context) { EntityManager entityManager = context.getEntityManager(); Parameters params = context.getParams(); jakarta.persistence.Query result = null; if (isNotEmpty(query.named())) { if (!context.hasQueryStringPostProcessors()) { result = params.applyTo(entityManager.createNamedQuery(query.named())); } else { jakarta.persistence.Query namedQuery = entityManager.createNamedQuery(query.named()); String named = factory.extract(namedQuery); String jpqlQuery = context.applyQueryStringPostProcessors(named); result = params.applyTo(entityManager.createQuery(jpqlQuery)); } } else if (query.isNative()) { String jpqlQuery = context.applyQueryStringPostProcessors(query.value()); Class resultType = getQueryResultType(context.getMethod()); if (isEntityType(resultType)) { result = params.applyTo(entityManager.createNativeQuery(jpqlQuery, resultType)); } else { result = params.applyTo(entityManager.createNativeQuery(jpqlQuery)); } } else { String jpqlQuery = context.applyQueryStringPostProcessors(query.value()); context.setQueryString(jpqlQuery); result = params.applyTo(entityManager.createQuery(jpqlQuery)); } return context.applyRestrictions(result); } private boolean isEntityType(Class cls) { return cls.getAnnotation(Entity.class) != null; } private Class getQueryResultType(Method method) { if (ClassUtils.returns(method, List.class) && !ClassUtils.returns(method, Object.class)) { ParameterizedType pt = (ParameterizedType) method.getGenericReturnType(); return (Class) pt.getActualTypeArguments()[0]; } return method.getReturnType(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/DelegateQueryBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.persistence.PersistenceException; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.data.api.QueryInvocationException; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.util.bean.BeanDestroyable; import org.apache.deltaspike.data.spi.DelegateQueryHandler; @ApplicationScoped public class DelegateQueryBuilder extends QueryBuilder { @Inject private BeanManager beanManager; private final Map> lookupCache = new HashMap<>(); @Override public Object execute(CdiQueryInvocationContext context) { try { DelegateQueryHandler delegate = lookup(context); if (delegate != null) { Object result = invoke(delegate, context); if (result instanceof Collection && context.getRepositoryMethodMetadata().isReturnsStream()) { return ((Collection) result).stream(); } else if (context.getRepositoryMethodMetadata().isReturnsOptional() && !(result instanceof Optional)) { return Optional.ofNullable(result); } else { return result; } } } catch (PersistenceException e) { throw e; } catch (Exception e) { throw new QueryInvocationException(e, context); } throw new QueryInvocationException("No DelegateQueryHandler found", context); } private DelegateQueryHandler lookup(CdiQueryInvocationContext context) { Bean selectedBean = lookupCache.get(context.getMethod()); if (selectedBean == null) { Set> beans = BeanProvider .getBeanDefinitions(DelegateQueryHandler.class, true, true); for (Bean bean : beans) { if (ClassUtils.containsPossiblyGenericMethod(bean.getBeanClass(), context.getMethod())) { selectedBean = bean; } } if (selectedBean != null) { lookupCache.put(context.getMethod(), selectedBean); } } if (selectedBean != null) { CreationalContext cc = beanManager.createCreationalContext(selectedBean); DelegateQueryHandler instance = (DelegateQueryHandler) beanManager.getReference( selectedBean, DelegateQueryHandler.class, cc); if (selectedBean.getScope().equals(Dependent.class)) { context.addDestroyable(new BeanDestroyable(selectedBean, instance, cc)); } return instance; } return null; } private Object invoke(DelegateQueryHandler delegate, CdiQueryInvocationContext context) { try { Method extract = ClassUtils.extractPossiblyGenericMethod(delegate.getClass(), context.getMethod()); return extract.invoke(delegate, context.getMethodParameters()); } catch (InvocationTargetException e) { if (e.getCause() != null && e.getCause() instanceof PersistenceException) { throw (PersistenceException) e.getCause(); } throw new QueryInvocationException(e, context); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodExpressionException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; public class MethodExpressionException extends RuntimeException { private static final long serialVersionUID = 1L; private final String property; private final Class repoClass; private final String method; public MethodExpressionException(Class repoClass, String method) { this(null, repoClass, method); } public MethodExpressionException(String property, Class repoClass, String method) { this.property = property; this.repoClass = repoClass; this.method = method; } @Override public String getMessage() { if (property != null) { return "Invalid property '" + property + "' in method expression " + repoClass.getName() + "." + method; } return "Method '" + method + "'of Repository " + repoClass.getName() + " is not a method expression"; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/MethodQueryBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.builder.part.QueryRoot; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.param.Parameters; @ApplicationScoped public class MethodQueryBuilder extends QueryBuilder { @Override public Object execute(CdiQueryInvocationContext context) { Query jpaQuery = createJpaQuery(context); return context.executeQuery(jpaQuery); } private Query createJpaQuery(CdiQueryInvocationContext context) { Parameters params = context.getParams(); QueryRoot root = context.getRepositoryMethodMetadata().getQueryRoot(); String jpqlQuery = context.applyQueryStringPostProcessors(root.getJpqlQuery()); context.setQueryString(jpqlQuery); params.updateValues(root.getParameterUpdates()); Query result = params.applyTo(context.getEntityManager().createQuery(jpqlQuery)); return context.applyRestrictions(result); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/OrderDirection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; public enum OrderDirection { ASC { @Override public OrderDirection change() { return DESC; } }, DESC { @Override public OrderDirection change() { return ASC; } }; public abstract OrderDirection change(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/QueryBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import jakarta.persistence.Query; import java.text.MessageFormat; import java.util.List; /** * Query builder factory. Delegates to concrete implementations. */ public abstract class QueryBuilder { public static final String QUERY_SELECT = "select e from {0} e"; public static final String QUERY_COUNT = "select count(e) from {0} e"; public static final String QUERY_DELETE = "delete from {0} e"; public static final String ENTITY_NAME = "e"; public static String selectQuery(String entityName) { return MessageFormat.format(QUERY_SELECT, entityName); } public static String deleteQuery(String entityName) { return MessageFormat.format(QUERY_DELETE, entityName); } public static String countQuery(String entityName) { return MessageFormat.format(QUERY_COUNT, entityName); } @SuppressWarnings("unchecked") public Object executeQuery(CdiQueryInvocationContext context) { Object result = execute(context); if (!isUnmappableResult(result) && context.hasQueryInOutMapper()) { QueryInOutMapper mapper = (QueryInOutMapper) context.getQueryInOutMapper(); if (result instanceof List) { return mapper.mapResultList((List) result); } return mapper.mapResult(result); } return result; } protected abstract Object execute(CdiQueryInvocationContext ctx); private boolean isUnmappableResult(Object result) { return result instanceof QueryResult || result instanceof Query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/QueryBuilderContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import java.util.Collections; import java.util.LinkedList; import java.util.List; import org.apache.deltaspike.data.impl.param.ParameterUpdate; public class QueryBuilderContext { private final StringBuilder builder; private final List paramUpdates; private int counter = 1; public QueryBuilderContext() { this.builder = new StringBuilder(); this.paramUpdates = new LinkedList<>(); } public int increment() { return counter++; } public QueryBuilderContext append(String string) { builder.append(string); return this; } public String resultString() { return builder.toString(); } public int getCounter() { return counter; } public void addParameterUpdate(ParameterUpdate update) { paramUpdates.add(update); } public List getParameterUpdates() { return Collections.unmodifiableList(paramUpdates); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/QueryBuilderFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import static org.apache.deltaspike.data.impl.meta.RepositoryMethodType.ANNOTATED; import static org.apache.deltaspike.data.impl.meta.RepositoryMethodType.DELEGATE; import static org.apache.deltaspike.data.impl.meta.RepositoryMethodType.PARSE; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.meta.RepositoryMethodType; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; @ApplicationScoped public class QueryBuilderFactory { @Inject private MethodQueryBuilder methodQueryBuilder; @Inject private DelegateQueryBuilder delegateQueryBuilder; @Inject private AnnotatedQueryBuilder annotatedQueryBuilder; protected QueryBuilder getQueryBuilder(RepositoryMethodType repositoryMethodType) { switch (repositoryMethodType) { case ANNOTATED: return annotatedQueryBuilder; case PARSE: return methodQueryBuilder; case DELEGATE: return delegateQueryBuilder; default: throw new RuntimeException( "No " + QueryBuilder.class.getName() + " avialable for type: " + repositoryMethodType); } } public QueryBuilder build(RepositoryMethodMetadata methodMetadata, CdiQueryInvocationContext context) { QueryBuilder builder = getQueryBuilder(context.getRepositoryMethodMetadata().getMethodType()); if (QueryResult.class.equals(methodMetadata.getMethod().getReturnType())) { return new WrappedQueryBuilder(builder); } return builder; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/QueryOperator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; /** * Comparison options for queries. */ public enum QueryOperator { LessThan("LessThan", "{0} < {1}"), LessThanEquals("LessThanEquals", "{0} <= {1}"), GreaterThan("GreaterThan", "{0} > {1}"), GreaterThanEquals("GreaterThanEquals", "{0} >= {1}"), NotLike("NotLike", "{0} not like {1}"), Like("Like", "{0} like {1}"), LikeIgnoreCase("LikeIgnoreCase", "upper({0}) like {1}", true), NotEqual("NotEqual", "{0} <> {1}"), NotEqualIgnoreCase("NotEqualIgnoreCase", "upper({0}) <> upper({1})"), Equal("Equal", "{0} = {1}"), EqualIgnoreCase("EqualIgnoreCase", "upper({0}) = upper({1})"), IgnoreCase("IgnoreCase", "upper({0}) = upper({1})"), Between("Between", "{0} between {1} and {2}", 2), IsNotNull("IsNotNull", "{0} IS NOT NULL", 0), IsNull("IsNull", "{0} IS NULL", 0), NotIn("NotIn", "{0} NOT IN {1}"), In("In", "{0} IN {1}"), True("True", "{0} IS TRUE", 0), False("False", "{0} IS FALSE", 0), Containing("Containing", "{0} like CONCAT(''%'', CONCAT({1}, ''%''))"), StartingWith("StartingWith", "{0} like CONCAT({1}, ''%'')"), EndingWith("EndingWith", "{0} like CONCAT(''%'', {1})"); private final String expression; private final String jpql; private final int paramNum; private final boolean caseInsensitive; private QueryOperator(String expression, String jpql) { this(expression, jpql, 1); } private QueryOperator(String expression, String jpql, boolean caseInsensitive) { this(expression, jpql, 1, caseInsensitive); } private QueryOperator(String expression, String jpql, int paramNum) { this(expression, jpql, paramNum, false); } private QueryOperator(String expression, String jpql, int paramNum, boolean caseInsensitive) { this.expression = expression; this.jpql = jpql; this.paramNum = paramNum; this.caseInsensitive = caseInsensitive; } public String getExpression() { return expression; } public String getJpql() { return jpql; } public int getParamNum() { return paramNum; } public boolean isCaseInsensitive() { return caseInsensitive; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/WrappedQueryBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder; import org.apache.deltaspike.data.impl.builder.result.DefaultQueryResult; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; public class WrappedQueryBuilder extends QueryBuilder { private final QueryBuilder delegate; public WrappedQueryBuilder(QueryBuilder delegate) { this.delegate = delegate; } @Override @SuppressWarnings("rawtypes") public Object execute(CdiQueryInvocationContext ctx) { return new DefaultQueryResult(delegate, ctx); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/AndQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; class AndQueryPart extends ConnectingQueryPart { public AndQueryPart(boolean first) { super(first); } @Override protected QueryPart build(String queryPart, String method, RepositoryMetadata repo) { children.add(new PropertyQueryPart().build(queryPart, method, repo)); return this; } @Override protected QueryPart buildQuery(QueryBuilderContext ctx) { if (!first) { ctx.append(" and "); } buildQueryForChildren(ctx); return this; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/BasePropertyQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import org.apache.deltaspike.data.impl.builder.MethodExpressionException; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.property.query.NamedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyQueries; import org.apache.deltaspike.data.impl.property.query.PropertyQuery; abstract class BasePropertyQueryPart extends QueryPart { static final String SEPARATOR = "_"; void validate(String name, String method, RepositoryMetadata repo) { Class current = repo.getEntityMetadata().getEntityClass(); if (name == null) { throw new MethodExpressionException(null, repo.getRepositoryClass(), method); } for (String property : name.split(SEPARATOR)) { PropertyQuery query = PropertyQueries.createQuery(current) .addCriteria(new NamedPropertyCriteria(property)); Property result = query.getFirstResult(); if (result == null) { throw new MethodExpressionException(property, repo.getRepositoryClass(), method); } current = result.getJavaClass(); } } String rewriteSeparator(String name) { if (name.contains("_")) { return name.replaceAll(SEPARATOR, "."); } return name; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/ConnectingQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; abstract class ConnectingQueryPart extends QueryPart { protected final boolean first; public ConnectingQueryPart(boolean first) { this.first = first; } public boolean isFirst() { return first; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/OrQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import static org.apache.deltaspike.data.impl.util.QueryUtils.splitByKeyword; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; class OrQueryPart extends ConnectingQueryPart { public OrQueryPart(boolean first) { super(first); } @Override protected QueryPart build(String queryPart, String method, RepositoryMetadata repo) { String[] andParts = splitByKeyword(queryPart, "And"); boolean first = true; for (String and : andParts) { AndQueryPart andPart = new AndQueryPart(first); first = false; children.add(andPart.build(and, method, repo)); } return this; } @Override protected QueryPart buildQuery(QueryBuilderContext ctx) { if (!first) { ctx.append(" or "); } buildQueryForChildren(ctx); return this; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/OrderByQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import static org.apache.deltaspike.core.util.StringUtils.isNotEmpty; import static org.apache.deltaspike.data.impl.util.QueryUtils.splitByKeyword; import static org.apache.deltaspike.data.impl.util.QueryUtils.uncapitalize; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.LinkedHashSet; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; public class OrderByQueryPart extends BasePropertyQueryPart { private static final String KEYWORD_ASC = "Asc"; private static final String KEYWORD_DESC = "Desc"; private final List attributes = new LinkedList(); @Override protected QueryPart build(String queryPart, String method, RepositoryMetadata repo) { Set collect = new LinkedHashSet(); List ascSplit = new LinkedList(); split(queryPart, KEYWORD_ASC, ascSplit); for (String ascPart : ascSplit) { split(ascPart, KEYWORD_DESC, collect); } for (String part : collect) { Direction direction = Direction.fromQueryPart(part); String attribute = direction.attribute(part); validate(attribute, method, repo); attributes.add(new OrderByQueryAttribute(attribute, direction)); } return this; } @Override protected QueryPart buildQuery(QueryBuilderContext ctx) { ctx.append(" order by "); for (Iterator it = attributes.iterator(); it.hasNext();) { it.next().buildQuery(ctx); if (it.hasNext()) { ctx.append(", "); } } return this; } private void split(String queryPart, String keyword, Collection result) { for (String part : splitByKeyword(queryPart, keyword)) { String attribute = !part.endsWith(KEYWORD_DESC) && !part.endsWith(KEYWORD_ASC) ? part + keyword : part; result.add(attribute); } } private class OrderByQueryAttribute { private final String attribute; private final Direction direction; public OrderByQueryAttribute(String attribute, Direction direction) { this.attribute = attribute; this.direction = direction; } protected void buildQuery(QueryBuilderContext ctx) { String entityPrefix = QueryBuilder.ENTITY_NAME + "."; ctx.append(entityPrefix).append(rewriteSeparator(attribute)) .append(direction.queryDirection()); } } private static enum Direction { ASC(KEYWORD_ASC), DESC(KEYWORD_DESC), DEFAULT(""); private final String postfix; private Direction(String postfix) { this.postfix = postfix; } public boolean endsWith(String queryPart) { return isNotEmpty(postfix) ? queryPart.endsWith(postfix) : false; } public String attribute(String queryPart) { String attribute = isNotEmpty(postfix) ? queryPart.substring(0, queryPart.indexOf(postfix)) : queryPart; return uncapitalize(attribute); } public String queryDirection() { return isNotEmpty(postfix) ? " " + postfix.toLowerCase() : ""; } public static Direction fromQueryPart(String queryPart) { for (Direction dir : values()) { if (dir.endsWith(queryPart)) { return dir; } } return DEFAULT; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/PropertyQueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import static org.apache.deltaspike.data.impl.util.QueryUtils.uncapitalize; import java.text.MessageFormat; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.builder.QueryOperator; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.param.ToUpperStringParameterUpdate; class PropertyQueryPart extends BasePropertyQueryPart { private String name; private QueryOperator comparator; @Override protected QueryPart build(String queryPart, String method, RepositoryMetadata repo) { comparator = QueryOperator.Equal; name = uncapitalize(queryPart); for (QueryOperator comp : QueryOperator.values()) { if (queryPart.endsWith(comp.getExpression())) { comparator = comp; name = uncapitalize(queryPart.substring(0, queryPart.indexOf(comp.getExpression()))); break; } } validate(name, method, repo); name = rewriteSeparator(name); return this; } @Override protected QueryPart buildQuery(QueryBuilderContext ctx) { String[] args = new String[comparator.getParamNum() + 1]; args[0] = QueryBuilder.ENTITY_NAME + "." + name; for (int i = 1; i < args.length; i++) { args[i] = "?" + ctx.increment(); } ctx.append(MessageFormat.format(comparator.getJpql(), (Object[]) args)); if (comparator.isCaseInsensitive() && args.length >= 1) { ctx.addParameterUpdate(new ToUpperStringParameterUpdate(args[1].substring(1))); } return this; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryPart.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; public abstract class QueryPart { protected List children = new LinkedList(); protected abstract QueryPart build(String queryPart, String method, RepositoryMetadata repo); protected abstract QueryPart buildQuery(QueryBuilderContext ctx); protected void buildQueryForChildren(QueryBuilderContext ctx) { for (QueryPart child : children) { child.buildQuery(ctx); } } protected boolean hasChildren(Set> excluded) { if (children == null || children.isEmpty()) { return false; } for (QueryPart part : children) { if (!excluded.contains(part.getClass())) { return true; } } return false; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/part/QueryRoot.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import static org.apache.deltaspike.data.impl.util.QueryUtils.splitByKeyword; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.deltaspike.data.impl.builder.MethodExpressionException; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.builder.QueryBuilderContext; import org.apache.deltaspike.data.impl.meta.RepositoryMethodPrefix; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.param.ParameterUpdate; /** * Root of the query tree. Also the only exposed class in the package. */ public class QueryRoot extends QueryPart { public static final QueryRoot UNKNOWN_ROOT = new QueryRoot("null-object", new RepositoryMethodPrefix("", null)); private static final Logger log = Logger.getLogger(QueryRoot.class.getName()); private final String entityName; private final RepositoryMethodPrefix methodPrefix; private String jpqlQuery; private List paramUpdates; protected QueryRoot(String entityName, RepositoryMethodPrefix methodPrefix) { this.entityName = entityName; this.methodPrefix = methodPrefix; } public static QueryRoot create(String method, RepositoryMetadata repo, RepositoryMethodPrefix prefix) { QueryRoot root = new QueryRoot(repo.getEntityMetadata().getEntityName(), prefix); root.build(method, method, repo); root.createJpql(); return root; } public String getJpqlQuery() { return jpqlQuery; } public List getParameterUpdates() { return paramUpdates; } @Override protected QueryPart build(String queryPart, String method, RepositoryMetadata repo) { String[] orderByParts = splitByKeyword(queryPart, "OrderBy"); if (hasQueryConditions(orderByParts)) { String[] orParts = splitByKeyword(removePrefix(orderByParts[0]), "Or"); boolean first = true; for (String or : orParts) { OrQueryPart orPart = new OrQueryPart(first); first = false; children.add(orPart.build(or, method, repo)); } } if (orderByParts.length > 1) { OrderByQueryPart orderByPart = new OrderByQueryPart(); children.add(orderByPart.build(orderByParts[1], method, repo)); } if (children.isEmpty()) { throw new MethodExpressionException(repo.getRepositoryClass(), method); } return this; } @Override protected QueryPart buildQuery(QueryBuilderContext ctx) { if (methodPrefix.isDelete()) { ctx.append(QueryBuilder.deleteQuery(entityName)); } else if (methodPrefix.isCount()) { ctx.append(QueryBuilder.countQuery(entityName)); } else { ctx.append(QueryBuilder.selectQuery(entityName)); } if (hasChildren(excludedForWhereCheck())) { ctx.append(" where "); } buildQueryForChildren(ctx); return this; } protected String createJpql() { QueryBuilderContext ctx = new QueryBuilderContext(); buildQuery(ctx); jpqlQuery = ctx.resultString(); paramUpdates = ctx.getParameterUpdates(); log.log(Level.FINER, "createJpql: Query is {0}", jpqlQuery); return jpqlQuery; } private Set> excludedForWhereCheck() { Set> excluded = new HashSet>(); excluded.add(OrderByQueryPart.class); return excluded; } private boolean hasQueryConditions(String[] orderByParts) { String orderByPart = orderByParts[0]; String prefix = methodPrefix.getPrefix(); return !prefix.equals(orderByPart) && !orderByPart.matches(prefix); } private String removePrefix(String queryPart) { return methodPrefix.removePrefix(queryPart); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/CountQueryPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import static org.apache.deltaspike.core.util.StringUtils.isNotEmpty; import static org.apache.deltaspike.data.impl.util.QueryUtils.nullSafeValue; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; import org.apache.deltaspike.data.impl.param.Parameters; import org.apache.deltaspike.data.impl.util.jpa.QueryStringExtractorFactory; public class CountQueryPostProcessor implements JpaQueryPostProcessor { private static final Logger log = Logger.getLogger(CountQueryPostProcessor.class.getName()); private final QueryStringExtractorFactory factory = new QueryStringExtractorFactory(); @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { String queryString = getQueryString(context, query); QueryExtraction extract = new QueryExtraction(queryString); String count = extract.rewriteToCount(); log.log(Level.FINER, "Rewrote query {0} to {1}", new Object[] { queryString, count }); Query result = context.getEntityManager().createQuery(count); Parameters params = context.getParams(); params.applyTo(result); return result; } private String getQueryString(CdiQueryInvocationContext context, Query query) { if (isNotEmpty(context.getQueryString())) { return context.getQueryString(); } return factory.extract(query); } private static class QueryExtraction { private String select; private String from; private String where; private String entityName; private final String query; public QueryExtraction(String query) { this.query = query; } public String rewriteToCount() { splitQuery(); extractEntityName(); return rewrite(); } private String rewrite() { return new StringBuilder() .append("select count(") .append(nullSafeValue(select, entityName)) .append(") ") .append(from) .append(nullSafeValue(where)) .toString(); } private void extractEntityName() { String[] split = from.split(" "); if (split.length > 1) { entityName = split[split.length - 1]; } else { entityName = "*"; } } private void splitQuery() { String lower = query.toLowerCase(); int selectIndex = lower.indexOf("select"); int fromIndex = lower.indexOf("from"); int whereIndex = lower.indexOf("where"); int orderByIndex = lower.indexOf("order by"); if (selectIndex >= 0) { select = query.substring("select".length(), fromIndex); } if (whereIndex >= 0) { from = query.substring(fromIndex, whereIndex); where = query.substring(whereIndex); if (orderByIndex > 0) { where = where.substring(0, orderByIndex - whereIndex); } } else { from = query.substring(fromIndex); } } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/FirstResultPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; public class FirstResultPostProcessor implements JpaQueryPostProcessor { private final int startPosition; public FirstResultPostProcessor(int startPosition) { this.startPosition = startPosition; } @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { query.setFirstResult(startPosition); return query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/FlushModePostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.FlushModeType; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; public class FlushModePostProcessor implements JpaQueryPostProcessor { private final FlushModeType flushMode; public FlushModePostProcessor(FlushModeType flushMode) { this.flushMode = flushMode; } @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { query.setFlushMode(flushMode); return query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/HintPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; public class HintPostProcessor implements JpaQueryPostProcessor { private final String hintName; private final Object hintValue; public HintPostProcessor(String hintName, Object hintValue) { this.hintName = hintName; this.hintValue = hintValue; } @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { query.setHint(hintName, hintValue); return query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/LockModePostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.LockModeType; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; public class LockModePostProcessor implements JpaQueryPostProcessor { private final LockModeType lockMode; public LockModePostProcessor(LockModeType lockMode) { this.lockMode = lockMode; } @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { query.setLockMode(lockMode); return query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/MaxResultPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.JpaQueryPostProcessor; public class MaxResultPostProcessor implements JpaQueryPostProcessor { private final int max; public MaxResultPostProcessor(int max) { this.max = max; } @Override public Query postProcess(CdiQueryInvocationContext context, Query query) { query.setMaxResults(max); return query; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/postprocessor/OrderByQueryStringPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.postprocessor; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.builder.OrderDirection; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.handler.QueryStringPostProcessor; public class OrderByQueryStringPostProcessor implements QueryStringPostProcessor { private static final String ORDER_BY = " order by "; private final String attribute; private OrderDirection direction; private boolean appendEntityName; public OrderByQueryStringPostProcessor(SingularAttribute attribute, OrderDirection direction, boolean appendEntityName) { this.attribute = attribute.getName(); this.direction = direction; this.appendEntityName = appendEntityName; } public OrderByQueryStringPostProcessor(String attribute, OrderDirection direction, boolean appendEntityName) { this.attribute = attribute; this.direction = direction; this.appendEntityName = appendEntityName; } @Override public String postProcess(String queryString) { StringBuilder builder = new StringBuilder(queryString); if (queryString.contains(ORDER_BY)) { builder.append(","); } else { builder.append(ORDER_BY); } if (appendEntityName) { builder.append(QueryBuilder.ENTITY_NAME) .append("."); } return builder .append(attribute) .append(" ").append(direction) .toString(); } public boolean matches(SingularAttribute attribute) { return matches(attribute.getName()); } public boolean matches(String attribute) { return this.attribute.equals(attribute); } public void changeDirection() { direction = direction.change(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/DefaultQueryResult.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.result; import java.util.Iterator; import java.util.List; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.NoResultException; import jakarta.persistence.Query; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.impl.builder.OrderDirection; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.builder.postprocessor.CountQueryPostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.FirstResultPostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.FlushModePostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.HintPostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.LockModePostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.MaxResultPostProcessor; import org.apache.deltaspike.data.impl.builder.postprocessor.OrderByQueryStringPostProcessor; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.QueryStringPostProcessor; public class DefaultQueryResult implements QueryResult { private final QueryBuilder builder; private final CdiQueryInvocationContext context; private int page = 0; private int pageSize = 10; public DefaultQueryResult(QueryBuilder builder, CdiQueryInvocationContext context) { this.builder = builder; this.context = context; } @Override public QueryResult orderAsc(SingularAttribute attribute) { return orderAsc(attribute, true); } @Override public QueryResult orderAsc(SingularAttribute attribute, boolean appendEntityName) { context.addQueryStringPostProcessor(new OrderByQueryStringPostProcessor(attribute, OrderDirection.ASC, appendEntityName)); return this; } @Override public QueryResult orderAsc(String attribute) { return orderAsc(attribute, true); } @Override public QueryResult orderAsc(String attribute, boolean appendEntityName) { context.addQueryStringPostProcessor(new OrderByQueryStringPostProcessor(attribute, OrderDirection.ASC, appendEntityName)); return this; } @Override public QueryResult orderDesc(SingularAttribute attribute) { return orderDesc(attribute, true); } @Override public QueryResult orderDesc(SingularAttribute attribute, boolean appendEntityName) { context.addQueryStringPostProcessor(new OrderByQueryStringPostProcessor(attribute, OrderDirection.DESC, appendEntityName)); return this; } @Override public QueryResult orderDesc(String attribute) { return orderDesc(attribute, true); } @Override public QueryResult orderDesc(String attribute, boolean appendEntityName) { context.addQueryStringPostProcessor(new OrderByQueryStringPostProcessor(attribute, OrderDirection.DESC, appendEntityName)); return this; } @Override public QueryResult changeOrder(final SingularAttribute attribute) { changeOrder(new ChangeOrder() { @Override public boolean matches(OrderByQueryStringPostProcessor orderBy) { return orderBy.matches(attribute); } @Override public void addDefault() { orderAsc(attribute); } }); return this; } @Override public QueryResult changeOrder(final String attribute) { changeOrder(new ChangeOrder() { @Override public boolean matches(OrderByQueryStringPostProcessor orderBy) { return orderBy.matches(attribute); } @Override public void addDefault() { orderAsc(attribute); } }); return this; } @Override public QueryResult clearOrder() { for (Iterator it = context.getQueryStringPostProcessors().iterator(); it.hasNext();) { if (it.next() instanceof OrderByQueryStringPostProcessor) { it.remove(); } } return this; } @Override public QueryResult maxResults(int max) { context.addJpaQueryPostProcessor(new MaxResultPostProcessor(max)); pageSize = max; return this; } @Override public QueryResult firstResult(int first) { context.addJpaQueryPostProcessor(new FirstResultPostProcessor(first)); return this; } @Override public QueryResult lockMode(LockModeType lockMode) { context.addJpaQueryPostProcessor(new LockModePostProcessor(lockMode)); return this; } @Override public QueryResult flushMode(FlushModeType flushMode) { context.addJpaQueryPostProcessor(new FlushModePostProcessor(flushMode)); return this; } @Override public QueryResult hint(String hint, Object value) { context.addJpaQueryPostProcessor(new HintPostProcessor(hint, value)); return this; } @Override @SuppressWarnings("unchecked") public List getResultList() { return ((Query) builder.executeQuery(context)).getResultList(); } @Override @SuppressWarnings("unchecked") public T getSingleResult() { return (T) ((Query) builder.executeQuery(context)).getSingleResult(); } @Override public T getOptionalResult() { try { return getSingleResult(); } catch (NoResultException e) { return null; } } @Override public T getAnyResult() { List queryResult = getResultList(); return !queryResult.isEmpty() ? queryResult.get(0) : null; } @Override public long count() { CountQueryPostProcessor counter = new CountQueryPostProcessor(); context.addJpaQueryPostProcessor(counter); try { Long result = (Long) ((Query) builder.executeQuery(context)).getSingleResult(); return result.intValue(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } finally { context.removeJpaQueryPostProcessor(counter); } } @Override public QueryResult withPageSize(int pageSize) { return maxResults(pageSize); } @Override public QueryResult toPage(int page) { this.page = page; return firstResult(pageSize * page); } @Override public QueryResult nextPage() { page = page + 1; return firstResult(pageSize * page); } @Override public QueryResult previousPage() { page = page > 0 ? page - 1 : page; return firstResult(pageSize * page); } @Override public int countPages() { return (int) Math.ceil((double) count() / pageSize); } @Override public int currentPage() { return page; } @Override public int pageSize() { return pageSize; } private QueryResult changeOrder(ChangeOrder changeOrder) { for (QueryStringPostProcessor processor : context.getQueryStringPostProcessors()) { if (processor instanceof OrderByQueryStringPostProcessor) { OrderByQueryStringPostProcessor orderBy = (OrderByQueryStringPostProcessor) processor; if (changeOrder.matches(orderBy)) { orderBy.changeDirection(); return this; } } } changeOrder.addDefault(); return this; } private abstract static class ChangeOrder { public abstract boolean matches(OrderByQueryStringPostProcessor orderBy); public abstract void addDefault(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.result; import jakarta.persistence.Query; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; public interface QueryProcessor { Object executeQuery(Query query, CdiQueryInvocationContext context); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/builder/result/QueryProcessorFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.result; import java.lang.reflect.Method; import java.util.List; import java.util.Optional; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.NoResultException; import jakarta.persistence.Query; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.QueryInvocationException; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.api.SingleResultType; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; @ApplicationScoped public class QueryProcessorFactory { private NoOpQueryProcessor noOp; private ListResultQueryProcessor listResult; private StreamResultQueryProcessor streamResult; private ExecuteUpdateQueryProcessor executeUpdate; private SingleResultQueryProcessor singleResult; @PostConstruct public void init() { noOp = new NoOpQueryProcessor(); listResult = new ListResultQueryProcessor(); streamResult = new StreamResultQueryProcessor(); executeUpdate = new ExecuteUpdateQueryProcessor(); singleResult = new SingleResultQueryProcessor(); } public QueryProcessor build(RepositoryMethodMetadata methodMetadata) { if (ClassUtils.returns(methodMetadata.getMethod(), QueryResult.class)) { return noOp; } if (ClassUtils.returns(methodMetadata.getMethod(), List.class)) { return listResult; } if (methodMetadata.isReturnsStream()) { return streamResult; } if (isModifying(methodMetadata)) { return executeUpdate; } return singleResult; } private boolean isModifying(RepositoryMethodMetadata methodMetadata) { boolean matchesType = Void.TYPE.equals(methodMetadata.getMethod().getReturnType()) || int.class.equals(methodMetadata.getMethod().getReturnType()) || Integer.class.equals(methodMetadata.getMethod().getReturnType()); return (methodMetadata.getMethod().isAnnotationPresent(Modifying.class) && matchesType) || methodMetadata.getMethodPrefix().isDelete(); } private static final class ListResultQueryProcessor implements QueryProcessor { @Override public Object executeQuery(Query query, CdiQueryInvocationContext context) { return query.getResultList(); } } private static final class NoOpQueryProcessor implements QueryProcessor { @Override public Object executeQuery(Query query, CdiQueryInvocationContext context) { return query; } } private static final class StreamResultQueryProcessor implements QueryProcessor { // will be cached per @ApplicationScoped private boolean initialized; private Method getResultStreamMethod; @Override public Object executeQuery(Query query, CdiQueryInvocationContext context) { if (initialized == false) { initialized = true; try { // take the query.getClass() instead of Query.class // as the users might use JPA 2.2 API but still a JPA 2.0 impl (could happen in TomEE soon) getResultStreamMethod = query.getClass().getMethod("getResultStream"); } catch (Exception e) { // ignore } } if (getResultStreamMethod != null) { try { // delegate to JPA 2.2, which is probably optimized and fetches the data lazy return getResultStreamMethod.invoke(query); } catch (Exception e) { throw new QueryInvocationException(e, context); } } return query.getResultList().stream(); } } private static final class SingleResultQueryProcessor implements QueryProcessor { @Override public Object executeQuery(Query query, CdiQueryInvocationContext context) { SingleResultType style = context.getRepositoryMethodMetadata().getSingleResultType(); Object result = null; switch (style) { case JPA: return query.getSingleResult(); case OPTIONAL: try { result = query.getSingleResult(); } catch (NoResultException e) { } break; default: @SuppressWarnings("unchecked") List queryResult = query.getResultList(); result = !queryResult.isEmpty() ? queryResult.get(0) : null; } if (context.getRepositoryMethodMetadata().isReturnsOptional()) { return Optional.ofNullable(result); } else { return result; } } } private static final class ExecuteUpdateQueryProcessor implements QueryProcessor { @Override public Object executeQuery(Query query, CdiQueryInvocationContext context) { return query.executeUpdate(); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/QueryCriteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.persistence.EntityManager; import jakarta.persistence.NoResultException; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.From; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.CollectionAttribute; import jakarta.persistence.metamodel.ListAttribute; import jakarta.persistence.metamodel.MapAttribute; import jakarta.persistence.metamodel.PluralAttribute; import jakarta.persistence.metamodel.SetAttribute; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.Criteria; import org.apache.deltaspike.data.api.criteria.QuerySelection; import org.apache.deltaspike.data.impl.builder.OrderDirection; import org.apache.deltaspike.data.impl.criteria.predicate.Between; import org.apache.deltaspike.data.impl.criteria.predicate.Eq; import org.apache.deltaspike.data.impl.criteria.predicate.EqIgnoreCase; import org.apache.deltaspike.data.impl.criteria.predicate.FetchBuilder; import org.apache.deltaspike.data.impl.criteria.predicate.GreaterThan; import org.apache.deltaspike.data.impl.criteria.predicate.GreaterThanOrEqual; import org.apache.deltaspike.data.impl.criteria.predicate.In; import org.apache.deltaspike.data.impl.criteria.predicate.IsEmpty; import org.apache.deltaspike.data.impl.criteria.predicate.IsNotEmpty; import org.apache.deltaspike.data.impl.criteria.predicate.IsNotNull; import org.apache.deltaspike.data.impl.criteria.predicate.IsNull; import org.apache.deltaspike.data.impl.criteria.predicate.JoinBuilder; import org.apache.deltaspike.data.impl.criteria.predicate.LessThan; import org.apache.deltaspike.data.impl.criteria.predicate.LessThanOrEqual; import org.apache.deltaspike.data.impl.criteria.predicate.Like; import org.apache.deltaspike.data.impl.criteria.predicate.NotEq; import org.apache.deltaspike.data.impl.criteria.predicate.NotEqIgnoreCase; import org.apache.deltaspike.data.impl.criteria.predicate.NotLike; import org.apache.deltaspike.data.impl.criteria.predicate.OrBuilder; import org.apache.deltaspike.data.impl.criteria.predicate.PredicateBuilder; import org.apache.deltaspike.data.impl.criteria.processor.OrderBy; import org.apache.deltaspike.data.impl.criteria.processor.QueryProcessor; public class QueryCriteria implements Criteria { private static final Logger log = Logger.getLogger(QueryCriteria.class.getName()); private EntityManager entityManager; private Class entityClass; private Class resultClass; private JoinType joinType; private final boolean ignoreNull = true; private boolean distinct = false; private final OrderBy orderByProcessor = new OrderBy(); private final List> builders = new LinkedList>(); private final List> processors = new LinkedList>(); private final List> selections = new LinkedList>(); public QueryCriteria(Class entityClass, Class resultClass, EntityManager entityManager) { this(entityClass, resultClass, entityManager, null); } public QueryCriteria(Class entityClass, Class resultClass, EntityManager entityManager, JoinType joinType) { this.entityClass = entityClass; this.resultClass = resultClass; this.entityManager = entityManager; this.joinType = joinType; } // -------------------------------------------------------------------- // Public criteria methods // -------------------------------------------------------------------- @Override public List getResultList() { return createQuery().getResultList(); } @Override public R getSingleResult() { return createQuery().getSingleResult(); } @Override public R getOptionalResult() { try { return getSingleResult(); } catch (NoResultException e) { return null; } } @Override public R getAnyResult() { List queryResult = getResultList(); return !queryResult.isEmpty() ? queryResult.get(0) : null; } @Override public TypedQuery createQuery() { try { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery query = createCriteriaQuery(builder); From root = query.from(entityClass); if (selections.size() == 1) { Selection[] selections = prepareSelections(query, builder, root); query.select((Selection) selections[0]); } if (selections.size() > 1) { query.multiselect(prepareSelections(query, builder, root)); } List predicates = predicates(builder, root); query.distinct(distinct); if (!predicates.isEmpty()) { query.where(predicates.toArray(new Predicate[predicates.size()])); } applyProcessors(query, builder, root); return (TypedQuery) entityManager.createQuery(query); } catch (RuntimeException e) { log.log(Level.SEVERE, "Exception while creating JPA query", e); throw e; } } @Override public Criteria or(Criteria... criteria) { return internalOr(criteria); } @Override @SuppressWarnings("unchecked") public Criteria or(Collection> criteria) { return internalOr(criteria.toArray(new Criteria[criteria.size()])); } @Override public Criteria join(SingularAttribute att, Criteria criteria) { add(new JoinBuilder(criteria, joinType, att)); return this; } @Override public Criteria join(ListAttribute att, Criteria criteria) { add(new JoinBuilder(criteria, joinType, att)); return this; } @Override public Criteria join(CollectionAttribute att, Criteria criteria) { add(new JoinBuilder(criteria, joinType, att)); return this; } @Override public Criteria join(SetAttribute att, Criteria criteria) { add(new JoinBuilder(criteria, joinType, att)); return this; } @Override public Criteria join(MapAttribute att, Criteria criteria) { add(new JoinBuilder(criteria, joinType, att)); return this; } @Override public Criteria fetch(SingularAttribute att) { add(new FetchBuilder(att, null)); return this; } @Override public Criteria fetch(SingularAttribute att, JoinType joinType) { add(new FetchBuilder(att, joinType)); return this; } @Override public Criteria fetch(PluralAttribute att) { add(new FetchBuilder(att, null)); return this; } @Override public Criteria fetch(PluralAttribute att, JoinType joinType) { add(new FetchBuilder(att, joinType)); return this; } @Override public

Criteria orderAsc(SingularAttribute att) { addOrderBy(att, OrderDirection.ASC); return this; } @Override public

Criteria orderDesc(SingularAttribute att) { addOrderBy(att, OrderDirection.DESC); return this; } @Override public Criteria distinct() { distinct = true; return this; } @Override public Criteria select(Class resultClass, QuerySelection... selection) { QueryCriteria result = new QueryCriteria(entityClass, resultClass, entityManager, joinType); result.builders.addAll(this.builders); result.distinct = this.distinct; result.processors.addAll(this.processors); result.selections.addAll(Arrays.asList(selection)); return result; } @Override public Criteria select(QuerySelection... selection) { return select(Object[].class, selection); } @Override public List predicates(CriteriaBuilder builder, Path path) { List predicates = new LinkedList(); for (PredicateBuilder pbuilder : builders) { List p = pbuilder.build(builder, path); predicates.addAll(p); } return predicates; } // -------------------------------------------------------------------- // Package criteria methods // -------------------------------------------------------------------- void applyProcessors(CriteriaQuery query, CriteriaBuilder builder, From from) { orderByProcessor.process(query, builder, from); for (QueryProcessor proc : processors) { proc.process(query, builder, from); } } @SuppressWarnings("unchecked") Criteria internalOr(Criteria... others) { List> list = new LinkedList>(); list.addAll(Arrays.asList(others)); add(new OrBuilder(list.toArray(new Criteria[list.size()]))); return this; } // -------------------------------------------------------------------- // Private criteria methods // -------------------------------------------------------------------- private void add(PredicateBuilder pred) { builders.add(pred); } private

void add(PredicateBuilder pred, P value) { if (ignoreNull && value != null) { builders.add(pred); } else if (!ignoreNull) { builders.add(pred); } } private

void addOrderBy(SingularAttribute att, OrderDirection orderDirection) { orderByProcessor.add(att, orderDirection); } private Selection[] prepareSelections(CriteriaQuery query, CriteriaBuilder builder, From root) { List> result = new ArrayList>(selections.size()); for (QuerySelection selection : selections) { result.add(selection.toSelection(query, builder, root)); } return result.toArray(new Selection[] {}); } private CriteriaQuery createCriteriaQuery(CriteriaBuilder builder) { return builder.createQuery(resultClass); } // -------------------------------------------------------------------- // Predicates // -------------------------------------------------------------------- @Override public

Criteria eq(SingularAttribute att, P value) { add(new Eq(att, value), value); return this; } @Override public

Criteria eqIgnoreCase(SingularAttribute att, String value) { add(new EqIgnoreCase(att, value), value); return this; } @Override public

Criteria notEq(SingularAttribute att, P value) { add(new NotEq(att, value), value); return this; } @Override public

Criteria notEqIgnoreCase(SingularAttribute att, String value) { add(new NotEqIgnoreCase(att, value), value); return this; } @Override public

Criteria like(SingularAttribute att, String value) { add(new Like(att, value), value); return this; } @Override public

Criteria likeIgnoreCase(SingularAttribute att, String value) { add(new Like(att, value, true), value); return this; } @Override public

Criteria notLike(SingularAttribute att, String value) { add(new NotLike(att, value), value); return this; } @Override public

Criteria notLikeIgnoreCase(SingularAttribute att, String value) { add(new NotLike(att, value, true), value); return this; } @Override public

> Criteria lt(SingularAttribute att, P value) { add(new LessThan(att, value), value); return this; } @Override public

> Criteria ltOrEq(SingularAttribute att, P value) { add(new LessThanOrEqual(att, value), value); return this; } @Override public

> Criteria gt(SingularAttribute att, P value) { add(new GreaterThan(att, value), value); return this; } @Override public

> Criteria gtOrEq(SingularAttribute att, P value) { add(new GreaterThanOrEqual(att, value), value); return this; } @Override public

> Criteria between(SingularAttribute att, P lower, P upper) { add(new Between(att, lower, upper)); return this; } @Override public

Criteria isNull(SingularAttribute att) { add(new IsNull(att)); return this; } @Override public

Criteria notNull(SingularAttribute att) { add(new IsNotNull(att)); return this; } @Override public

> Criteria empty(SingularAttribute att) { add(new IsEmpty(att)); return this; } @Override public

> Criteria notEmpty(SingularAttribute att) { add(new IsNotEmpty(att)); return this; } @Override public

Criteria in(SingularAttribute att, P... values) { add(new In(att, values), values); return this; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/Between.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class Between> extends SingleValueBuilder { private final V upper; public Between(SingularAttribute att, V lower, V upper) { super(att, lower); this.upper = upper; } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.between(path.get(getAtt()), getValue(), upper)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/Eq.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class Eq extends SingleValueBuilder { public Eq(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.equal(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/EqIgnoreCase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class EqIgnoreCase extends SingleValueBuilder { public EqIgnoreCase(SingularAttribute att, String value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.equal(builder.upper(path.get(getAtt())), getValue().toUpperCase())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/FetchBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Collections; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.From; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.PluralAttribute; import jakarta.persistence.metamodel.SingularAttribute; public class FetchBuilder implements PredicateBuilder

{ private final JoinType joinType; private SingularAttribute singular; private PluralAttribute plural; public FetchBuilder(SingularAttribute singular, JoinType joinType) { this.joinType = joinType; this.singular = singular; } public FetchBuilder(PluralAttribute plural, JoinType joinType) { this.joinType = joinType; this.plural = plural; } @SuppressWarnings("rawtypes") @Override public List build(CriteriaBuilder builder, Path

path) { if (singular != null) { fetchSingular((From) path); } else if (plural != null) { fetchPlural((From) path); } return Collections.emptyList(); } SingularAttribute getSingular() { return singular; } void setSingular(SingularAttribute singular) { this.singular = singular; } PluralAttribute getPlural() { return plural; } void setPlural(PluralAttribute plural) { this.plural = plural; } JoinType getJoinType() { return joinType; } @SuppressWarnings({ "rawtypes", "unchecked" }) private void fetchSingular(From path) { if (joinType == null) { path.fetch(singular); } else { path.fetch(singular, joinType); } } @SuppressWarnings({ "rawtypes", "unchecked" }) private void fetchPlural(From path) { if (joinType == null) { path.fetch(plural); } else { path.fetch(plural, joinType); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/GreaterThan.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class GreaterThan> extends SingleValueBuilder { public GreaterThan(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.greaterThan(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/GreaterThanOrEqual.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class GreaterThanOrEqual> extends SingleValueBuilder { public GreaterThanOrEqual(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.greaterThanOrEqualTo(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/In.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class In implements PredicateBuilder

{ private final SingularAttribute singular; private final V[] values; public In(SingularAttribute singular, V[] values) { this.singular = singular; this.values = Arrays.copyOf(values, values.length); } @Override public List build(CriteriaBuilder builder, Path

path) { Path p = path.get(singular); CriteriaBuilder.In in = builder.in(p); for (V value : values) { if (value != null) { in.value(value); } } return Arrays.asList((Predicate) in); } SingularAttribute getSingular() { return singular; } V[] getValues() { return values; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/IsEmpty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.Collection; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class IsEmpty> extends NoValueBuilder { public IsEmpty(SingularAttribute att) { super(att); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.isEmpty(path.get(getAtt()))); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/IsNotEmpty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.Collection; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class IsNotEmpty> extends NoValueBuilder { public IsNotEmpty(SingularAttribute att) { super(att); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.isNotEmpty(path.get(getAtt()))); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/IsNotNull.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class IsNotNull extends NoValueBuilder { public IsNotNull(SingularAttribute att) { super(att); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.isNotNull(path.get(getAtt()))); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/IsNull.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class IsNull extends NoValueBuilder { public IsNull(SingularAttribute att) { super(att); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.isNull(path.get(getAtt()))); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/JoinBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.From; import jakarta.persistence.criteria.Join; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.CollectionAttribute; import jakarta.persistence.metamodel.ListAttribute; import jakarta.persistence.metamodel.MapAttribute; import jakarta.persistence.metamodel.SetAttribute; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.Criteria; @SuppressWarnings({ "rawtypes", "unchecked" }) public class JoinBuilder implements PredicateBuilder

{ private final Criteria criteria; private final JoinType joinType; private SingularAttribute singular; private ListAttribute list; private CollectionAttribute collection; private SetAttribute set; private MapAttribute map; public JoinBuilder(Criteria criteria, JoinType joinType) { this.criteria = criteria; this.joinType = joinType; } public JoinBuilder(Criteria criteria, JoinType joinType, SingularAttribute singular) { this(criteria, joinType); this.singular = singular; } public JoinBuilder(Criteria criteria, JoinType joinType, ListAttribute list) { this(criteria, joinType); this.list = list; } public JoinBuilder(Criteria criteria, JoinType joinType, CollectionAttribute collection) { this(criteria, joinType); this.collection = collection; } public JoinBuilder(Criteria criteria, JoinType joinType, SetAttribute set) { this(criteria, joinType); this.set = set; } public JoinBuilder(Criteria criteria, JoinType joinType, MapAttribute map) { this(criteria, joinType); this.map = map; } @Override public List build(CriteriaBuilder builder, Path

path) { Join join = null; if (singular != null) { join = joinSingular((From) path); } else if (list != null) { join = joinList((From) path); } else if (collection != null) { join = joinCollection((From) path); } else if (set != null) { join = joinSet((From) path); } else { join = joinMap((From) path); } return criteria.predicates(builder, join); } private Join joinSingular(From path) { if (joinType == null) { return path.join(singular); } return path.join(singular, joinType); } private Join joinList(From path) { if (joinType == null) { return path.join(list); } return path.join(list, joinType); } private Join joinCollection(From path) { if (joinType == null) { return path.join(collection); } return path.join(collection, joinType); } private Join joinSet(From path) { if (joinType == null) { return path.join(set); } return path.join(set, joinType); } private Join joinMap(From path) { if (joinType == null) { return path.join(map); } return path.join(map, joinType); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/LessThan.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class LessThan> extends SingleValueBuilder { public LessThan(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.lessThan(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/LessThanOrEqual.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class LessThanOrEqual> extends SingleValueBuilder { public LessThanOrEqual(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.lessThanOrEqualTo(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/Like.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class Like extends SingleValueBuilder { private final boolean caseInsensitive; public Like(SingularAttribute att, String value) { this(att, value, false); } public Like(SingularAttribute att, String value, boolean caseInsensitive) { super(att, value); this.caseInsensitive = caseInsensitive; } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.like( caseInsensitive ? builder.upper(path.get(getAtt())) : path.get(getAtt()), caseInsensitive ? getValue().toUpperCase() : getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/NoValueBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import jakarta.persistence.metamodel.SingularAttribute; abstract class NoValueBuilder implements PredicateBuilder { private final SingularAttribute att; NoValueBuilder(SingularAttribute att) { this.att = att; } SingularAttribute getAtt() { return att; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/NotEq.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class NotEq extends SingleValueBuilder { public NotEq(SingularAttribute att, V value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.notEqual(path.get(getAtt()), getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/NotEqIgnoreCase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class NotEqIgnoreCase extends SingleValueBuilder { public NotEqIgnoreCase(SingularAttribute att, String value) { super(att, value); } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.notEqual(builder.upper(path.get(getAtt())), getValue().toUpperCase())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/NotLike.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.metamodel.SingularAttribute; public class NotLike extends SingleValueBuilder { private final boolean caseInsensitive; public NotLike(SingularAttribute att, String value) { this(att, value, false); } public NotLike(SingularAttribute att, String value, boolean caseInsensitive) { super(att, value); this.caseInsensitive = caseInsensitive; } @Override public List build(CriteriaBuilder builder, Path path) { return Arrays.asList(builder.notLike( caseInsensitive ? builder.upper(path.get(getAtt())) : path.get(getAtt()), caseInsensitive ? getValue().toUpperCase() : getValue())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/OrBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; import org.apache.deltaspike.data.api.criteria.Criteria; public class OrBuilder

implements PredicateBuilder

{ private final Criteria[] criteria; public OrBuilder(Criteria... criteria) { this.criteria = criteria; } @Override public List build(CriteriaBuilder builder, Path

path) { List and = new ArrayList(criteria.length); for (Criteria c : criteria) { and.add(builder.and( c.predicates(builder, path).toArray(new Predicate[0]))); } return Arrays.asList(builder.or(and.toArray(new Predicate[0]))); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/PredicateBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import java.util.List; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Predicate; public interface PredicateBuilder

{ List build(CriteriaBuilder builder, Path

path); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/predicate/SingleValueBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.predicate; import jakarta.persistence.metamodel.SingularAttribute; abstract class SingleValueBuilder extends NoValueBuilder { private final V value; SingleValueBuilder(SingularAttribute att, V value) { super(att); this.value = value; } V getValue() { return value; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/OrderBy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.processor; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Order; import jakarta.persistence.criteria.Path; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.builder.OrderDirection; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class OrderBy

implements QueryProcessor

{ private final List> orderByDefinitions = new ArrayList>(); public void add(SingularAttribute att, OrderDirection dir) { orderByDefinitions.add(new OrderByDefinition(att, dir)); } @Override public void process(CriteriaQuery query, CriteriaBuilder builder, Path

path) { List orders = new ArrayList(); Iterator> iterator = orderByDefinitions.iterator(); while (iterator.hasNext()) { OrderByDefinition orderByDefinition = iterator.next(); switch (orderByDefinition.getDir()) { case ASC: orders.add(builder.asc(path.get(orderByDefinition.getAtt()))); break; default: orders.add(builder.desc(path.get(orderByDefinition.getAtt()))); } } query.orderBy(orders); } private class OrderByDefinition { private final SingularAttribute att; private final OrderDirection dir; public OrderByDefinition(SingularAttribute att, OrderDirection dir) { this.att = att; this.dir = dir; } public SingularAttribute getAtt() { return att; } public OrderDirection getDir() { return dir; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (getClass() != o.getClass()) { return false; } @SuppressWarnings("unchecked") OrderByDefinition that = (OrderByDefinition) o; if (att != null ? !att.equals(that.att) : that.att != null) { return false; } return dir == that.dir; } @Override public int hashCode() { int result = att != null ? att.hashCode() : 0; result = 31 * result + (dir != null ? dir.hashCode() : 0); return result; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/processor/QueryProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.processor; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; public interface QueryProcessor

{ void process(CriteriaQuery query, CriteriaBuilder builder, Path

path); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/AttributeQuerySelection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; public class AttributeQuerySelection extends SingularAttributeSelection { public AttributeQuerySelection(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return path.get(getAttribute()); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/SingularAttributeSelection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.QuerySelection; public abstract class SingularAttributeSelection implements QuerySelection { protected final SingularAttribute attribute; public SingularAttributeSelection(SingularAttribute attribute) { this.attribute = attribute; } public SingularAttribute getAttribute() { return attribute; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Abs.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Abs extends SingularAttributeSelection { public Abs(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.abs(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Avg.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Avg extends SingularAttributeSelection { public Avg(SingularAttribute attribute) { super(attribute); } @Override @SuppressWarnings("unchecked") public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return (Selection) builder.avg(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Count.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.QuerySelection; public class Count

implements QuerySelection { private final SingularAttribute attribute; public Count(SingularAttribute attribute) { this.attribute = attribute; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.count(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/CountDistinct.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.QuerySelection; public class CountDistinct

implements QuerySelection { private final SingularAttribute attribute; public CountDistinct(SingularAttribute attribute) { this.attribute = attribute; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.countDistinct(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Max.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Max extends SingularAttributeSelection { public Max(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.max(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Min.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Min extends SingularAttributeSelection { public Min(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.min(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Modulo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Modulo

extends SingularAttributeSelection { private final Integer modulo; public Modulo(SingularAttribute attribute, Integer modulo) { super(attribute); this.modulo = modulo; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.mod(path.get(attribute), modulo); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Neg.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Neg extends SingularAttributeSelection { public Neg(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.neg(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/numeric/Sum.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.numeric; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Sum extends SingularAttributeSelection { public Sum(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.sum(path.get(attribute)); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Lower.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.strings; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Lower

extends SingularAttributeSelection { public Lower(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.lower(path.get(getAttribute())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFrom.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.strings; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class SubstringFrom

extends SingularAttributeSelection { private final int from; public SubstringFrom(SingularAttribute attribute, int from) { super(attribute); this.from = from; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.substring(path.get(getAttribute()), from); } int getFrom() { return from; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/SubstringFromTo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.strings; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; public class SubstringFromTo

extends SubstringFrom

{ private final int length; public SubstringFromTo(SingularAttribute attribute, int from, int length) { super(attribute, from); this.length = length; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.substring(path.get(getAttribute()), getFrom(), length); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Trim.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.strings; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; public class Trim

extends SingularAttributeSelection { private final CriteriaBuilder.Trimspec trimspec; public Trim(SingularAttribute attribute) { super(attribute); this.trimspec = CriteriaBuilder.Trimspec.BOTH; } public Trim(CriteriaBuilder.Trimspec trimspec, SingularAttribute attribute) { super(attribute); this.trimspec = trimspec; } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.trim(this.trimspec, path.get(getAttribute())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/strings/Upper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.strings; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.impl.criteria.selection.SingularAttributeSelection; public class Upper

extends SingularAttributeSelection { public Upper(SingularAttribute attribute) { super(attribute); } @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.upper(path.get(getAttribute())); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentDate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.temporal; import java.sql.Date; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import org.apache.deltaspike.data.api.criteria.QuerySelection; public class CurrentDate

implements QuerySelection { @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.currentDate(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/criteria/selection/temporal/CurrentTime.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria.selection.temporal; import java.sql.Time; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Path; import jakarta.persistence.criteria.Selection; import org.apache.deltaspike.data.api.criteria.QuerySelection; public class CurrentTime

implements QuerySelection { @Override public Selection

implements QuerySelection { @Override public Selection toSelection(CriteriaQuery query, CriteriaBuilder builder, Path path) { return builder.currentTimestamp(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.graph; public class EntityGraphException extends RuntimeException { private static final long serialVersionUID = 1L; public EntityGraphException(String message) { super(message); } public EntityGraphException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/graph/EntityGraphHelper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.graph; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import jakarta.persistence.EntityManager; import org.apache.deltaspike.data.api.EntityGraph; /** * Helper for entity graphs. */ public final class EntityGraphHelper { private EntityGraphHelper() { } public static Object getEntityGraph(EntityManager em, Class entityClass, EntityGraph entityGraphAnn) { String graphName = entityGraphAnn.value(); if (graphName.isEmpty()) { return buildEntityGraph(em, entityClass, entityGraphAnn.paths()); } else { return em.getEntityGraph(graphName); } } private static Object createEntityGraph(EntityManager em, Class entityClass) { return em.createEntityGraph(entityClass); } private static Object addSubgraph(Object graph, String attributeName) { if (graph instanceof jakarta.persistence.EntityGraph) { return ((jakarta.persistence.EntityGraph) graph).addSubgraph(attributeName); } else if (graph instanceof jakarta.persistence.Subgraph) { return ((jakarta.persistence.Subgraph) graph).addSubgraph(attributeName); } return null; } private static void addAttributeNodes(Object graph, String attributeName) { if (graph instanceof jakarta.persistence.EntityGraph) { ((jakarta.persistence.EntityGraph) graph).addAttributeNodes( new String[] { attributeName }); } else if (graph instanceof jakarta.persistence.Subgraph) { ((jakarta.persistence.Subgraph) graph).addAttributeNodes( new String[] { attributeName }); } } private static Object buildEntityGraph(EntityManager em, Class entityClass, String[] attributePaths) { Object graph = createEntityGraph(em, entityClass); List paths = new ArrayList<>(Arrays.asList(attributePaths)); // handle longest paths first Collections.sort(paths); Collections.reverse(paths); for (String path : attributePaths) { if (path.contains(".")) { String[] segments = path.split("\\."); Object parent = addSubgraph(graph, segments[0]); for (int i = 1; i < segments.length - 1; i++) { addSubgraph(parent, segments[i]); } addAttributeNodes(parent, segments[segments.length - 1]); } else { addAttributeNodes(graph, path); } } return graph; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/AbstractDelegateQueryHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import org.apache.deltaspike.data.spi.DelegateQueryHandler; public abstract class AbstractDelegateQueryHandler implements DelegateQueryHandler { @Inject protected CdiQueryInvocationContext context; @SuppressWarnings("unchecked") protected Class getEntityClass() { return (Class) context.getEntityClass(); } protected EntityManager getEntityManager() { return context.getEntityManager(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import java.util.Stack; @ApplicationScoped public class CdiQueryContextHolder { private final ThreadLocal> contextStack = new ThreadLocal>(); public void set(CdiQueryInvocationContext context) { if (contextStack.get() == null) { contextStack.set(new Stack()); } contextStack.get().push(context); } @Produces public CdiQueryInvocationContext get() { if (contextStack.get() != null && !contextStack.get().isEmpty()) { return contextStack.get().peek(); } return null; } public void dispose() { if (contextStack.get() != null && !contextStack.get().isEmpty()) { CdiQueryInvocationContext ctx = contextStack.get().pop(); ctx.cleanup(); } if (contextStack.get() != null && contextStack.get().isEmpty()) { contextStack.remove(); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CdiQueryInvocationContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import java.io.Serializable; import java.lang.reflect.Method; import java.util.LinkedList; import java.util.List; import jakarta.persistence.EntityManager; import jakarta.persistence.LockModeType; import jakarta.persistence.Query; import jakarta.persistence.QueryHint; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.data.api.EntityGraph; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.impl.graph.EntityGraphHelper; import org.apache.deltaspike.data.impl.meta.EntityMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; import org.apache.deltaspike.data.impl.param.Parameters; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.util.EntityUtils; import org.apache.deltaspike.data.impl.util.bean.DependentProviderDestroyable; import org.apache.deltaspike.data.impl.util.bean.Destroyable; import org.apache.deltaspike.data.spi.QueryInvocationContext; public class CdiQueryInvocationContext implements QueryInvocationContext { private final EntityManager entityManager; private final Parameters params; private final Object proxy; private final Method method; private final Object[] args; private final RepositoryMetadata repositoryMetadata; private final RepositoryMethodMetadata repositoryMethodMetadata; private final List queryPostProcessors; private final List jpaPostProcessors; private final List cleanup; private String queryString; public CdiQueryInvocationContext(Object proxy, Method method, Object[] args, RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata repositoryMethodMetadata, EntityManager entityManager) { this.proxy = proxy; this.method = method; this.args = args == null ? new Object[]{} : args; this.repositoryMetadata = repositoryMetadata; this.repositoryMethodMetadata = repositoryMethodMetadata; this.entityManager = entityManager; this.params = Parameters.create(method, this.args, repositoryMethodMetadata); this.queryPostProcessors = new LinkedList(); this.jpaPostProcessors = new LinkedList(); this.cleanup = new LinkedList(); } public void init() { if (hasQueryInOutMapper()) { QueryInOutMapper mapper = getQueryInOutMapper(); params.applyMapper(mapper); for (int i = 0; i < args.length; i++) { if (mapper.mapsParameter(args[i])) { args[i] = mapper.mapParameter(args[i]); } } } } @Override public EntityManager getEntityManager() { return entityManager; } @Override public boolean isNew(Object entity) { try { Property versionProperty = repositoryMetadata.getEntityMetadata().getVersionProperty(); if (versionProperty != null) { return versionProperty.getValue(entity) == null; } Property primaryKeyProperty = repositoryMetadata.getEntityMetadata().getPrimaryKeyProperty(); if (EntityUtils.primaryKeyValue(entity, primaryKeyProperty) == null) { return true; } if (!entityManager.contains(entity) && countCheck(entity, primaryKeyProperty)) { return true; } return false; } catch (IllegalArgumentException e) { // Not an entity return false; } } @Override public Class getEntityClass() { return repositoryMetadata.getEntityMetadata().getEntityClass(); } @Override public Class getRepositoryClass() { return repositoryMetadata.getRepositoryClass(); } public Object proceed() throws Exception { return method.invoke(proxy, args); } @Override public Method getMethod() { return method; } public Query applyRestrictions(Query query) { Parameters params = getParams(); Method method = getMethod(); if (params.hasSizeRestriction()) { query.setMaxResults(params.getSizeRestriciton()); } if (params.hasFirstResult()) { query.setFirstResult(params.getFirstResult()); } LockModeType lockMode = extractLockMode(); if (lockMode != null) { query.setLockMode(lockMode); } QueryHint[] hints = extractQueryHints(); if (hints != null) { for (QueryHint hint : hints) { query.setHint(hint.name(), hint.value()); } } applyEntityGraph(query, method); query = applyJpaQueryPostProcessors(query); return query; } public Object[] getMethodParameters() { return args; } public void addQueryStringPostProcessor(QueryStringPostProcessor postProcessor) { queryPostProcessors.add(postProcessor); } public void addJpaQueryPostProcessor(JpaQueryPostProcessor postProcessor) { jpaPostProcessors.add(postProcessor); } public void removeJpaQueryPostProcessor(JpaQueryPostProcessor postProcessor) { jpaPostProcessors.remove(postProcessor); } public boolean hasQueryStringPostProcessors() { return !queryPostProcessors.isEmpty(); } public String applyQueryStringPostProcessors(String queryString) { String result = queryString; for (QueryStringPostProcessor processor : queryPostProcessors) { result = processor.postProcess(result); } return result; } public Query applyJpaQueryPostProcessors(Query query) { Query result = query; for (JpaQueryPostProcessor processor : jpaPostProcessors) { result = processor.postProcess(this, result); } return result; } public void addDestroyable(Destroyable destroyable) { cleanup.add(destroyable); } public void cleanup() { for (Destroyable destroy : cleanup) { destroy.destroy(); } cleanup.clear(); } public Object executeQuery(Query jpaQuery) { return repositoryMethodMetadata.getQueryProcessor().executeQuery(jpaQuery, this); } public Parameters getParams() { return params; } public String getQueryString() { return queryString; } public void setQueryString(String queryString) { this.queryString = queryString; } public List getQueryStringPostProcessors() { return queryPostProcessors; } public boolean hasQueryInOutMapper() { return repositoryMethodMetadata.getQueryInOutMapperClass() != null; } public QueryInOutMapper getQueryInOutMapper() { if (repositoryMethodMetadata.getQueryInOutMapperClass() == null) { return null; } QueryInOutMapper result = null; if (repositoryMethodMetadata.isQueryInOutMapperIsNormalScope()) { result = BeanProvider.getContextualReference(repositoryMethodMetadata.getQueryInOutMapperClass()); } else { DependentProvider> mappedProvider = BeanProvider.getDependent(repositoryMethodMetadata.getQueryInOutMapperClass()); result = mappedProvider.get(); this.addDestroyable(new DependentProviderDestroyable(mappedProvider)); } return result; } public Object getProxy() { return proxy; } private LockModeType extractLockMode() { org.apache.deltaspike.data.api.Query query = getRepositoryMethodMetadata().getQuery(); if (query != null && query.lock() != LockModeType.NONE) { return query.lock(); } return null; } private QueryHint[] extractQueryHints() { org.apache.deltaspike.data.api.Query query = getRepositoryMethodMetadata().getQuery(); if (query != null && query.hints().length > 0) { return query.hints(); } return null; } private void applyEntityGraph(Query query, Method method) { EntityGraph entityGraphAnn = method.getAnnotation(EntityGraph.class); if (entityGraphAnn == null) { return; } Object graph = EntityGraphHelper.getEntityGraph(getEntityManager(), repositoryMetadata.getEntityMetadata().getEntityClass(), entityGraphAnn); query.setHint(entityGraphAnn.type().getHintName(), graph); } private boolean countCheck(Object entity, Property primaryKeyProperty) { StringBuilder jpql = new StringBuilder("SELECT COUNT(e) FROM " + getEntityMetadata() .getEntityName() + " e "); jpql.append("WHERE e."); jpql.append(primaryKeyProperty.getName()); jpql.append(" = :id"); final Query query = entityManager.createQuery(jpql.toString()); query.setParameter("id", EntityUtils.primaryKeyValue(entity, primaryKeyProperty)); final Long result = (Long) query.getSingleResult(); if (Long.valueOf(0).equals(result)) { return true; } return false; } public RepositoryMetadata getRepositoryMetadata() { return repositoryMetadata; } public EntityMetadata getEntityMetadata() { return repositoryMetadata.getEntityMetadata(); } public RepositoryMethodMetadata getRepositoryMethodMetadata() { return repositoryMethodMetadata; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/CriteriaSupportHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import jakarta.enterprise.context.Dependent; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.JoinType; import jakarta.persistence.metamodel.SingularAttribute; import org.apache.deltaspike.data.api.criteria.Criteria; import org.apache.deltaspike.data.api.criteria.CriteriaSupport; import org.apache.deltaspike.data.api.criteria.QuerySelection; import org.apache.deltaspike.data.impl.criteria.QueryCriteria; import org.apache.deltaspike.data.impl.criteria.selection.AttributeQuerySelection; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Abs; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Avg; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Count; import org.apache.deltaspike.data.impl.criteria.selection.numeric.CountDistinct; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Max; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Min; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Modulo; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Neg; import org.apache.deltaspike.data.impl.criteria.selection.numeric.Sum; import org.apache.deltaspike.data.impl.criteria.selection.strings.Lower; import org.apache.deltaspike.data.impl.criteria.selection.strings.SubstringFrom; import org.apache.deltaspike.data.impl.criteria.selection.strings.SubstringFromTo; import org.apache.deltaspike.data.impl.criteria.selection.strings.Trim; import org.apache.deltaspike.data.impl.criteria.selection.strings.Upper; import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentDate; import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentTime; import org.apache.deltaspike.data.impl.criteria.selection.temporal.CurrentTimestamp; @Dependent public class CriteriaSupportHandler extends AbstractDelegateQueryHandler implements CriteriaSupport { @Override public Criteria criteria() { return new QueryCriteria(getEntityClass(), getEntityClass(), getEntityManager()); } @Override public Criteria where(Class clazz) { return new QueryCriteria(clazz, clazz, getEntityManager()); } @Override public Criteria where(Class clazz, JoinType joinType) { return new QueryCriteria(clazz, clazz, getEntityManager(), joinType); } @Override public QuerySelection attribute(SingularAttribute attribute) { return new AttributeQuerySelection(attribute); } // ---------------------------------------------------------------------------- // NUMERIC QUERY SELECTION // ---------------------------------------------------------------------------- @Override public QuerySelection abs(SingularAttribute attribute) { return new Abs(attribute); } @Override public QuerySelection avg(SingularAttribute attribute) { return new Avg(attribute); } @Override public QuerySelection count(SingularAttribute attribute) { return new Count(attribute); } @Override public QuerySelection countDistinct(SingularAttribute attribute) { return new CountDistinct(attribute); } @Override public QuerySelection max(SingularAttribute attribute) { return new Max(attribute); } @Override public QuerySelection min(SingularAttribute attribute) { return new Min(attribute); } @Override public QuerySelection neg(SingularAttribute attribute) { return new Neg(attribute); } @Override public QuerySelection sum(SingularAttribute attribute) { return new Sum(attribute); } @Override public QuerySelection modulo(SingularAttribute attribute, Integer modulo) { return new Modulo(attribute, modulo); } // ---------------------------------------------------------------------------- // STRING QUERY SELECTION // ---------------------------------------------------------------------------- @Override public QuerySelection upper(SingularAttribute attribute) { return new Upper(attribute); } @Override public QuerySelection lower(SingularAttribute attribute) { return new Lower(attribute); } @Override public QuerySelection substring(SingularAttribute attribute, int from) { return new SubstringFrom(attribute, from); } @Override public QuerySelection substring(SingularAttribute attribute, int from, int length) { return new SubstringFromTo(attribute, from, length); } @Override public QuerySelection trim(SingularAttribute attribute) { return new Trim(attribute); } @Override public QuerySelection trim(CriteriaBuilder.Trimspec trimspec, SingularAttribute attribute) { return new Trim(trimspec, attribute); } // ---------------------------------------------------------------------------- // TEMPORAL QUERY SELECTION // ---------------------------------------------------------------------------- @Override public QuerySelection currDate() { return new CurrentDate(); } @Override public QuerySelection currTime() { return new CurrentTime(); } @Override public QuerySelection currTStamp() { return new CurrentTimestamp(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityManagerDelegateHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import java.util.Map; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.metamodel.Metamodel; import org.apache.deltaspike.data.api.EntityManagerDelegate; import org.apache.deltaspike.data.spi.DelegateQueryHandler; import org.apache.deltaspike.data.spi.QueryInvocationContext; @SuppressWarnings("unchecked") @Dependent public class EntityManagerDelegateHandler implements EntityManagerDelegate, DelegateQueryHandler { @Inject private QueryInvocationContext context; @Override public void persist(E entity) { entityManager().persist(entity); } @Override public E merge(E entity) { return entityManager().merge(entity); } @Override public E find(Object primaryKey, Map properties) { return (E) entityManager().find(context.getEntityClass(), primaryKey, properties); } @Override public E find(Object primaryKey, LockModeType lockMode) { return (E) entityManager().find(context.getEntityClass(), primaryKey, lockMode); } @Override public E find(Object primaryKey, LockModeType lockMode, Map properties) { return (E) entityManager().find(context.getEntityClass(), primaryKey, lockMode, properties); } @Override public E getReference(Object primaryKey) { return (E) entityManager().getReference(context.getEntityClass(), primaryKey); } @Override public void setFlushMode(FlushModeType flushMode) { entityManager().setFlushMode(flushMode); } @Override public FlushModeType getFlushMode() { return entityManager().getFlushMode(); } @Override public void lock(Object entity, LockModeType lockMode) { entityManager().lock(entity, lockMode); } @Override public void lock(Object entity, LockModeType lockMode, Map properties) { entityManager().lock(entity, lockMode, properties); } @Override public void refresh(E entity, Map properties) { entityManager().refresh(entity, properties); } @Override public void refresh(E entity, LockModeType lockMode) { entityManager().refresh(entity, lockMode); } @Override public void refresh(E entity, LockModeType lockMode, Map properties) { entityManager().refresh(entity, lockMode, properties); } @Override public void clear() { entityManager().clear(); } @Override public void detach(E entity) { entityManager().detach(entity); } @Override public boolean contains(E entity) { return entityManager().contains(entity); } @Override public LockModeType getLockMode(E entity) { return entityManager().getLockMode(entity); } @Override public void setProperty(String propertyName, Object value) { entityManager().setProperty(propertyName, value); } @Override public Map getProperties() { return entityManager().getProperties(); } @Override public void joinTransaction() { entityManager().joinTransaction(); } @Override public T unwrap(Class cls) { return entityManager().unwrap(cls); } @Override public Object getDelegate() { return entityManager().getDelegate(); } @Override public void close() { entityManager().close(); } @Override public boolean isOpen() { return entityManager().isOpen(); } @Override public EntityTransaction getTransaction() { return entityManager().getTransaction(); } @Override public EntityManagerFactory getEntityManagerFactory() { return entityManager().getEntityManagerFactory(); } @Override public CriteriaBuilder getCriteriaBuilder() { return entityManager().getCriteriaBuilder(); } @Override public Metamodel getMetamodel() { return entityManager().getMetamodel(); } private EntityManager entityManager() { return context.getEntityManager(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.meta.RequiresTransaction; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.property.query.NamedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyQueries; import org.apache.deltaspike.data.impl.util.EntityUtils; import org.apache.deltaspike.data.impl.util.jpa.PersistenceUnitUtilDelegateFactory; import org.apache.deltaspike.data.spi.DelegateQueryHandler; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceUnitUtil; import jakarta.persistence.QueryHint; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.metamodel.SingularAttribute; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; import static org.apache.deltaspike.core.util.ArraysUtils.isEmpty; import static org.apache.deltaspike.data.impl.util.QueryUtils.isString; /** * Implement basic functionality from the {@link EntityRepository}. * * @param Entity type. * @param Primary key type, must be a serializable. */ @Dependent public class EntityRepositoryHandler implements EntityRepository, DelegateQueryHandler { private static final Logger log = Logger.getLogger(EntityRepositoryHandler.class.getName()); @Inject private CdiQueryInvocationContext context; @Override @RequiresTransaction public E save(E entity) { if (context.isNew(entity)) { entityManager().persist(entity); return entity; } return entityManager().merge(entity); } @Override @RequiresTransaction public E saveAndFlush(E entity) { E result = save(entity); flush(); return result; } @Override @RequiresTransaction public E saveAndFlushAndRefresh(E entity) { E result = saveAndFlush(entity); entityManager().refresh(result); return result; } @Override @RequiresTransaction public void refresh(E entity) { entityManager().refresh(entity); } @Override public E findBy(PK primaryKey) { Query query = context.getMethod().getAnnotation(Query.class); if (query != null && query.hints().length > 0) { Map hints = new HashMap(); for (QueryHint hint : query.hints()) { hints.put(hint.name(), hint.value()); } return entityManager().find(entityClass(), primaryKey, hints); } else { return entityManager().find(entityClass(), primaryKey); } } @Override public Optional findOptionalBy(PK primaryKey) { E found = null; try { found = findBy(primaryKey); } catch (Exception e) { } return Optional.ofNullable(found); } @Override public List findBy(E example, SingularAttribute... attributes) { return findBy(example, -1, -1, attributes); } @Override public List findBy(E example, int start, int max, SingularAttribute... attributes) { return executeExampleQuery(example, start, max, false, attributes); } @Override public List findByLike(E example, SingularAttribute... attributes) { return findByLike(example, -1, -1, attributes); } @Override public List findByLike(E example, int start, int max, SingularAttribute... attributes) { return executeExampleQuery(example, start, max, true, attributes); } @SuppressWarnings("unchecked") @Override public List findAll() { return context.applyRestrictions(entityManager().createQuery(allQuery(), entityClass())).getResultList(); } @SuppressWarnings("unchecked") @Override public List findAll(int start, int max) { TypedQuery query = entityManager().createQuery(allQuery(), entityClass()); if (start > 0) { query.setFirstResult(start); } if (max > 0) { query.setMaxResults(max); } return context.applyRestrictions(query).getResultList(); } @Override public Long count() { return (Long) context.applyRestrictions(entityManager().createQuery(countQuery(), Long.class)) .getSingleResult(); } @Override public Long count(E example, SingularAttribute... attributes) { return executeCountQuery(example, false, attributes); } @Override public Long countLike(E example, SingularAttribute... attributes) { return executeCountQuery(example, true, attributes); } @SuppressWarnings("unchecked") @Override public PK getPrimaryKey(E entity) { return (PK) persistenceUnitUtil().getIdentifier(entity); } @Override @RequiresTransaction public void remove(E entity) { entityManager().remove(entity); } @Override @RequiresTransaction public void removeAndFlush(E entity) { entityManager().remove(entity); flush(); } @Override @RequiresTransaction public void attachAndRemove(E entity) { if (!entityManager().contains(entity)) { entity = entityManager().merge(entity); } remove(entity); } @Override @RequiresTransaction public void flush() { entityManager().flush(); } public EntityManager entityManager() { return context.getEntityManager(); } public CriteriaQuery criteriaQuery() { return entityManager().getCriteriaBuilder().createQuery(entityClass()); } public TypedQuery typedQuery(String qlString) { return entityManager().createQuery(qlString, entityClass()); } @SuppressWarnings("unchecked") public Class entityClass() { return (Class) context.getEntityClass(); } public String tableName() { return EntityUtils.tableName(context.getEntityClass(), entityManager()); } public String entityName() { return context.getEntityMetadata().getEntityName(); } // ---------------------------------------------------------------------------- // PRIVATE // ---------------------------------------------------------------------------- private String allQuery() { return QueryBuilder.selectQuery(entityName()); } private String countQuery() { return QueryBuilder.countQuery(entityName()); } private String exampleQuery(String queryBase, List> properties, boolean useLikeOperator) { StringBuilder jpqlQuery = new StringBuilder(queryBase).append(" where "); jpqlQuery.append(prepareWhere(properties, useLikeOperator)); return jpqlQuery.toString(); } private void addParameters(TypedQuery query, E example, List> properties, boolean useLikeOperator) { for (Property property : properties) { property.setAccessible(); query.setParameter(property.getName(), transform(property.getValue(example), useLikeOperator)); } } private Object transform(Object value, final boolean useLikeOperator) { if (value != null && useLikeOperator && isString(value)) { // seems to be an OpenJPA bug: // parameters in querys fail validation, e.g. UPPER(e.name) like UPPER(:name) String result = ((String) value).toUpperCase(); return "%" + result + "%"; } return value; } private String prepareWhere(List> properties, boolean useLikeOperator) { Iterator> iterator = properties.iterator(); StringBuilder result = new StringBuilder(); while (iterator.hasNext()) { Property property = iterator.next(); String name = property.getName(); if (useLikeOperator && property.getJavaClass().getName().equals(String.class.getName())) { result.append("UPPER(e.").append(name).append(") like :").append(name) .append(iterator.hasNext() ? " and " : ""); } else { result.append("e.").append(name).append(" = :").append(name).append(iterator.hasNext() ? " and " : ""); } } return result.toString(); } private List extractPropertyNames(SingularAttribute... attributes) { List result = new ArrayList(attributes.length); for (SingularAttribute attribute : attributes) { result.add(attribute.getName()); } return result; } private List> extractProperties(SingularAttribute... attributes) { List names = extractPropertyNames(attributes); List> properties = PropertyQueries.createQuery(entityClass()) .addCriteria(new NamedPropertyCriteria(names.toArray(new String[]{}))).getResultList(); return properties; } private List executeExampleQuery(E example, int start, int max, boolean useLikeOperator, SingularAttribute... attributes) { // Not sure if this should be the intended behaviour // when we don't get any attributes maybe we should // return a empty list instead of all results if (isEmpty(attributes)) { return findAll(start, max); } List> properties = extractProperties(attributes); String jpqlQuery = exampleQuery(allQuery(), properties, useLikeOperator); log.log(Level.FINER, "findBy|findByLike: Created query {0}", jpqlQuery); TypedQuery query = entityManager().createQuery(jpqlQuery, entityClass()); // set starting position if (start > 0) { query.setFirstResult(start); } // set maximum results if (max > 0) { query.setMaxResults(max); } context.applyRestrictions(query); addParameters(query, example, properties, useLikeOperator); return query.getResultList(); } private Long executeCountQuery(E example, boolean useLikeOperator, SingularAttribute... attributes) { if (isEmpty(attributes)) { return count(); } List> properties = extractProperties(attributes); String jpqlQuery = exampleQuery(countQuery(), properties, useLikeOperator); log.log(Level.FINER, "count: Created query {0}", jpqlQuery); TypedQuery query = entityManager().createQuery(jpqlQuery, Long.class); addParameters(query, example, properties, useLikeOperator); context.applyRestrictions(query); return query.getSingleResult(); } private PersistenceUnitUtil persistenceUnitUtil() { return PersistenceUnitUtilDelegateFactory.get(entityManager()); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/JpaQueryPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import jakarta.persistence.Query; public interface JpaQueryPostProcessor { Query postProcess(CdiQueryInvocationContext context, Query query); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.core.util.interceptor.AbstractInvocationContext; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.data.api.QueryInvocationException; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.builder.QueryBuilderFactory; import org.apache.deltaspike.data.impl.meta.RepositoryMetadataHandler; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerRef; import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerRefLookup; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceException; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; /** * Entry point for query processing. */ @Repository @ApplicationScoped public class QueryHandler implements Serializable, InvocationHandler { private static final Logger log = Logger.getLogger(QueryHandler.class.getName()); @Inject private QueryBuilderFactory queryBuilderFactory; @Inject private RepositoryMetadataHandler metadataHandler; @Inject private CdiQueryContextHolder context; @Inject private EntityManagerRefLookup entityManagerRefLookup; @Inject private QueryRunner runner; @Inject private BeanManager beanManager; @Inject private TransactionStrategy transactionStrategy; @Inject private ActiveEntityManagerHolder activeEntityManagerHolder; @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { List> candidates = ProxyUtils.getProxyAndBaseTypes(proxy.getClass()); final RepositoryMetadata repositoryMetadata = metadataHandler.lookupMetadata(candidates); final RepositoryMethodMetadata repositoryMethodMetadata = metadataHandler.lookupMethodMetadata(repositoryMetadata, method); if (repositoryMethodMetadata.getTransactional() != null) { if (repositoryMethodMetadata.getTransactional().qualifier().length > 1) { throw new IllegalStateException(proxy.getClass().getName() + " uses @" + Transactional.class.getName() + " with multiple qualifiers. That isn't supported with @" + Repository.class.getName()); } Class qualifier = repositoryMethodMetadata.getTransactional().qualifier()[0]; if (!Any.class.equals(qualifier)) { EntityManager entityManager = BeanProvider.getContextualReference( EntityManager.class, false, AnnotationInstanceProvider.of(qualifier)); activeEntityManagerHolder.set(entityManager); } return transactionStrategy.execute( new AbstractInvocationContext<>(proxy, method, args, null) { @Override public Object proceed() throws Exception { try { return process(proxy, method, args, repositoryMetadata, repositoryMethodMetadata); } catch (Throwable t) { throw ExceptionUtils.throwAsRuntimeException(t); } } }); } else { return process(proxy, method, args, repositoryMetadata, repositoryMethodMetadata); } } protected Object process(Object proxy, Method method, Object[] args, RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata repositoryMethodMetadata) throws Throwable { CdiQueryInvocationContext queryContext = null; EntityManagerRef entityManagerRef = null; try { entityManagerRef = entityManagerRefLookup.lookupReference(repositoryMetadata); EntityManager entityManager = entityManagerRef.getEntityManager(); if (entityManager == null) { throw new IllegalStateException("Unable to look up EntityManager"); } queryContext = createContext(proxy, method, args, entityManager, repositoryMetadata, repositoryMethodMetadata); QueryBuilder builder = queryBuilderFactory.build(repositoryMethodMetadata, queryContext); Object result = runner.executeQuery(builder, queryContext); return result; } catch (PersistenceException e) { throw e; } catch (Exception e) { log.log(Level.FINEST, "Query execution error", e); if (queryContext != null) { throw new QueryInvocationException(e, queryContext); } throw new QueryInvocationException(e, proxy.getClass(), method); } finally { if (entityManagerRef != null) { entityManagerRef.release(); } context.dispose(); } } private CdiQueryInvocationContext createContext(Object proxy, Method method, Object[] args, EntityManager entityManager, RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata repositoryMethodMetadata) { CdiQueryInvocationContext queryContext = new CdiQueryInvocationContext(proxy, method, args, repositoryMetadata, repositoryMethodMetadata, entityManager); context.set(queryContext); queryContext.init(); return queryContext; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryRunner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import org.apache.deltaspike.data.impl.builder.QueryBuilder; public interface QueryRunner { Object executeQuery(QueryBuilder builder, CdiQueryInvocationContext context) throws Throwable; } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/handler/QueryStringPostProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; public interface QueryStringPostProcessor { String postProcess(String queryString); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/EntityMetadata.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import java.io.Serializable; import org.apache.deltaspike.data.impl.property.Property; public class EntityMetadata { private Class entityClass; private Property primaryKeyProperty; private Class primaryKeyClass; private Property versionProperty; private String entityName; public EntityMetadata(Class entityClass) { this.entityClass = entityClass; } public EntityMetadata(Class entityClass, Class primaryKeyClass) { this.entityClass = entityClass; this.primaryKeyClass = primaryKeyClass; } public EntityMetadata(Class entityClass, String entityName, Class primaryKeyClass) { this.entityClass = entityClass; this.entityName = entityName; this.primaryKeyClass = primaryKeyClass; } public Class getEntityClass() { return entityClass; } public void setEntityClass(Class entityClass) { this.entityClass = entityClass; } public Class getPrimaryKeyClass() { return primaryKeyClass; } public void setPrimaryKeyClass(Class primaryKeyClass) { this.primaryKeyClass = primaryKeyClass; } public Property getPrimaryKeyProperty() { return primaryKeyProperty; } public void setPrimaryKeyProperty(Property primaryKeyProperty) { this.primaryKeyProperty = primaryKeyProperty; } public Property getVersionProperty() { return versionProperty; } public void setVersionProperty(Property versionProperty) { this.versionProperty = versionProperty; } public String getEntityName() { return entityName; } public void setEntityName(String entityName) { this.entityName = entityName; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/EntityMetadataInitializer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.impl.util.EntityUtils; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.logging.Level; import java.util.logging.Logger; @ApplicationScoped public class EntityMetadataInitializer { private static final Logger LOG = Logger.getLogger(EntityMetadataInitializer.class.getName()); public EntityMetadata init(RepositoryMetadata metadata) { try { EntityMetadata entityMetadata = extract(metadata.getRepositoryClass()); if (entityMetadata == null) { return null; } entityMetadata.setPrimaryKeyProperty(EntityUtils.primaryKeyProperty(entityMetadata.getEntityClass())); entityMetadata.setVersionProperty(EntityUtils.getVersionProperty(entityMetadata.getEntityClass())); entityMetadata.setEntityName(EntityUtils.entityName(entityMetadata.getEntityClass())); return entityMetadata; } catch (Exception e) { throw new RuntimeException("Could not initialize repository metadata for: " + metadata.getRepositoryClass(), e); } } private EntityMetadata extract(Class repositoryClass) { // get from annotation Repository repository = repositoryClass.getAnnotation(Repository.class); if (repository == null) { return null; } Class entityClass = repository.forEntity(); boolean isEntityClass = !Object.class.equals(entityClass) && EntityUtils.isEntityClass(entityClass); if (isEntityClass) { return new EntityMetadata(entityClass, EntityUtils.primaryKeyClass(entityClass)); } // get from type for (Type inf : repositoryClass.getGenericInterfaces()) { EntityMetadata result = extractFromType(inf); if (result != null) { return result; } } EntityMetadata entityMetadata = extractFromType(repositoryClass.getGenericSuperclass()); if (entityMetadata != null) { return entityMetadata; } for (Type intf : repositoryClass.getGenericInterfaces()) { if (intf instanceof Class) { entityMetadata = extract((Class) intf); if (entityMetadata != null) { return entityMetadata; } } } if (repositoryClass.getSuperclass() != null) { return extract(repositoryClass.getSuperclass()); } return null; } private EntityMetadata extractFromType(Type type) { LOG.log(Level.FINER, "extractFrom: type = {0}", type); if (!(type instanceof ParameterizedType)) { return null; } ParameterizedType parametrizedType = (ParameterizedType) type; Type[] genericTypes = parametrizedType.getActualTypeArguments(); EntityMetadata result = null; // don't use a foreach here, we must be sure that the we first get the entity type for (Type genericType : genericTypes) { if (genericType instanceof Class && EntityUtils.isEntityClass((Class) genericType)) { result = new EntityMetadata((Class) genericType); continue; } if (result != null && genericType instanceof Class) { result.setPrimaryKeyClass((Class) genericType); return result; } } return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMetadata.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import java.lang.reflect.Method; import java.util.Map; import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerMetadata; public class RepositoryMetadata extends EntityManagerMetadata { private Class repositoryClass; private EntityMetadata entityMetadata; private Map methodsMetadata; public RepositoryMetadata(Class repositoryClass) { this.repositoryClass = repositoryClass; } public RepositoryMetadata(Class repositoryClass, EntityMetadata entityMetadata) { this.repositoryClass = repositoryClass; this.entityMetadata = entityMetadata; } public Class getRepositoryClass() { return repositoryClass; } public void setRepositoryClass(Class repositoryClass) { this.repositoryClass = repositoryClass; } public EntityMetadata getEntityMetadata() { return entityMetadata; } public void setEntityMetadata(EntityMetadata entityMetadata) { this.entityMetadata = entityMetadata; } public Map getMethodsMetadata() { return methodsMetadata; } public void setMethodsMetadata(Map methodsMetadata) { this.methodsMetadata = methodsMetadata; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMetadataHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import java.lang.reflect.Method; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import org.apache.deltaspike.data.impl.RepositoryExtension; @ApplicationScoped public class RepositoryMetadataHandler { private final Map, RepositoryMetadata> repositoriesMetadata = new ConcurrentHashMap, RepositoryMetadata>(); @Inject private BeanManager beanManager; @Inject private RepositoryExtension extension; @Inject private RepositoryMetadataInitializer metadataInitializer; @PostConstruct public void init() { for (Class repositoryClass : extension.getRepositoryClasses()) { RepositoryMetadata metadata = metadataInitializer.init(repositoryClass, beanManager); // invalid if (metadata != null) { repositoriesMetadata.put(repositoryClass, metadata); } } } /** * Lookup the Repository component meta data from a list of candidate classes. * Depending on the implementation, proxy objects might have been modified so the actual class * does not match the original Repository class. * * @param candidateClasses List of candidates to check. * @return A {@link RepositoryMetadataInitializer}. */ public RepositoryMetadata lookupMetadata(List> candidateClasses) { for (Class repoClass : candidateClasses) { if (repositoriesMetadata.containsKey(repoClass)) { return repositoriesMetadata.get(repoClass); } } throw new RuntimeException("Unknown Repository classes " + candidateClasses); } /** * lookup the {@link RepositoryMethodMetadata} for a specific repository and method. * * @param repositoryMetadata The Repository metadata to lookup the method for. * @param method The method object to get Repository meta data for. * @return A {@link RepositoryMethodMetadata}. */ public RepositoryMethodMetadata lookupMethodMetadata(RepositoryMetadata repositoryMetadata, Method method) { return repositoryMetadata.getMethodsMetadata().get(method); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMetadataInitializer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.persistence.FlushModeType; import org.apache.deltaspike.data.api.EntityManagerConfig; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; import org.apache.deltaspike.jpa.spi.entitymanager.QualifierBackedEntityManagerResolver; @ApplicationScoped public class RepositoryMetadataInitializer { private static final Logger log = Logger.getLogger(RepositoryMetadataInitializer.class.getName()); @Inject private RepositoryMethodMetadataInitializer methodMetadataInitializer; @Inject private EntityMetadataInitializer entityMetadataInitializer; public RepositoryMetadata init(Class repositoryClass, BeanManager beanManager) { RepositoryMetadata repositoryMetadata = new RepositoryMetadata(repositoryClass); // read from looks for JPA Transactional and EntityManagerConfig to determine attributes // if those are set, don't process old annotations if (!repositoryMetadata.readFrom(repositoryClass, beanManager)) { repositoryMetadata.setEntityManagerResolverClass(extractEntityManagerResolver(repositoryClass)); repositoryMetadata.setEntityManagerFlushMode(extractEntityManagerFlushMode(repositoryClass)); if (repositoryMetadata.getEntityManagerResolverClass() != null) { Set> beans = beanManager.getBeans(repositoryMetadata.getEntityManagerResolverClass()); Class scope = beanManager.resolve(beans).getScope(); repositoryMetadata.setEntityManagerResolverIsNormalScope(beanManager.isNormalScope(scope)); } else { EntityManagerResolver resolver; if (repositoryMetadata.getQualifiers() != null) { resolver = new QualifierBackedEntityManagerResolver(beanManager, repositoryMetadata.getQualifiers()); } else { resolver = new QualifierBackedEntityManagerResolver(beanManager, Default.class); } repositoryMetadata.setUnmanagedResolver(resolver); repositoryMetadata.setEntityManagerResolverIsNormalScope(false); } } EntityMetadata entityMetadata = entityMetadataInitializer.init(repositoryMetadata); if (entityMetadata == null) { return null; } repositoryMetadata.setEntityMetadata(entityMetadata); initializeMethodsMetadata(repositoryMetadata, beanManager); return repositoryMetadata; } private void initializeMethodsMetadata(RepositoryMetadata repositoryMetadata, BeanManager beanManager) { repositoryMetadata.setMethodsMetadata(new HashMap()); Set> allImplemented = new HashSet>(); collectClasses(repositoryMetadata.getRepositoryClass(), allImplemented); log.log(Level.FINER, "collectClasses(): Found {0} for {1}", new Object[] { allImplemented, repositoryMetadata.getRepositoryClass() }); for (Class implemented : allImplemented) { Method[] repositoryMethods = implemented.getDeclaredMethods(); for (Method repositoryMethod : repositoryMethods) { RepositoryMethodMetadata methodMetadata = methodMetadataInitializer.init(repositoryMetadata, repositoryMethod, beanManager); repositoryMetadata.getMethodsMetadata().put(repositoryMethod, methodMetadata); } } } private void collectClasses(Class cls, Set> result) { if (cls == null || cls == Object.class) { return; } result.add(cls); for (Class child : cls.getInterfaces()) { collectClasses(child, result); } collectClasses(cls.getSuperclass(), result); } private Class extractEntityManagerResolver(Class clazz) { EntityManagerConfig config = extractEntityManagerConfig(clazz); if (config != null && !EntityManagerResolver.class.equals(config.entityManagerResolver())) { return config.entityManagerResolver(); } return null; } private FlushModeType extractEntityManagerFlushMode(Class clazz) { EntityManagerConfig config = extractEntityManagerConfig(clazz); if (config != null) { return config.flushMode(); } return null; } private EntityManagerConfig extractEntityManagerConfig(Class clazz) { if (clazz.isAnnotationPresent(EntityManagerConfig.class)) { return clazz.getAnnotation(EntityManagerConfig.class); } return null; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethodMetadata.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import java.lang.reflect.Method; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.SingleResultType; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.impl.builder.part.QueryRoot; import org.apache.deltaspike.data.impl.builder.result.QueryProcessor; import org.apache.deltaspike.jpa.api.transaction.Transactional; public class RepositoryMethodMetadata { private Method method; private RepositoryMethodType methodType; private RepositoryMethodPrefix methodPrefix; private Query query; private Modifying modifying; private QueryRoot queryRoot; private QueryProcessor queryProcessor; private Class> queryInOutMapperClass; private boolean queryInOutMapperIsNormalScope; private boolean returnsOptional; private boolean returnsStream; private SingleResultType singleResultType; private boolean requiresTransaction; private Transactional transactional; public RepositoryMethodMetadata() { } public RepositoryMethodMetadata(Method method) { this.method = method; } public Method getMethod() { return method; } public void setMethod(Method method) { this.method = method; } public RepositoryMethodType getMethodType() { return methodType; } public void setMethodType(RepositoryMethodType methodType) { this.methodType = methodType; } public RepositoryMethodPrefix getMethodPrefix() { return methodPrefix; } public void setMethodPrefix(RepositoryMethodPrefix methodPrefix) { this.methodPrefix = methodPrefix; } public QueryRoot getQueryRoot() { return queryRoot; } public void setQueryRoot(QueryRoot queryRoot) { this.queryRoot = queryRoot; } public QueryProcessor getQueryProcessor() { return queryProcessor; } public void setQueryProcessor(QueryProcessor queryProcessor) { this.queryProcessor = queryProcessor; } public Class> getQueryInOutMapperClass() { return queryInOutMapperClass; } public void setQueryInOutMapperClass(Class> queryInOutMapperClass) { this.queryInOutMapperClass = queryInOutMapperClass; } public boolean isQueryInOutMapperIsNormalScope() { return queryInOutMapperIsNormalScope; } public void setQueryInOutMapperIsNormalScope(boolean queryInOutMapperIsNormalScope) { this.queryInOutMapperIsNormalScope = queryInOutMapperIsNormalScope; } public Query getQuery() { return query; } public void setQuery(Query query) { this.query = query; } public Modifying getModifying() { return modifying; } public void setModifying(Modifying modifying) { this.modifying = modifying; } public boolean isReturnsOptional() { return returnsOptional; } public void setReturnsOptional(boolean returnsOptional) { this.returnsOptional = returnsOptional; } public boolean isReturnsStream() { return returnsStream; } public void setReturnsStream(boolean returnsStream) { this.returnsStream = returnsStream; } public SingleResultType getSingleResultType() { return singleResultType; } public void setSingleResultType(SingleResultType singleResultType) { this.singleResultType = singleResultType; } public boolean isRequiresTransaction() { return requiresTransaction; } public void setRequiresTransaction(boolean requiresTransaction) { this.requiresTransaction = requiresTransaction; } public Transactional getTransactional() { return transactional; } public void setTransactional(Transactional transactional) { this.transactional = transactional; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethodMetadataInitializer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import static org.apache.deltaspike.core.util.StringUtils.isNotEmpty; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.persistence.LockModeType; import org.apache.deltaspike.core.util.AnnotationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.SingleResultType; import org.apache.deltaspike.data.api.mapping.MappingConfig; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.impl.builder.MethodExpressionException; import org.apache.deltaspike.data.impl.builder.part.QueryRoot; import org.apache.deltaspike.data.impl.builder.result.QueryProcessorFactory; import org.apache.deltaspike.data.impl.handler.EntityRepositoryHandler; import org.apache.deltaspike.jpa.api.transaction.Transactional; @ApplicationScoped public class RepositoryMethodMetadataInitializer { @Inject private QueryProcessorFactory queryProcessorFactory; public RepositoryMethodMetadata init(RepositoryMetadata repositoryMetadata, Method method, BeanManager beanManager) { RepositoryMethodMetadata repositoryMethodMetadata = new RepositoryMethodMetadata(); repositoryMethodMetadata.setMethod(method); repositoryMethodMetadata.setReturnsOptional(Optional.class.isAssignableFrom(method.getReturnType())); repositoryMethodMetadata.setReturnsStream(Stream.class.isAssignableFrom(method.getReturnType())); repositoryMethodMetadata.setQuery(method.isAnnotationPresent(Query.class) ? method.getAnnotation(Query.class) : null); repositoryMethodMetadata.setModifying(method.isAnnotationPresent(Modifying.class) ? method.getAnnotation(Modifying.class) : null); repositoryMethodMetadata.setTransactional(AnnotationUtils.extractAnnotationFromMethodOrClass( beanManager, method, repositoryMetadata.getRepositoryClass(), Transactional.class)); repositoryMethodMetadata.setMethodPrefix(new RepositoryMethodPrefix( repositoryMetadata.getRepositoryClass().getAnnotation(Repository.class).methodPrefix(), method.getName())); repositoryMethodMetadata.setMethodType( extractMethodType(repositoryMetadata, repositoryMethodMetadata)); repositoryMethodMetadata.setQueryProcessor(queryProcessorFactory.build(repositoryMethodMetadata)); repositoryMethodMetadata.setQueryInOutMapperClass( extractMapper(method, repositoryMetadata)); initQueryRoot(repositoryMetadata, repositoryMethodMetadata); initQueryInOutMapperIsNormalScope(repositoryMethodMetadata, beanManager); initSingleResultType(repositoryMethodMetadata); initRequiresTransaction(repositoryMethodMetadata); return repositoryMethodMetadata; } private RepositoryMethodType extractMethodType(RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata repositoryMethodMetadata) { if (isAnnotated(repositoryMethodMetadata)) { return RepositoryMethodType.ANNOTATED; } if (isMethodExpression(repositoryMetadata, repositoryMethodMetadata)) { return RepositoryMethodType.PARSE; } return RepositoryMethodType.DELEGATE; } private void initQueryRoot(RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata methodMetadata) { if (methodMetadata.getMethodType() == RepositoryMethodType.PARSE) { methodMetadata.setQueryRoot( QueryRoot.create(methodMetadata.getMethod().getName(), repositoryMetadata, methodMetadata.getMethodPrefix())); } else { methodMetadata.setQueryRoot(QueryRoot.UNKNOWN_ROOT); } } private void initQueryInOutMapperIsNormalScope(RepositoryMethodMetadata repositoryMethodMetadata, BeanManager beanManager) { if (repositoryMethodMetadata.getQueryInOutMapperClass() != null) { Set> beans = beanManager.getBeans(repositoryMethodMetadata.getQueryInOutMapperClass()); Class scope = beanManager.resolve(beans).getScope(); repositoryMethodMetadata.setQueryInOutMapperIsNormalScope(beanManager.isNormalScope(scope)); } } private boolean isAnnotated(RepositoryMethodMetadata repositoryMethodMetadata) { if (repositoryMethodMetadata.getQuery() != null) { return isValid(repositoryMethodMetadata.getQuery()); } return false; } private boolean isValid(Query query) { return isNotEmpty(query.value()) || isNotEmpty(query.named()); } private boolean isMethodExpression(RepositoryMetadata repositoryMetadata, RepositoryMethodMetadata repositoryMethodMetadata) { if (!Modifier.isAbstract(repositoryMethodMetadata.getMethod().getModifiers())) { return false; } try { QueryRoot.create(repositoryMethodMetadata.getMethod().getName(), repositoryMetadata, repositoryMethodMetadata.getMethodPrefix()); return true; } catch (MethodExpressionException e) { return false; } } private Class> extractMapper(Method queryMethod, RepositoryMetadata repositoryMetadata) { if (queryMethod.isAnnotationPresent(MappingConfig.class)) { return queryMethod.getAnnotation(MappingConfig.class).value(); } if (repositoryMetadata.getRepositoryClass().isAnnotationPresent(MappingConfig.class)) { return repositoryMetadata.getRepositoryClass().getAnnotation(MappingConfig.class).value(); } return null; } private void initSingleResultType(RepositoryMethodMetadata repositoryMethodMetadata) { SingleResultType singleResultType = repositoryMethodMetadata.getQuery() != null ? repositoryMethodMetadata.getQuery().singleResult() : repositoryMethodMetadata.getMethodPrefix().getSingleResultStyle(); if (repositoryMethodMetadata.isReturnsOptional() && singleResultType == SingleResultType.JPA) { repositoryMethodMetadata.setSingleResultType(SingleResultType.OPTIONAL); } else { repositoryMethodMetadata.setSingleResultType(singleResultType); } } private void initRequiresTransaction(RepositoryMethodMetadata repositoryMethodMetadata) { boolean requiresTransaction = false; if (ClassUtils.containsMethod(EntityRepositoryHandler.class, repositoryMethodMetadata.getMethod())) { Method originalMethod = ClassUtils.extractMethod(EntityRepositoryHandler.class, repositoryMethodMetadata.getMethod()); if (originalMethod.isAnnotationPresent(RequiresTransaction.class)) { requiresTransaction = true; } } Query query = repositoryMethodMetadata.getQuery(); Modifying modifying = repositoryMethodMetadata.getModifying(); if ((query != null && !query.lock().equals(LockModeType.NONE)) || modifying != null) { requiresTransaction = true; } repositoryMethodMetadata.setRequiresTransaction(requiresTransaction); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethodPrefix.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import org.apache.deltaspike.data.api.SingleResultType; import java.util.regex.Matcher; import java.util.regex.Pattern; public class RepositoryMethodPrefix { public static final String DEFAULT_PREFIX = "findBy"; public static final String DEFAULT_OPT_PREFIX = "findOptionalBy"; public static final String DEFAULT_ANY_PREFIX = "findAnyBy"; public static final String DEFAULT_DELETE_PREFIX = "deleteBy"; public static final String DEFAULT_COUNT_PREFIX = "countBy"; public static final String DEFAULT_REMOVE_PREFIX = "removeBy"; private static final String FIND_ALL_PREFIX = "findAll"; private static final String FIND_FIRST_PREFIX = "find(First|Top)(\\d+)(By)*"; private static final String FIND_FIRST_PREFIX_PATTERN = FIND_FIRST_PREFIX + "(.*)"; private static final Pattern DIGIT_PATTERN = Pattern.compile("\\d+"); private final String customPrefix; private final String methodName; private int definedMaxResults = 0; public RepositoryMethodPrefix(String customPrefix, String methodName) { this.customPrefix = customPrefix; this.methodName = methodName; if (this.methodName != null) { this.parseMaxResults(); } } public String removePrefix(String queryPart) { if (hasCustomPrefix() && queryPart.startsWith(customPrefix)) { return queryPart.substring(customPrefix.length()); } KnownQueryPrefix known = KnownQueryPrefix.fromMethodName(queryPart); if (known != null) { return known.removePrefix(queryPart); } return queryPart; } public boolean hasCustomPrefix() { return !"".equals(customPrefix); } public String getCustomPrefix() { return customPrefix; } public String getPrefix() { if (hasCustomPrefix()) { return customPrefix; } KnownQueryPrefix prefix = KnownQueryPrefix.fromMethodName(methodName); if (prefix != null) { return prefix.getPrefix(); } return ""; } public SingleResultType getSingleResultStyle() { KnownQueryPrefix prefix = KnownQueryPrefix.fromMethodName(methodName); if (prefix != null) { return prefix.getStyle(); } return SingleResultType.JPA; } public boolean isDelete() { return this.getPrefix().equalsIgnoreCase(DEFAULT_DELETE_PREFIX) || this.getPrefix().equalsIgnoreCase(DEFAULT_REMOVE_PREFIX); } public boolean isCount() { return this.getPrefix().equalsIgnoreCase(DEFAULT_COUNT_PREFIX); } public int getDefinedMaxResults() { return definedMaxResults; } private void parseMaxResults() { if (this.methodName.matches(FIND_FIRST_PREFIX_PATTERN)) { Matcher matcher = DIGIT_PATTERN.matcher(this.methodName); if (matcher.find()) { this.definedMaxResults = Integer.parseInt(matcher.group()); } } } private enum KnownQueryPrefix { DEFAULT(DEFAULT_PREFIX, SingleResultType.JPA), ALL(FIND_ALL_PREFIX, SingleResultType.JPA), FIND_FIRST(FIND_FIRST_PREFIX, SingleResultType.JPA) { @Override public boolean matches(String name) { return name.matches(FIND_FIRST_PREFIX_PATTERN); } @Override public String removePrefix(String queryPart) { return queryPart.replaceFirst(FIND_FIRST_PREFIX,""); } }, OPTIONAL(DEFAULT_OPT_PREFIX,SingleResultType.OPTIONAL), ANY(DEFAULT_ANY_PREFIX, SingleResultType.ANY), DELETE_DEFAULT(DEFAULT_DELETE_PREFIX, SingleResultType.ANY), REMOVE_DEFAULT(DEFAULT_REMOVE_PREFIX, SingleResultType.ANY), COUNT_DEFAULT(DEFAULT_COUNT_PREFIX, SingleResultType.ANY); private final String prefix; private final SingleResultType singleResultType; KnownQueryPrefix(String prefix, SingleResultType singleResultType) { this.prefix = prefix; this.singleResultType = singleResultType; } public String removePrefix(String queryPart) { return queryPart.substring(prefix.length()); } public String getPrefix() { return prefix; } public SingleResultType getStyle() { return this.singleResultType; } public boolean matches(String name) { return name.startsWith(getPrefix()); } public static KnownQueryPrefix fromMethodName(String name) { for (KnownQueryPrefix mapping : values()) { if (mapping.matches(name)) { return mapping; } } return null; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RepositoryMethodType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; /** * Repository method type. Stands for *
    *
  • Delegated methods - the Repository has a concrete implementation for this or the method is implemented in the * {@link org.apache.deltaspike.data.impl.handler.EntityRepositoryHandler}.
  • *
  • Annotated method - the query is defined via a Query annotation.
  • *
  • The method defines a query expression by its name.
  • *
*/ public enum RepositoryMethodType { DELEGATE, ANNOTATED, PARSE } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/meta/RequiresTransaction.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Target(METHOD) @Retention(RUNTIME) public @interface RequiresTransaction { } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/IndexedParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; import jakarta.persistence.Query; /** * Query parameters which have an index (?1). */ public class IndexedParameter extends Parameter { private final int index; public IndexedParameter(int index, Object value) { super(value); this.index = index; } @Override public void apply(Query query) { query.setParameter(index, queryValue()); } @Override public boolean is(String ident) { try { return Integer.valueOf(ident).intValue() == index; } catch (NumberFormatException e) { return false; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/NamedParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; import jakarta.persistence.Query; /** * Parameters which have a name (:name). */ public class NamedParameter extends Parameter { private final String name; public NamedParameter(String name, Object value) { super(value); this.name = name; } @Override public void apply(Query query) { query.setParameter(name, queryValue()); } @Override public boolean is(String ident) { return ident != null && ident.equals(name); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/Parameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.persistence.Query; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; /** * Base class for parameters. */ public abstract class Parameter { private static final Logger LOG = Logger.getLogger(Parameter.class.getName()); protected Object value; protected Object mappedValue = null; public Parameter(Object value) { this.value = value; } public abstract void apply(Query query); public abstract boolean is(String ident); public void applyMapper(QueryInOutMapper mapper) { if (mapper.mapsParameter(value)) { mappedValue = mapper.mapParameter(value); LOG.log(Level.FINE, "Converting param {0} to {1}", new Object[] { value, mappedValue }); } } public void updateValue(Object newValue) { if (mappedValue != null) { mappedValue = newValue; } else { value = newValue; } } protected Object queryValue() { return mappedValue != null ? mappedValue : value; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/ParameterUpdate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; public interface ParameterUpdate { String forParamWithId(); Object newParamValue(Object current); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/Parameters.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.persistence.Query; import org.apache.deltaspike.data.api.FirstResult; import org.apache.deltaspike.data.api.MaxResults; import org.apache.deltaspike.data.api.QueryParam; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; /** * Convenience class to manage method and query parameters. */ public final class Parameters { private static final Logger LOG = Logger.getLogger(Parameters.class.getName()); private static final int DEFAULT_MAX = 0; private static final int DEFAULT_FIRST = -1; private final List parameterList; private final int max; private final int firstResult; private Parameters(List parameters, int max, int firstResult) { this.parameterList = parameters; this.max = max; this.firstResult = firstResult; } public static Parameters createEmpty() { List empty = Collections.emptyList(); return new Parameters(empty, DEFAULT_MAX, DEFAULT_FIRST); } public static Parameters create(Method method, Object[] parameters, RepositoryMethodMetadata repositoryMethod) { int max = extractSizeRestriction(method, repositoryMethod); int first = DEFAULT_FIRST; List result = new ArrayList(parameters.length); int paramIndex = 1; Annotation[][] annotations = method.getParameterAnnotations(); for (int i = 0; i < parameters.length; i++) { if (isParameter(method.getParameterAnnotations()[i])) { QueryParam qpAnnotation = extractFrom(annotations[i], QueryParam.class); if (qpAnnotation != null) { result.add(new NamedParameter(qpAnnotation.value(), parameters[i])); } else { result.add(new IndexedParameter(paramIndex++, parameters[i])); } } else { max = extractInt(parameters[i], annotations[i], MaxResults.class, max); first = extractInt(parameters[i], annotations[i], FirstResult.class, first); } } return new Parameters(result, max, first); } public void applyMapper(QueryInOutMapper mapper) { for (Parameter param : parameterList) { param.applyMapper(mapper); } } public void updateValues(List updates) { for (ParameterUpdate update : updates) { for (Parameter param : parameterList) { if (param.is(update.forParamWithId())) { param.updateValue(update.newParamValue(param.queryValue())); } } } } public Query applyTo(Query query) { for (Parameter param : parameterList) { param.apply(query); } return query; } public boolean hasSizeRestriction() { return max > DEFAULT_MAX; } public int getSizeRestriciton() { return max; } public boolean hasFirstResult() { return firstResult > DEFAULT_FIRST; } public int getFirstResult() { return firstResult; } private static int extractSizeRestriction(Method method, RepositoryMethodMetadata repositoryMethod) { if (repositoryMethod.getQuery() != null) { return repositoryMethod.getQuery().max(); } return repositoryMethod.getMethodPrefix().getDefinedMaxResults(); } @SuppressWarnings("unchecked") private static A extractFrom(Annotation[] annotations, Class target) { for (Annotation annotation : annotations) { if (annotation.annotationType().isAssignableFrom(target)) { return (A) annotation; } } return null; } private static int extractInt(Object parameter, Annotation[] annotations, Class target, int defaultVal) { if (parameter != null) { A result = extractFrom(annotations, target); if (result != null) { if (parameter instanceof Integer) { return (Integer) parameter; } else { LOG.log(Level.WARNING, "Method parameter extraction: " + "Param type must be int: {0}->is:{1}", new Object[] { target, parameter.getClass() }); } } } return defaultVal; } private static boolean isParameter(Annotation[] annotations) { return extractFrom(annotations, MaxResults.class) == null && extractFrom(annotations, FirstResult.class) == null; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/param/ToUpperStringParameterUpdate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.param; public class ToUpperStringParameterUpdate implements ParameterUpdate { private final String id; public ToUpperStringParameterUpdate(String id) { this.id = id; } @Override public String forParamWithId() { return id; } @Override public Object newParamValue(Object current) { if (current instanceof String) { return ((String) current).toUpperCase(); } return current; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/FieldProperty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.Field; public interface FieldProperty extends Property { @Override Field getAnnotatedElement(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/FieldPropertyImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Type; /** * A bean property based on the value contained in a field */ class FieldPropertyImpl implements FieldProperty { private final Field field; FieldPropertyImpl(Field field) { this.field = field; } @Override public String getName() { return field.getName(); } @Override public Type getBaseType() { return field.getGenericType(); } @Override public Field getAnnotatedElement() { return field; } @Override public Member getMember() { return field; } @Override @SuppressWarnings("unchecked") public Class getJavaClass() { return (Class) field.getType(); } @Override public V getValue(Object instance) { setAccessible(); return Reflections.getFieldValue(field, instance, getJavaClass()); } @Override public void setValue(Object instance, V value) { setAccessible(); Reflections.setFieldValue(true, field, instance, value); } @Override public Class getDeclaringClass() { return field.getDeclaringClass(); } @Override public boolean isReadOnly() { return false; } @Override public void setAccessible() { Reflections.setAccessible(field); } @Override public String toString() { return field.toString(); } @Override public int hashCode() { return field.hashCode(); } @Override public boolean equals(Object obj) { return field.equals(obj); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/MethodProperty.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.Method; public interface MethodProperty extends Property { @Override Method getAnnotatedElement(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/MethodPropertyImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.beans.Introspector; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Type; /** * A bean property based on the value represented by a getter/setter method pair */ class MethodPropertyImpl implements MethodProperty { private static final String GETTER_METHOD_PREFIX = "get"; private static final String SETTER_METHOD_PREFIX = "set"; private static final String BOOLEAN_GETTER_METHOD_PREFIX = "is"; private static final int GETTER_METHOD_PREFIX_LENGTH = GETTER_METHOD_PREFIX.length(); private static final int SETTER_METHOD_PREFIX_LENGTH = SETTER_METHOD_PREFIX.length(); private static final int BOOLEAN_GETTER_METHOD_PREFIX_LENGTH = BOOLEAN_GETTER_METHOD_PREFIX.length(); private final Method getterMethod; private final String propertyName; private final Method setterMethod; public MethodPropertyImpl(Method method) { final String accessorMethodPrefix; final String propertyNameInAccessorMethod; if (method.getName().startsWith(GETTER_METHOD_PREFIX)) { if (method.getReturnType() == Void.TYPE) { throw new IllegalArgumentException( "Invalid accessor method, must have return value if starts with 'get'. Method: " + method); } else if (method.getParameterTypes().length > 0) { throw new IllegalArgumentException( "Invalid accessor method, must have zero arguments if starts with 'get'. Method: " + method); } propertyNameInAccessorMethod = method.getName().substring(GETTER_METHOD_PREFIX_LENGTH); accessorMethodPrefix = GETTER_METHOD_PREFIX; } else if (method.getName().startsWith(SETTER_METHOD_PREFIX)) { if (method.getReturnType() != Void.TYPE) { throw new IllegalArgumentException( "Invalid accessor method, must not have return value if starts with 'set'. Method: " + method); } else if (method.getParameterTypes().length != 1) { throw new IllegalArgumentException( "Invalid accessor method, must have one argument if starts with 'set'. Method: " + method); } propertyNameInAccessorMethod = method.getName().substring(SETTER_METHOD_PREFIX_LENGTH); accessorMethodPrefix = SETTER_METHOD_PREFIX; } else if (method.getName().startsWith(BOOLEAN_GETTER_METHOD_PREFIX)) { if (method.getReturnType() != Boolean.TYPE || !method.getReturnType().isPrimitive()) { throw new IllegalArgumentException( "Invalid accessor method, must return boolean primitive if starts " + "with 'is'. Method: " + method); } propertyNameInAccessorMethod = method.getName().substring(BOOLEAN_GETTER_METHOD_PREFIX_LENGTH); accessorMethodPrefix = BOOLEAN_GETTER_METHOD_PREFIX; } else { throw new IllegalArgumentException("Invalid accessor method, must start with 'get', 'set' or 'is'. " + "Method: " + method); } if (propertyNameInAccessorMethod.length() == 0 || !Character.isUpperCase(propertyNameInAccessorMethod.charAt(0))) { throw new IllegalArgumentException("Invalid accessor method, prefix '" + accessorMethodPrefix + "' must be followed a non-empty property name, capitalized. Method: " + method); } this.propertyName = Introspector.decapitalize(propertyNameInAccessorMethod); this.getterMethod = getGetterMethod(method.getDeclaringClass(), propertyName); this.setterMethod = getSetterMethod(method.getDeclaringClass(), propertyName); } @Override public String getName() { return propertyName; } @Override @SuppressWarnings("unchecked") public Class getJavaClass() { return (Class) getterMethod.getReturnType(); } @Override public Type getBaseType() { return getterMethod.getGenericReturnType(); } @Override public Method getAnnotatedElement() { return getterMethod; } @Override public Member getMember() { return getterMethod; } @Override public V getValue(Object instance) { if (getterMethod == null) { throw new UnsupportedOperationException("Property " + this.setterMethod.getDeclaringClass() + "." + propertyName + " cannot be read, as there is no getter method."); } return Reflections.cast(Reflections.invokeMethod(getterMethod, instance)); } @Override public void setValue(Object instance, V value) { if (setterMethod == null) { throw new UnsupportedOperationException("Property " + this.getterMethod.getDeclaringClass() + "." + propertyName + " is read only, as there is no setter method."); } Reflections.invokeMethod(setterMethod, instance, value); } private static Method getSetterMethod(Class clazz, String name) { Method[] methods = clazz.getMethods(); for (Method method : methods) { String methodName = method.getName(); if (methodName.startsWith(SETTER_METHOD_PREFIX) && method.getParameterTypes().length == 1) { if (Introspector.decapitalize(methodName.substring(SETTER_METHOD_PREFIX_LENGTH)).equals(name)) { return method; } } } return null; } private static Method getGetterMethod(Class clazz, String name) { for (Method method : clazz.getDeclaredMethods()) { String methodName = method.getName(); if (method.getParameterTypes().length == 0) { if (methodName.startsWith(GETTER_METHOD_PREFIX)) { if (Introspector.decapitalize(methodName.substring(GETTER_METHOD_PREFIX_LENGTH)).equals(name)) { return method; } } else if (methodName.startsWith(BOOLEAN_GETTER_METHOD_PREFIX)) { if (Introspector.decapitalize(methodName.substring(BOOLEAN_GETTER_METHOD_PREFIX_LENGTH)).equals( name)) { return method; } } } } throw new IllegalArgumentException("no such getter method: " + clazz.getName() + '.' + name); } @Override public Class getDeclaringClass() { return getterMethod.getDeclaringClass(); } @Override public boolean isReadOnly() { return setterMethod == null; } @Override public void setAccessible() { if (setterMethod != null) { Reflections.setAccessible(setterMethod); } if (getterMethod != null) { Reflections.setAccessible(getterMethod); } } @Override public String toString() { StringBuilder builder = new StringBuilder(); if (isReadOnly()) { builder.append("read-only ").append(setterMethod.toString()).append("; "); } builder.append(getterMethod.toString()); return builder.toString(); } @Override public int hashCode() { int hash = 1; hash = hash * 31 + (setterMethod == null ? 0 : setterMethod.hashCode()); hash = hash * 31 + getterMethod.hashCode(); return hash; } @Override public boolean equals(Object obj) { if (obj instanceof MethodPropertyImpl) { MethodPropertyImpl that = (MethodPropertyImpl) obj; if (this.setterMethod == null) { return that.setterMethod == null && this.getterMethod.equals(that.getterMethod); } else { return this.setterMethod.equals(that.setterMethod) && this.getterMethod.equals(that.getterMethod); } } else { return false; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/Properties.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; /** * Utility class for working with JavaBean style properties * * @see Property */ public class Properties { private Properties() { } /** * Create a JavaBean style property from the field * * @param * @param field * @return */ public static FieldProperty createProperty(Field field) { return new FieldPropertyImpl(field); } /** * Create a JavaBean style property from the specified method * * @param * @param method * @return * @throws IllegalArgumentException * if the method does not match JavaBean conventions * @see http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html */ public static MethodProperty createProperty(Method method) { return new MethodPropertyImpl(method); } /** * Create a JavaBean style property from the specified member * * @param * @param member * @return * @throws IllegalArgumentException * if the method does not match JavaBean conventions * @see http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html */ public static Property createProperty(Member member) { if (member instanceof Method) { return new MethodPropertyImpl(Method.class.cast(member)); } else if (member instanceof Field) { return new FieldPropertyImpl(Field.class.cast(member)); } else { throw new IllegalArgumentException("Cannot make a property of " + member + " - it is neither a method or a field"); } } /** * Indicates whether this method is a valid property method. */ public static boolean isProperty(Method method) { try { new MethodPropertyImpl(method); return true; } catch (IllegalArgumentException e) { return false; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/Property.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Member; import java.lang.reflect.Type; /** * A representation of a JavaBean style property * * @param the type of the properties value * @see Properties */ public interface Property { /** * Returns the name of the property. If the property is a field, then the field name is returned. Otherwise, if the * property is a method, then the name that is returned is the getter method name without the "get" or "is" prefix, * and a lower case first letter. * * @return The name of the property */ String getName(); /** * Returns the property type * * @return The property type */ Type getBaseType(); /** * Returns the property type * * @return The property type */ Class getJavaClass(); /** * Get the element responsible for retrieving the property value * * @return */ AnnotatedElement getAnnotatedElement(); /** * Get the member responsible for retrieving the property value * * @return */ Member getMember(); /** * Returns the property value for the specified bean. The property to be returned is either a field or getter * method. * * @param bean * The bean to read the property from * @return The property value * @throws ClassCastException * if the value is not of the type V */ V getValue(Object instance); /** * This method sets the property value for a specified bean to the specified value. The property to be set is either * a field or setter method. * * @param bean * The bean containing the property to set * @param value * The new property value */ void setValue(Object instance, V value); /** * Returns the class that declares the property * * @return */ Class getDeclaringClass(); /** * Indicates whether this is a read-only property * * @return */ boolean isReadOnly(); /** * Calls the setAccessible method on the underlying member(s). *

* The operation should be performed within a {@link java.security.PrivilegedAction} */ void setAccessible(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/Reflections.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.beans.Introspector; import java.io.Serializable; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; /** * Utility class for working with JDK Reflection and also CDI's * {@link jakarta.enterprise.inject.spi.Annotated} metadata. */ public class Reflections { private Reflections() { } /** *

* Perform a runtime cast. Similar to {@link Class#cast(Object)}, but useful when you do not have a {@link Class} * object for type you wish to cast to. *

*

*

* {@link Class#cast(Object)} should be used if possible *

* * @param * the type to cast to * @param obj * the object to perform the cast on * @return the casted object * @throws ClassCastException * if the type T is not a subtype of the object * @see Class#cast(Object) */ @SuppressWarnings("unchecked") public static T cast(Object obj) { return (T) obj; } /** * Determine if a method exists in a specified class hierarchy * * @param clazz * The class to search * @param name * The name of the method * @return true if a method is found, otherwise false */ public static boolean methodExists(Class clazz, String name) { for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { for (Method m : c.getDeclaredMethods()) { if (m.getName().equals(name)) { return true; } } } return false; } /** * Get all the declared methods on the class hierarchy. This will return overridden methods. * * @param clazz * The class to search * @return the set of all declared methods or an empty set if there are none */ public static Set getAllDeclaredMethods(Class clazz) { HashSet methods = new HashSet(); for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { for (Method a : c.getDeclaredMethods()) { methods.add(a); } } return methods; } /** * Search the class hierarchy for a method with the given name and arguments. Will return the nearest match, * starting with the class specified and searching up the hierarchy. * * @param clazz * The class to search * @param name * The name of the method to search for * @param args * The arguments of the method to search for * @return The method found, or null if no method is found */ public static Method findDeclaredMethod(Class clazz, String name, Class... args) { for (Class c = clazz; c != null && c != Object.class; c = c.getSuperclass()) { try { return c.getDeclaredMethod(name, args); } catch (NoSuchMethodException e) { // No-op, continue the search } } return null; } private static String buildInvokeMethodErrorMessage(Method method, Object obj, Object... args) { StringBuilder message = new StringBuilder(String.format( "Exception invoking method [%s] on object [%s], using arguments [", method.getName(), obj)); if (args != null) { for (int i = 0; i < args.length; i++) { message.append((i > 0 ? "," : "") + args[i]); } } message.append("]"); return message.toString(); } /** * Set the accessibility flag on the {@link AccessibleObject} as described in * {@link AccessibleObject#setAccessible(boolean)}. * * @param
* member the accessible object type * @param member * the accessible object * @return the accessible object after the accessible flag has been altered * @deprecated call method directly as SecurityManager got deprecated and will soon be removed from Java */ @Deprecated public static A setAccessible(final A member) { member.setAccessible(true); return member; } /** *

* Invoke the specified method on the provided instance, passing any additional arguments included in this method as * arguments to the specified method. *

*

*

* This method provides the same functionality and throws the same exceptions as * {@link Reflections#invokeMethod(boolean, Method, Class, Object, Object...)}, with the expected return type set to * {@link Object} and no change to the method's accessibility. *

* * @see Reflections#invokeMethod(boolean, Method, Class, Object, Object...) * @see Method#invoke(Object, Object...) */ public static Object invokeMethod(Method method, Object instance, Object... args) { return invokeMethod(false, method, Object.class, instance, args); } /** *

* Invoke the specified method on the provided instance, passing any additional arguments included in this method as * arguments to the specified method. *

*

*

* This method attempts to set the accessible flag of the method before invoking the * method if the first argument is true. *

*

*

* This method provides the same functionality and throws the same exceptions as * {@link Reflections#invokeMethod(boolean, Method, Class, Object, Object...)}, with the expected return type set to * {@link Object}. *

* * @see Reflections#invokeMethod(boolean, Method, Class, Object, Object...) * @see Method#invoke(Object, Object...) */ public static Object invokeMethod(boolean setAccessible, Method method, Object instance, Object... args) { return invokeMethod(setAccessible, method, Object.class, instance, args); } /** *

* Invoke the specified method on the provided instance, passing any additional arguments included in this method as * arguments to the specified method. *

*

*

* This method provides the same functionality and throws the same exceptions as * {@link Reflections#invokeMethod(boolean, Method, Class, Object, Object...)}, with the expected return type set to * {@link Object} and honoring the accessibility of the method. *

* * @see Reflections#invokeMethod(boolean, Method, Class, Object, Object...) * @see Method#invoke(Object, Object...) */ public static T invokeMethod(Method method, Class expectedReturnType, Object instance, Object... args) { return invokeMethod(false, method, expectedReturnType, instance, args); } /** *

* Invoke the method on the instance, with any arguments specified, casting the result of invoking the method to the * expected return type. *

*

*

* This method wraps {@link Method#invoke(Object, Object...)}, converting the checked exceptions that * {@link Method#invoke(Object, Object...)} specifies to runtime exceptions. *

*

*

* If instructed, this method attempts to set the accessible flag of the method before * invoking the method. *

* * @param setAccessible * flag indicating whether method should first be set as accessible * @param method * the method to invoke * @param instance * the instance to invoke the method * @param args * the arguments to the method * @return the result of invoking the method, or null if the method's return type is void * @throws RuntimeException * if this Method object enforces Java language access control and the underlying method is * inaccessible or if the underlying method throws an exception or if the initialization provoked by * this method fails. * @throws IllegalArgumentException * if the method is an instance method and the specified instance argument is not an * instance of the class or interface declaring the underlying method (or of a subclass or implementor * thereof); if the number of actual and formal parameters differ; if an unwrapping conversion for * primitive arguments fails; or if, after possible unwrapping, a parameter value cannot be converted to * the corresponding formal parameter type by a method invocation conversion. * @throws NullPointerException * if the specified instance is null and the method is an instance method. * @throws ClassCastException * if the result of invoking the method cannot be cast to the expectedReturnType * @throws ExceptionInInitializerError * if the initialization provoked by this method fails. * @see Method#invoke(Object, Object...) */ public static T invokeMethod(boolean setAccessible, Method method, Class expectedReturnType, Object instance, Object... args) { if (setAccessible && !method.isAccessible()) { setAccessible(method); } try { return expectedReturnType.cast(method.invoke(instance, args)); } catch (IllegalAccessException ex) { throw new RuntimeException(buildInvokeMethodErrorMessage(method, instance, args), ex); } catch (IllegalArgumentException ex) { throw new IllegalArgumentException(buildInvokeMethodErrorMessage(method, instance, args), ex); } catch (InvocationTargetException ex) { throw new RuntimeException(buildInvokeMethodErrorMessage(method, instance, args), ex.getCause()); } catch (NullPointerException ex) { NullPointerException ex2 = new NullPointerException(buildInvokeMethodErrorMessage(method, instance, args)); ex2.initCause(ex.getCause()); throw ex2; } catch (ExceptionInInitializerError e) { ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildInvokeMethodErrorMessage(method, instance, args)); e2.initCause(e.getCause()); throw e2; } } /** *

* Set the value of a field on the instance to the specified value. *

*

*

* This method provides the same functionality and throws the same exceptions as * {@link Reflections#setFieldValue(boolean, Field, Object, Object)} *

*/ public static void setFieldValue(Field field, Object instance, Object value) { setFieldValue(false, field, instance, value); } /** *

* Sets the value of a field on the instance to the specified value. *

*

*

* This method wraps {@link Field#set(Object, Object)}, converting the checked exceptions that * {@link Field#set(Object, Object)} specifies to runtime exceptions. *

*

*

* If instructed, this method attempts to set the accessible flag of the method before * invoking the method. *

* * @param field * the field on which to operate, or null if the field is static * @param instance * the instance on which the field value should be set upon * @param value * the value to set the field to * @throws RuntimeException * if the underlying field is inaccessible. * @throws IllegalArgumentException * if the specified instance is not an instance of the class or interface declaring the * underlying field (or a subclass or implementor thereof), or if an unwrapping conversion fails. * @throws NullPointerException * if the specified instance is null and the field is an instance field. * @throws ExceptionInInitializerError * if the initialization provoked by this method fails. * @see Field#set(Object, Object) */ public static void setFieldValue(boolean setAccessible, Field field, Object instance, Object value) { if (setAccessible && !field.isAccessible()) { setAccessible(field); } try { field.set(instance, value); } catch (IllegalAccessException e) { throw new RuntimeException(buildSetFieldValueErrorMessage(field, instance, value), e); } catch (NullPointerException ex) { NullPointerException ex2 = new NullPointerException(buildSetFieldValueErrorMessage(field, instance, value)); ex2.initCause(ex.getCause()); throw ex2; } catch (ExceptionInInitializerError e) { ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildSetFieldValueErrorMessage(field, instance, value)); e2.initCause(e.getCause()); throw e2; } } private static String buildSetFieldValueErrorMessage(Field field, Object obj, Object value) { return String.format("Exception setting [%s] field on object [%s] to value [%s]", field.getName(), obj, value); } private static String buildGetFieldValueErrorMessage(Field field, Object obj) { return String.format("Exception reading [%s] field from object [%s].", field.getName(), obj); } public static Object getFieldValue(Field field, Object instance) { return getFieldValue(field, instance, Object.class); } /** *

* Get the value of the field, on the specified instance, casting the value of the field to the expected type. *

*

*

* This method wraps {@link Field#get(Object)}, converting the checked exceptions that {@link Field#get(Object)} * specifies to runtime exceptions. *

* * @param * the type of the field's value * @param field * the field to operate on * @param instance * the instance from which to retrieve the value * @param expectedType * the expected type of the field's value * @return the value of the field * @throws RuntimeException * if the underlying field is inaccessible. * @throws IllegalArgumentException * if the specified instance is not an instance of the class or interface declaring the * underlying field (or a subclass or implementor thereof). * @throws NullPointerException * if the specified instance is null and the field is an instance field. * @throws ExceptionInInitializerError * if the initialization provoked by this method fails. */ public static T getFieldValue(Field field, Object instance, Class expectedType) { try { return Reflections.cast(field.get(instance)); } catch (IllegalAccessException e) { throw new RuntimeException(buildGetFieldValueErrorMessage(field, instance), e); } catch (NullPointerException ex) { NullPointerException ex2 = new NullPointerException(buildGetFieldValueErrorMessage(field, instance)); ex2.initCause(ex.getCause()); throw ex2; } catch (ExceptionInInitializerError e) { ExceptionInInitializerError e2 = new ExceptionInInitializerError(buildGetFieldValueErrorMessage(field, instance)); e2.initCause(e.getCause()); throw e2; } } /** * Check if a class is serializable. * * @param clazz * The class to check * @return true if the class implements serializable or is a primitive */ public static boolean isSerializable(Class clazz) { return clazz.isPrimitive() || Serializable.class.isAssignableFrom(clazz); } /** * Gets the property name from a getter method. *

* We extend JavaBean conventions, allowing the getter method to have parameters * * @param method * The getter method * @return The name of the property. Returns null if method wasn't JavaBean getter-styled */ public static String getPropertyName(Method method) { String methodName = method.getName(); if (methodName.matches("^(get).*")) { return Introspector.decapitalize(methodName.substring(3)); } else if (methodName.matches("^(is).*")) { return Introspector.decapitalize(methodName.substring(2)); } else { return null; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/AnnotatedPropertyCriteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * A criteria that matches a property based on its annotations * @see PropertyCriteria */ public class AnnotatedPropertyCriteria implements PropertyCriteria { private final Class annotationClass; public AnnotatedPropertyCriteria(Class annotationClass) { this.annotationClass = annotationClass; } @Override public boolean fieldMatches(Field f) { return f.isAnnotationPresent(annotationClass); } @Override public boolean methodMatches(Method m) { return m.isAnnotationPresent(annotationClass); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/NamedPropertyCriteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import java.beans.Introspector; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * A criteria that matches a property based on name * @see PropertyCriteria */ public class NamedPropertyCriteria implements PropertyCriteria { private final String[] propertyNames; public NamedPropertyCriteria(String... propertyNames) { this.propertyNames = propertyNames; } @Override public boolean fieldMatches(Field f) { for (String propertyName : propertyNames) { if (propertyName.equals(f.getName())) { return true; } } return false; } @Override public boolean methodMatches(Method m) { for (String propertyName : propertyNames) { if (m.getName().startsWith("get") && Introspector.decapitalize(m.getName().substring(3)).equals(propertyName)) { return true; } } return false; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/PropertyCriteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import java.lang.reflect.Field; import java.lang.reflect.Method; /** *

* A property criteria can be used to filter the properties found by a {@link PropertyQuery} *

*

*

* Solder provides a number of property queries ( {@link TypedPropertyCriteria}, {@link NamedPropertyCriteria} and * {@link AnnotatedPropertyCriteria}), or you can create a custom query by implementing this interface. *

* * @see PropertyQuery#addCriteria(PropertyCriteria) * @see PropertyQueries * @see TypedPropertyCriteria * @see AnnotatedPropertyCriteria * @see NamedPropertyCriteria */ public interface PropertyCriteria { /** * Tests whether the specified field matches the criteria * * @param f * @return true if the field matches */ boolean fieldMatches(Field f); /** * Tests whether the specified method matches the criteria * * @param m * @return true if the method matches */ boolean methodMatches(Method m); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/PropertyQueries.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; /** * Utilities for working with property queries * * @see PropertyQuery */ public class PropertyQueries { private PropertyQueries() { } /** * Create a new {@link PropertyQuery} * * @param * @param targetClass * @return */ public static PropertyQuery createQuery(Class targetClass) { return new PropertyQuery(targetClass); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/PropertyQuery.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.deltaspike.data.impl.property.MethodProperty; import org.apache.deltaspike.data.impl.property.Properties; import org.apache.deltaspike.data.impl.property.Property; /** *

* Queries a target class for properties that match certain criteria. A property may either be a private or public * field, declared by the target class or inherited from a superclass, or a public method declared by the target class * or inherited from any of its superclasses. For properties that are exposed via a method, the property must be a * JavaBean style property, i.e. it must provide both an accessor and mutator method according to the JavaBean * specification. *

*

*

* This class is not thread-safe, however the result returned by the getResultList() method is. *

* * @see PropertyQueries * @see PropertyCriteria */ public class PropertyQuery { private final Class targetClass; private final List criteria; PropertyQuery(Class targetClass) { if (targetClass == null) { throw new IllegalArgumentException("targetClass parameter may not be null"); } this.targetClass = targetClass; this.criteria = new ArrayList(); } /** * Add a criteria to query * * @param criteria * the criteria to add */ public PropertyQuery addCriteria(PropertyCriteria criteria) { this.criteria.add(criteria); return this; } /** * Get the first result from the query, causing the query to be run. * * @return the first result, or null if there are no results */ public Property getFirstResult() { List> results = getResultList(); return results.isEmpty() ? null : results.get(0); } /** * Get the first result from the query that is not marked as read only, causing the query to be run. * * @return the first writable result, or null if there are no results */ public Property getFirstWritableResult() { List> results = getWritableResultList(); return results.isEmpty() ? null : results.get(0); } /** * Get a single result from the query, causing the query to be run. An exception is thrown if the query does not * return exactly one result. * * @return the single result * @throws RuntimeException * if the query does not return exactly one result */ public Property getSingleResult() { List> results = getResultList(); if (results.size() == 1) { return results.get(0); } else if (results.isEmpty()) { throw new RuntimeException("Expected one property match, but the criteria did not match any properties on " + targetClass.getName()); } else { throw new RuntimeException("Expected one property match, but the criteria matched " + results.size() + " properties on " + targetClass.getName()); } } /** * Get a single result from the query that is not marked as read only, causing the query to be run. An exception is * thrown if the query does not return exactly one result. * * @return the single writable result * @throws RuntimeException * if the query does not return exactly one result */ public Property getWritableSingleResult() { List> results = getWritableResultList(); if (results.size() == 1) { return results.get(0); } else if (results.isEmpty()) { throw new RuntimeException("Expected one property match, but the criteria did not match any properties on " + targetClass.getName()); } else { throw new RuntimeException("Expected one property match, but the criteria matched " + results.size() + " properties on " + targetClass.getName()); } } /** * Get the result from the query, causing the query to be run. * * @return the results, or an empty list if there are no results */ public List> getResultList() { return getResultList(false); } /** * Get the non read only results from the query, causing the query to be run. * * @return the results, or an empty list if there are no results */ public List> getWritableResultList() { return getResultList(true); } /** * Get the result from the query, causing the query to be run. * * @param writable * if this query should only return properties that are not read only * @return the results, or an empty list if there are no results */ private List> getResultList(boolean writable) { List> results = new ArrayList>(); // First check public accessor methods (we ignore private methods) for (Method method : targetClass.getMethods()) { if (!(method.getName().startsWith("is") || method.getName().startsWith("get"))) { continue; } boolean match = true; for (PropertyCriteria c : criteria) { if (!c.methodMatches(method)) { match = false; break; } } if (match) { MethodProperty property = Properties. createProperty(method); if (!writable || !property.isReadOnly()) { results.add(property); } } } Class cls = targetClass; while (cls != null && !cls.equals(Object.class)) { // Now check declared fields for (Field field : cls.getDeclaredFields()) { boolean match = true; for (PropertyCriteria c : criteria) { if (!c.fieldMatches(field)) { match = false; break; } } Property prop = Properties. createProperty(field); if (match && !resultsContainsProperty(results, prop.getName())) { if (!writable || !prop.isReadOnly()) { results.add(prop); } } } cls = cls.getSuperclass(); } return results; } private boolean resultsContainsProperty(List> results, String propertyName) { for (Property p : results) { if (propertyName.equals(p.getName())) { return true; } } return false; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/property/query/TypedPropertyCriteria.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * A criteria that matches a property based on its type * * @see PropertyCriteria */ public class TypedPropertyCriteria implements PropertyCriteria { private final Class propertyClass; public TypedPropertyCriteria(Class propertyClass) { this.propertyClass = propertyClass; } @Override public boolean fieldMatches(Field f) { return propertyClass.equals(f.getType()); } @Override public boolean methodMatches(Method m) { return propertyClass.equals(m.getReturnType()); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/tx/InvocationContextWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.tx; import org.apache.deltaspike.core.util.interceptor.AbstractInvocationContext; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; public abstract class InvocationContextWrapper extends AbstractInvocationContext { public InvocationContextWrapper(CdiQueryInvocationContext context) { super(context.getProxy(), context.getMethod(), context.getMethodParameters(), null); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/tx/ThreadLocalEntityManagerHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.tx; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; import jakarta.persistence.EntityManager; import org.apache.deltaspike.jpa.impl.entitymanager.DefaultEntityManagerHolder; @Specializes @ApplicationScoped public class ThreadLocalEntityManagerHolder extends DefaultEntityManagerHolder { private static final long serialVersionUID = 1L; private final ThreadLocal holder = new ThreadLocal(); @Override public void set(EntityManager entityManager) { holder.set(entityManager); } @Override public boolean isSet() { return get() != null; } @Override public EntityManager get() { return holder.get(); } @Override public void dispose() { holder.remove(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/tx/TransactionalQueryRunner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.tx; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; import org.apache.deltaspike.data.impl.handler.QueryRunner; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy; @ApplicationScoped public class TransactionalQueryRunner implements QueryRunner { @Inject private TransactionStrategy strategy; @Inject private ActiveEntityManagerHolder activeEntityManagerHolder; @Override public Object executeQuery(final QueryBuilder builder, final CdiQueryInvocationContext context) throws Throwable { if (context.getRepositoryMethodMetadata().isRequiresTransaction()) { try { activeEntityManagerHolder.set(context.getEntityManager()); return executeTransactional(builder, context); } finally { activeEntityManagerHolder.dispose(); } } return executeNonTransactional(builder, context); } protected Object executeNonTransactional(final QueryBuilder builder, final CdiQueryInvocationContext context) { return builder.executeQuery(context); } protected Object executeTransactional(final QueryBuilder builder, final CdiQueryInvocationContext context) throws Exception { return strategy.execute(new InvocationContextWrapper(context) { @Override public Object proceed() throws Exception { return builder.executeQuery(context); } }); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/EntityUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util; import java.io.Serializable; import java.util.LinkedList; import java.util.List; import jakarta.persistence.EmbeddedId; import jakarta.persistence.Entity; import jakarta.persistence.EntityManager; import jakarta.persistence.Id; import jakarta.persistence.IdClass; import jakarta.persistence.Table; import jakarta.persistence.Version; import jakarta.persistence.metamodel.EntityType; import org.apache.deltaspike.core.util.StringUtils; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.property.query.AnnotatedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.NamedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyQueries; import org.apache.deltaspike.data.impl.property.query.PropertyQuery; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptorProvider; public final class EntityUtils { private EntityUtils() { } @SuppressWarnings({ "unchecked", "rawtypes" }) public static Class primaryKeyClass(Class entityClass) { if (entityClass.isAnnotationPresent(IdClass.class)) { return entityClass.getAnnotation(IdClass.class).value(); // Serializablity isn't required, could cause // problems } Class clazz = PersistenceUnitDescriptorProvider.getInstance().primaryKeyIdClass(entityClass); if (clazz != null) { return clazz; } Property property = primaryKeyProperty(entityClass); return property.getJavaClass(); } public static Object primaryKeyValue(Object entity) { Property property = primaryKeyProperty(entity.getClass()); return primaryKeyValue(entity, property); } public static Object primaryKeyValue(Object entity, Property primaryKeyProperty) { return primaryKeyProperty.getValue(entity); } public static String entityName(Class entityClass) { String result = null; if (entityClass.isAnnotationPresent(Entity.class)) { result = entityClass.getAnnotation(Entity.class).name(); } else { result = PersistenceUnitDescriptorProvider.getInstance().entityName(entityClass); } return (result != null && !"".equals(result)) ? result : entityClass.getSimpleName(); } public static String tableName(Class entityClass, EntityManager entityManager) { String tableName = PersistenceUnitDescriptorProvider.getInstance().entityTableName(entityClass); if (StringUtils.isEmpty(tableName)) { Table tableAnnotation = entityClass.getAnnotation(Table.class); if (tableAnnotation != null && StringUtils.isNotEmpty(tableAnnotation.name())) { return tableAnnotation.name(); } EntityType entityType = entityManager.getMetamodel().entity(entityClass); return entityType.getName(); } return tableName; } public static boolean isEntityClass(Class entityClass) { return entityClass.isAnnotationPresent(Entity.class) || PersistenceUnitDescriptorProvider.getInstance().isEntity(entityClass); } public static Property primaryKeyProperty(Class entityClass) { for (PropertyCriteria c : primaryKeyPropertyCriteriaList(entityClass)) { PropertyQuery query = PropertyQueries. createQuery(entityClass) .addCriteria(c); if (query.getFirstResult() != null) { return query.getFirstResult(); } } throw new IllegalStateException("Class " + entityClass + " has no id defined"); } private static List primaryKeyPropertyCriteriaList(Class entityClass) { List criteria = new LinkedList(); criteria.add(new AnnotatedPropertyCriteria(Id.class)); criteria.add(new AnnotatedPropertyCriteria(EmbeddedId.class)); String[] fromMappingFiles = PersistenceUnitDescriptorProvider.getInstance().primaryKeyFields(entityClass); if (fromMappingFiles != null) { for (String id : fromMappingFiles) { criteria.add(new NamedPropertyCriteria(id)); } } return criteria; } public static Property getVersionProperty(Class entityClass) { List criteriaList = new LinkedList(); criteriaList.add(new AnnotatedPropertyCriteria(Version.class)); String fromMappingFiles = PersistenceUnitDescriptorProvider.getInstance().versionField(entityClass); if (fromMappingFiles != null) { criteriaList.add(new NamedPropertyCriteria(fromMappingFiles)); } for (PropertyCriteria criteria : criteriaList) { PropertyQuery query = PropertyQueries. createQuery(entityClass).addCriteria(criteria); Property result = query.getFirstResult(); if (result != null) { return result; } } return null; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/QueryUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util; import java.text.MessageFormat; import org.apache.deltaspike.core.util.StringUtils; public final class QueryUtils { private static final String KEYWORD_SPLITTER = "({0})(?=[A-Z])"; private QueryUtils() { } public static String[] splitByKeyword(String query, String keyword) { return query.split(MessageFormat.format(KEYWORD_SPLITTER, keyword)); } public static String uncapitalize(String value) { if (StringUtils.isEmpty(value)) { return null; } if (value.length() == 1) { return value.toLowerCase(); } return value.substring(0, 1).toLowerCase() + value.substring(1); } public static boolean isString(Object value) { return value != null && value instanceof String; } public static String nullSafeValue(String value) { return nullSafeValue(value, null); } public static String nullSafeValue(String value, String fallback) { return value != null ? value : (fallback != null ? fallback : ""); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/bean/BeanDestroyable.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.bean; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; public class BeanDestroyable implements Destroyable { private final Bean bean; private final T instance; private final CreationalContext creationalContext; public BeanDestroyable(Bean bean, T instance, CreationalContext creationalContext) { this.bean = bean; this.instance = instance; this.creationalContext = creationalContext; } @Override public void destroy() { bean.destroy(instance, creationalContext); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/bean/DependentProviderDestroyable.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.bean; import org.apache.deltaspike.core.api.provider.DependentProvider; public class DependentProviderDestroyable implements Destroyable { private final DependentProvider dependent; public DependentProviderDestroyable(DependentProvider dependent) { this.dependent = dependent; } @Override public void destroy() { dependent.destroy(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/bean/Destroyable.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.bean; public interface Destroyable { void destroy(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/BaseQueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import java.lang.reflect.Method; public abstract class BaseQueryStringExtractor implements QueryStringExtractor { Object invoke(String methodName, Object target) { try { Method method = target.getClass().getMethod(methodName); return method.invoke(target); } catch (Exception e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/EclipseLinkEjbQueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; @ProviderSpecific("org.eclipse.persistence.jpa.JpaQuery") public class EclipseLinkEjbQueryStringExtractor extends BaseQueryStringExtractor { @Override public String extractFrom(Object query) { Object dbQuery = invoke("getDatabaseQuery", query); return (String) invoke("getJPQLString", dbQuery); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/Hibernate6QueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; @ProviderSpecific("org.hibernate.query.Query") public class Hibernate6QueryStringExtractor extends BaseQueryStringExtractor { @Override public String extractFrom(Object query) { return (String) invoke("getQueryString", query); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/HibernateQueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; @ProviderSpecific("org.hibernate.ejb.HibernateQuery") public class HibernateQueryStringExtractor extends BaseQueryStringExtractor { @Override public String extractFrom(Object query) { Object hibernateQuery = invoke("getHibernateQuery", query); return (String) invoke("getQueryString", hibernateQuery); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaPersistenceUnitUtilDelegate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import org.apache.deltaspike.data.impl.util.EntityUtils; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceUnitUtil; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class OpenJpaPersistenceUnitUtilDelegate implements PersistenceUnitUtil { private final PersistenceUnitUtil persistenceUnitUtil; private final EntityManager entityManager; public OpenJpaPersistenceUnitUtilDelegate(EntityManager entityManager) { this.persistenceUnitUtil = entityManager.getEntityManagerFactory().getPersistenceUnitUtil(); this.entityManager = entityManager; } @Override public boolean isLoaded(Object entity, String attributeName) { return persistenceUnitUtil.isLoaded(entity, attributeName); } @Override public boolean isLoaded(Object entity) { return persistenceUnitUtil.isLoaded(entity); } @Override public Object getIdentifier(Object entity) { final String methodName = "getIdObject"; try { if (!entityManager.contains(entity)) { entity = entityManager.getReference(entity.getClass(), EntityUtils.primaryKeyValue(entity)); } final Object identifier = persistenceUnitUtil.getIdentifier(entity); if (identifier != null) { final Method method; method = identifier.getClass().getMethod(methodName); return method.invoke(identifier); } } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (IllegalStateException e) { return null; } return null; } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/OpenJpaQueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; @ProviderSpecific("org.apache.openjpa.persistence.OpenJPAQuery") public class OpenJpaQueryStringExtractor extends BaseQueryStringExtractor { @Override public String extractFrom(Object query) { return (String) invoke("getQueryString", query); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/PersistenceUnitUtilDelegateFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.PersistenceUnitUtil; public class PersistenceUnitUtilDelegateFactory { private PersistenceUnitUtilDelegateFactory() { } public static PersistenceUnitUtil get(EntityManager entityManager) { final EntityManagerFactory entityManagerFactory = entityManager.getEntityManagerFactory(); final String vendorName = (String) entityManagerFactory.getProperties().get("VendorName"); if (vendorName != null && "openjpa".equalsIgnoreCase(vendorName)) { return new OpenJpaPersistenceUnitUtilDelegate(entityManager); } return entityManagerFactory.getPersistenceUnitUtil(); } } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/ProviderSpecific.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; @Target({ TYPE }) @Retention(RUNTIME) public @interface ProviderSpecific { String value(); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; public interface QueryStringExtractor { String extractFrom(Object query); } ================================================ FILE: deltaspike/modules/data/impl/src/main/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.Query; @ApplicationScoped public class QueryStringExtractorFactory { private final QueryStringExtractor[] extractors = new QueryStringExtractor[] { new HibernateQueryStringExtractor(), new Hibernate6QueryStringExtractor(), new EclipseLinkEjbQueryStringExtractor(), new OpenJpaQueryStringExtractor() }; public String extract(final Query query) { for (final QueryStringExtractor extractor : extractors) { final String compare = extractor.getClass().getAnnotation(ProviderSpecific.class).value(); final Object implQuery = toImplQuery(compare, query); if (implQuery != null) { return extractor.extractFrom(implQuery); } } throw new RuntimeException("Persistence provider not supported"); } private static Object toImplQuery(final String clazzName, final Query query) { try { Class toClass = Class.forName(clazzName); try { // throw a persistence exception if not possible return query.unwrap(toClass); } catch (Exception e) { toClass.cast(query); return query; } } catch (Exception e) { return null; } } } ================================================ FILE: deltaspike/modules/data/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/data/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.data.impl.RepositoryExtension ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/DisabledRepositoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.service.DisabledRepository; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class DisabledRepositoryTest { @Deployment public static Archive deployment() { WebArchive archive = initDeployment() .addClasses(SimpleRepository.class, RepositoryDeactivator.class, DisabledRepository.class ); archive.delete("WEB-INF/classes/META-INF/apache-deltaspike.properties"); archive.addAsWebInfResource("disabled/META-INF/apache-deltaspike.properties", "classes/META-INF/apache-deltaspike.properties"); return archive; } @Inject private SimpleRepository simpleRepository; @Inject private DisabledRepository disabledRepository; @Test public void disabledSimpleRepository() { try { simpleRepository.findAll(); Assert.fail("Should have been failed because SimpleRepository was disabled"); } catch (RuntimeException e) { Assert.assertNotNull(e); } } @Test public void disabledRepository() { try { disabledRepository.findAll(); Assert.fail("Should have been failed because DisabledRepository was disabled"); } catch (RuntimeException e) { Assert.assertNotNull(e); } } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/QueryResultTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.List; import jakarta.inject.Inject; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.NonUniqueResultException; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.*; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class QueryResultTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(SimpleRepository.class) .addPackage(Simple.class.getPackage()); } @Inject private SimpleRepository repo; private SimpleBuilder builder; @Test public void should_sort_result() { // given final String name = "testSortResult"; builder.createSimple(name, Integer.valueOf(99)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(56)); builder.createSimple(name, Integer.valueOf(123)); // when List result = repo.findByName(name) .orderDesc(Simple_.counter) .orderAsc(Simple_.id) .getResultList(); // then assertNotNull(result); assertFalse(result.isEmpty()); int lastCounter = Integer.MAX_VALUE; long lastId = Long.MIN_VALUE; for (Simple simple : result) { int currentCounter = simple.getCounter().intValue(); long currentId = simple.getId().longValue(); if (currentCounter == lastCounter) { assertTrue(currentId > lastId); } else { assertTrue(currentCounter < lastCounter); } lastCounter = currentCounter; lastId = currentId; } } @Test public void should_change_sort_order() { // given final String name = "testChangeSortOrder"; builder.createSimple(name, Integer.valueOf(99)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(229)); // when QueryResult query = repo.findByName(name); List result1 = query .changeOrder(Simple_.counter) .getResultList(); List result2 = query .changeOrder(Simple_.counter) .getResultList(); // then assertEquals(22, result1.get(0).getCounter().intValue()); assertEquals(229, result2.get(0).getCounter().intValue()); } @Test public void should_clear_sort_order() { // given final String name = "testClearSortOrder"; builder.createSimple(name, Integer.valueOf(99)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(229)); // when QueryResult query = repo.findByName(name); List result1 = query .changeOrder(Simple_.counter) .getResultList(); List result2 = query .clearOrder() .getResultList(); // then assertEquals(result1.size(), result2.size()); for (int i = 0; i < result1.size(); i++) { int count1 = result1.get(i).getCounter().intValue(); int count2 = result2.get(i).getCounter().intValue(); if (count1 != count2) { return; } } fail("Both collections sorted: " + result1 + "," + result2); } @Test public void should_page_result() { // given final String name = "testPageResult"; builder.createSimple(name, Integer.valueOf(99)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(56)); builder.createSimple(name, Integer.valueOf(123)); // when List result = repo.findByName(name) .hint("jakarta.persistence.query.timeout", 10000) .lockMode(LockModeType.NONE) .flushMode(FlushModeType.COMMIT) .orderDesc(Simple_.counter) .firstResult(2) .maxResults(2) .getResultList(); // then assertNotNull(result); assertFalse(result.isEmpty()); assertEquals(2, result.size()); } @Test public void should_page_with_page_api() { // given final String name = "testPageAPI"; builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(56)); builder.createSimple(name, Integer.valueOf(99)); builder.createSimple(name, Integer.valueOf(123)); builder.createSimple(name, Integer.valueOf(229)); builder.createSimple(name, Integer.valueOf(299)); builder.createSimple(name, Integer.valueOf(389)); // when QueryResult pagedQuery = repo .findByName(name) .withPageSize(2); List result1 = pagedQuery.getResultList(); List result2 = pagedQuery.nextPage().nextPage().getResultList(); int current = pagedQuery.currentPage(); List result3 = pagedQuery.toPage(1).getResultList(); int total = pagedQuery.countPages(); int pageSize = pagedQuery.pageSize(); // then assertEquals(2, result1.size()); assertEquals(2, result2.size()); assertEquals(2, result3.size()); assertEquals(2, current); assertEquals(4, total); assertEquals(2, pageSize); assertEquals(22, result1.get(0).getCounter().intValue()); assertEquals(229, result2.get(0).getCounter().intValue()); assertEquals(99, result3.get(0).getCounter().intValue()); } @Test public void should_modify_named_query() { // given final String name = "testModifyNamedQuery"; builder.createSimple(name + 0); builder.createSimple(name + 1); builder.createSimple(name + 2); builder.createSimple(name + 3); // when List result = repo.queryResultWithNamed(name + "%") .orderDesc(Simple_.name) .getResultList(); // then assertEquals(4, result.size()); assertEquals(name + 3, result.get(0).getName()); assertEquals(name + 2, result.get(1).getName()); } @Test public void should_count_with_method_query() { // given final String name = "testCountWithMethodQuery"; builder.createSimple(name); builder.createSimple(name); // when long result = repo.findByName(name).count(); // then assertEquals(2L, result); } @Test public void should_count_with_named_query() { // given final String name = "testCountWithNamedQuery"; builder.createSimple(name); builder.createSimple(name); // when long result = repo.queryResultWithNamed(name).count(); // then assertEquals(2L, result); } @Test public void should_count_without_whereclause() { // given final String name = "testCountWithoutWhereclause"; builder.createSimple(name); builder.createSimple(name); // when long result = repo.queryAll().count(); // then assertEquals(2L, result); } @Test public void should_count_with_orderby() { // given final String name = "testCountWithOrderBy"; builder.createSimple(name); builder.createSimple(name); // when long result = repo.findByQueryWithOrderBy(name).count(); // then assertEquals(2L, result); } @Test public void should_query_optional() { // given final String name = "should_query_optional"; builder.createSimple(name); // when Simple result1 = repo.queryResultWithNamed(name).getOptionalResult(); Simple result2 = repo.queryResultWithNamed("this_does_not_exist").getOptionalResult(); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test(expected = NonUniqueResultException.class) public void should_fail_query_optional_with_nonunique() { // given final String name = "should_fail_query_optional_with_nonunique"; builder.createSimple(name); builder.createSimple(name); // when repo.queryResultWithNamed(name).getOptionalResult(); } @Test public void should_query_any() { // given final String name = "should_query_any"; builder.createSimple(name); builder.createSimple(name); // when Simple result1 = repo.queryResultWithNamed(name).getAnyResult(); Simple result2 = repo.queryResultWithNamed("this_does_not_exist").getAnyResult(); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test public void should_paginate_with_orderby() { // given SimpleStringIdBuilder builder = new SimpleStringIdBuilder(getEntityManager()); final String name = "should_paginate_with_orderby"; final String name2 = "should_paginate_with_orderby2"; builder.createSimple("a", name); builder.createSimple("b", name2); // when QueryResult allOrderByNamePaginate = repo.findAllOrderByIdPaginate(0, 10); // then assertNotNull(allOrderByNamePaginate); List resultList = allOrderByNamePaginate.getResultList(); assertEquals(2, resultList.size()); assertEquals("a", resultList.get(0).getId()); assertEquals("b", resultList.get(1).getId()); } @Test public void should_sort_all_result() { List result = repo.queryAll() .orderDesc("s.counter",false) .orderAsc("s.enabled", false) .getResultList(); // no real check here, verifying query syntax passes. assertNotNull(result); } @Test public void should_sort_name_results() { List result = repo.queryResultWithNamed("name") .orderDesc(Simple_.counter, true) .orderAsc(Simple_.id) .getResultList(); // no real check here, verifying query syntax passes. assertNotNull(result); } @Before public void setup() { builder = new SimpleBuilder(getEntityManager()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/RepositoryDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.data.test.service.DisabledRepository; import org.apache.deltaspike.data.test.service.SimpleRepository; public class RepositoryDeactivator implements ClassDeactivator { private static final long serialVersionUID = 1L; @Override public Boolean isActivated(Class targetClass) { if (targetClass.equals(SimpleRepository.class) || targetClass.equals(DisabledRepository.class)) { return Boolean.FALSE; } return null; // no result for the given class } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/RepositoryExtensionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.BaseRepositoryInterface; import org.apache.deltaspike.data.test.service.ExtendedRepositoryInterface; import org.apache.deltaspike.data.test.service.ExtendedRepositoryInterface2; import org.apache.deltaspike.data.test.service.RepositoryInterface; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.Instance; import jakarta.inject.Inject; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class RepositoryExtensionTest extends TransactionalTestCase { private static final String NAME = "a_simple"; @Deployment public static Archive deployment() { return initDeployment() .addClasses(RepositoryInterface.class, BaseRepositoryInterface.class, ExtendedRepositoryInterface.class, ExtendedRepositoryInterface2.class, SimpleRepository.class) .addPackages(true, Simple.class.getPackage()); } @Inject Instance repo; @Inject Instance extendedRepo; @Inject Instance extendedClassRepo; @Inject private ExtendedRepositoryInterface2 repoOnInterface; @Test public void should_inject() { assertNotNull(repo.get()); assertNotNull(extendedRepo.get()); assertNotNull(extendedClassRepo.get()); } @Test public void should_work_based_on_interface() { testData.createSimple( NAME ); Simple find = repoOnInterface.findByName( NAME ); assertNotNull(find); assertEquals( NAME, find.getName() ); repoOnInterface.deleteAll(); long count = repoOnInterface.count( ); assertEquals(0, count ); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/audit/AuditEntityListenerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import jakarta.enterprise.inject.Produces; import org.apache.deltaspike.data.api.audit.CurrentUser; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.AuditedEntity; import org.apache.deltaspike.data.test.domain.Principal; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class AuditEntityListenerTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addPackage(AuditEntityListener.class.getPackage()) .addAsWebInfResource("test-orm.xml", "classes/META-INF/orm.xml") .addPackage(AuditedEntity.class.getPackage()); } private final String who = "test999"; private final Principal principal = new Principal(who); @Produces @CurrentUser public String who() { return who; } @Produces @CurrentUser public Principal entity() throws Exception { try { getEntityManager().persist(principal); } catch (Throwable e) { } return principal; } @Test public void should_set_creation_date() throws Exception { // given AuditedEntity entity = new AuditedEntity(); // when getEntityManager().persist(entity); getEntityManager().flush(); // then assertNotNull(entity.getCreated()); assertNotNull(entity.getModified()); assertEquals(entity.getCreated().getTime(), entity.getModified()); } @Test public void should_set_modification_date() throws Exception { // given AuditedEntity entity = new AuditedEntity(); getEntityManager().persist(entity); getEntityManager().flush(); // when entity = getEntityManager().find(AuditedEntity.class, entity.getId()); entity.setName("test"); getEntityManager().flush(); // then assertNotNull(entity.getGregorianModified()); assertNotNull(entity.getTimestamp()); } @Test public void should_set_changing_principal() { // given AuditedEntity entity = new AuditedEntity(); getEntityManager().persist(entity); getEntityManager().flush(); // when entity = getEntityManager().find(AuditedEntity.class, entity.getId()); entity.setName("test"); getEntityManager().flush(); // then assertNotNull(entity.getChanger()); assertEquals(who, entity.getChanger()); assertNotNull(entity.getPrincipal()); assertEquals(who, entity.getPrincipal().getName()); assertNotNull(entity.getChangerOnly()); assertEquals(who, entity.getChangerOnly()); assertNotNull(entity.getChangerOnlyPrincipal()); assertEquals(who, entity.getChangerOnlyPrincipal().getName()); } @Test public void should_set_creating_principal() { // given AuditedEntity entity = new AuditedEntity(); // when getEntityManager().persist(entity); getEntityManager().flush(); // then assertNotNull(entity.getCreator()); assertEquals(who, entity.getCreator()); assertNotNull(entity.getCreatorPrincipal()); assertEquals(who, entity.getCreatorPrincipal().getName()); assertNotNull(entity.getChanger()); assertEquals(who, entity.getChanger()); assertNotNull(entity.getPrincipal()); assertEquals(who, entity.getPrincipal().getName()); assertNull(entity.getChangerOnly()); assertNull(entity.getChangerOnlyPrincipal()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/audit/PrincipalProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import org.apache.deltaspike.data.api.audit.CreatedBy; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.test.domain.AuditedEntity; import org.apache.deltaspike.data.test.domain.Principal; import org.apache.deltaspike.data.test.domain.Simple; import org.junit.Test; import java.util.Date; import static org.junit.Assert.*; public class PrincipalProviderTest { public static class MockPrincipalProvider extends PrincipalProvider { private final String who; MockPrincipalProvider(String who) { this.who = who; } @Override protected Object resolvePrincipal(Object entity, Property property) { if (property.getJavaClass().isAssignableFrom(Principal.class)) { return new Principal(who); } return who; } } @Test public void should_set_users_for_creation() { // given String creator = "creator"; MockPrincipalProvider provider = new MockPrincipalProvider(creator); AuditedEntity entity = new AuditedEntity(); // when provider.prePersist(entity); // then assertNotNull(entity.getCreator()); assertNotNull(entity.getCreatorPrincipal()); assertNotNull(entity.getChanger()); assertEquals(entity.getCreator(), creator); assertEquals(entity.getCreatorPrincipal().getName(), creator); assertEquals(entity.getChanger(), creator); assertNull(entity.getChangerOnly()); assertNull(entity.getChangerOnlyPrincipal()); } @Test public void should_set_users_for_update() { // given String changer = "changer"; MockPrincipalProvider provider = new MockPrincipalProvider(changer); AuditedEntity entity = new AuditedEntity(); // when provider.preUpdate(entity); // then assertNotNull(entity.getChanger()); assertNotNull(entity.getChangerOnly()); assertNotNull(entity.getChangerOnlyPrincipal()); assertEquals(entity.getChanger(), changer); assertEquals(entity.getChangerOnly(), changer); assertEquals(entity.getChangerOnlyPrincipal().getName(), changer); assertNull(entity.getCreator()); assertNull(entity.getCreatorPrincipal()); } @Test public void should_not_fail_on_non_audited_entity() { // given Simple entity = new Simple("should_not_fail_on_non_audited_entity"); // when PrincipalProvider provider = new MockPrincipalProvider(""); provider.prePersist(entity); provider.preUpdate(entity); // then finish the test } @Test(expected = AuditPropertyException.class) public void should_fail_on_invalid_entity() { // given PrincipalProviderTest.InvalidEntity entity = new PrincipalProviderTest.InvalidEntity(); // when new MockPrincipalProvider("").prePersist(entity); // then fail(); } private static class InvalidEntity { @CreatedBy private Date nonUser; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/audit/TimestampsProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.audit; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.apache.deltaspike.data.api.audit.CreatedOn; import org.apache.deltaspike.data.test.domain.AuditedEntity; import org.apache.deltaspike.data.test.domain.Simple; import org.junit.Test; public class TimestampsProviderTest { @Test public void should_set_dates_for_creation() { // given AuditedEntity entity = new AuditedEntity(); // when new TimestampsProvider().prePersist(entity); // then assertNotNull(entity.getCreated()); assertNotNull(entity.getModified()); assertNull(entity.getGregorianModified()); assertNull(entity.getTimestamp()); } @Test public void should_set_dates_for_update() { // given AuditedEntity entity = new AuditedEntity(); // when new TimestampsProvider().preUpdate(entity); // then assertNull(entity.getCreated()); assertNotNull(entity.getModified()); assertNotNull(entity.getGregorianModified()); assertNotNull(entity.getTimestamp()); } @Test public void should_not_fail_on_non_audited_entity() { // given Simple entity = new Simple("should_not_fail_on_non_audited_entity"); // when TimestampsProvider provider = new TimestampsProvider(); provider.prePersist(entity); provider.preUpdate(entity); // then finish the test } @Test(expected = AuditPropertyException.class) public void should_fail_on_invalid_entity() { // given InvalidEntity entity = new InvalidEntity(); // when new TimestampsProvider().prePersist(entity); // then fail(); } private static class InvalidEntity { @CreatedOn private String nonTemporal; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/builder/part/QueryRootTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.builder.part; import org.apache.deltaspike.data.impl.builder.MethodExpressionException; import org.apache.deltaspike.data.impl.meta.EntityMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMethodPrefix; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.SimpleFetchRepository; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.junit.Test; import static org.junit.Assert.assertEquals; public class QueryRootTest { private final RepositoryMetadata repo = new RepositoryMetadata(SimpleRepository.class, new EntityMetadata(Simple.class, "Simple", Long.class)); private final RepositoryMetadata repoFetchBy = new RepositoryMetadata(SimpleFetchRepository.class, new EntityMetadata(Simple.class, "Simple", Long.class)); @Test public void should_create_simple_query() { // given final String name = "findByName"; final String expected = "select e from Simple e " + "where e.name = ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_create_complex_query() { // given final String name = "findByNameAndTemporalBetweenOrEnabledIsNull" + "AndCamelCaseLikeIgnoreCaseAndEmbedded_embeddNotEqualIgnoreCase" + "OrderByEmbedded_embeddDesc"; final String expected = "select e from Simple e " + "where e.name = ?1 " + "and e.temporal between ?2 and ?3 " + "or e.enabled IS NULL " + "and upper(e.camelCase) like ?4 " + "and upper(e.embedded.embedd) <> upper(?5) " + "order by e.embedded.embedd desc"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_create_query_with_order_by_only() { // given final String name = "findByOrderByIdAsc"; final String expected = "select e from Simple e " + "order by e.id asc"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test(expected = MethodExpressionException.class) public void should_fail_in_where() { // given final String name = "findByInvalid"; // when QueryRoot.create(name, repo, prefix(name)); } @Test(expected = MethodExpressionException.class) public void should_fail_with_prefix_only() { // given final String name = "findBy"; // when QueryRoot.create(name, repo, prefix(name)); } @Test(expected = MethodExpressionException.class) public void should_fail_in_order_by() { // given final String name = "findByNameOrderByInvalidDesc"; // when QueryRoot.create(name, repo, prefix(name)); } @Test public void should_use_alternative_prefix() { // given final String name = "fetchByName"; final String expected = "select e from Simple e " + "where e.name = ?1"; // when String result = QueryRoot.create(name, repoFetchBy, new RepositoryMethodPrefix("fetchBy", name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_create_delete_query_by_name() { // given final String name = "deleteByName"; final String expected = "delete from Simple e " + "where e.name = ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_create_delete_query_by_name_and_enabled() { // given final String name = "deleteByNameAndEnabled"; final String expected = "delete from Simple e " + "where e.name = ?1 and e.enabled = ?2"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_order_by_in_order() { // given final String name = "findAllOrderByNameDescIdAsc"; final String expected = "select e from Simple e " + "order by e.name desc, e.id asc"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_LessThan() { // given final String name = "findByNameLessThan"; final String expected = "select e from Simple e " + "where e.name < ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_LessThanEquals() { // given final String name = "findByNameLessThanEquals"; final String expected = "select e from Simple e " + "where e.name <= ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_GreaterThan() { // given final String name = "findByNameGreaterThan"; final String expected = "select e from Simple e " + "where e.name > ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_GreaterThanEquals() { // given final String name = "findByNameGreaterThanEquals"; final String expected = "select e from Simple e " + "where e.name >= ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_Like() { // given final String name = "findByNameLike"; final String expected = "select e from Simple e " + "where e.name like ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_NotLike() { // given final String name = "findByNameNotLike"; final String expected = "select e from Simple e " + "where e.name not like ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_LikeIgnoreCase() { // given final String name = "findByNameLikeIgnoreCase"; final String expected = "select e from Simple e " + "where upper(e.name) like ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_NotEqual() { // given final String name = "findByNameNotEqual"; final String expected = "select e from Simple e " + "where e.name <> ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_NotEqualIgnoreCase() { // given final String name = "findByNameNotEqualIgnoreCase"; final String expected = "select e from Simple e " + "where upper(e.name) <> upper(?1)"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_Equal() { // given final String name = "findByNameEqual"; final String expected = "select e from Simple e " + "where e.name = ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_EqualIgnoreCase() { // given final String name = "findByNameEqualIgnoreCase"; final String expected = "select e from Simple e " + "where upper(e.name) = upper(?1)"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_IgnoreCase() { // given final String name = "findByNameIgnoreCase"; final String expected = "select e from Simple e " + "where upper(e.name) = upper(?1)"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_In() { // given final String name = "findByNameIn"; final String expected = "select e from Simple e " + "where e.name IN ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_Between() { // given final String name = "findByNameBetween"; final String expected = "select e from Simple e " + "where e.name between ?1 and ?2"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_IsNotNull() { // given final String name = "findByNameIsNotNull"; final String expected = "select e from Simple e " + "where e.name IS NOT NULL"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_IsNull() { // given final String name = "findByNameIsNull"; final String expected = "select e from Simple e " + "where e.name IS NULL"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_NotIn() { // given final String name = "findByNameNotIn"; final String expected = "select e from Simple e " + "where e.name NOT IN ?1"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_True() { // given final String name = "findByNameTrue"; final String expected = "select e from Simple e " + "where e.name IS TRUE"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_False() { // given final String name = "findByNameFalse"; final String expected = "select e from Simple e " + "where e.name IS FALSE"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_Containing() { // given final String name = "findByNameContaining"; final String expected = "select e from Simple e " + "where e.name like CONCAT('%', CONCAT(?1, '%'))"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_StartingWith() { // given final String name = "findByNameStartingWith"; final String expected = "select e from Simple e " + "where e.name like CONCAT(?1, '%')"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } @Test public void should_apply_comparator_EndingWith() { // given final String name = "findByNameEndingWith"; final String expected = "select e from Simple e " + "where e.name like CONCAT('%', ?1)"; // when String result = QueryRoot.create(name, repo, prefix(name)).getJpqlQuery().trim(); // then assertEquals(expected, result); } private RepositoryMethodPrefix prefix(final String name) { return new RepositoryMethodPrefix("", name); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/criteria/CriteriaTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.criteria; import jakarta.inject.Inject; import jakarta.persistence.NonUniqueResultException; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.OneToMany; import org.apache.deltaspike.data.test.domain.OneToOne; import org.apache.deltaspike.data.test.domain.Parent; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.ParentRepository; import org.apache.deltaspike.data.test.service.SimpleCriteriaRepository; import org.apache.deltaspike.data.test.service.Statistics; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; import java.util.Calendar; import java.util.Date; import java.util.List; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.*; @Category(WebProfileCategory.class) public class CriteriaTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(SimpleCriteriaRepository.class, ParentRepository.class, Statistics.class) .addPackage(Simple.class.getPackage()); } @Inject private SimpleCriteriaRepository repo; @Inject private ParentRepository parentRepo; @Test public void should_create_criteria_query() { // given final String name = "testCreateCriteriaQuery"; createSimple(name, 55); // when List result1 = repo.queryByCriteria(name, Boolean.TRUE, 0, 50); List result2 = repo.queryByCriteria(name, Boolean.TRUE, 50, 100); List result3 = repo.queryByCriteria(name, Boolean.FALSE, 50, 100); // then assertEquals(0, result1.size()); assertEquals(1, result2.size()); assertEquals(0, result3.size()); } @Test public void should_query_with_ignore_case() { // given final String name = "TEST_query_EQ_with_igNOREe_case"; final String nameLike = "TEST_query_LIKE_with_igNOREe_case"; createSimple(name, 155); createSimple(nameLike, 166); // when List result1 = repo.queryByIgnoreCase(name.toLowerCase(), "no_match"); List result2 = repo.queryByIgnoreCase("no_match", "%" + nameLike.substring(5, 22) + "%"); // then assertEquals(1, result1.size()); assertEquals(Integer.valueOf(155), result1.get(0).getCounter()); assertEquals(1, result2.size()); assertEquals(Integer.valueOf(166), result2.get(0).getCounter()); } @Test public void should_create_join_criteria_query() { // given final String name = "testCreateJoinCriteriaQuery"; final String nameOne = name + "-one"; final String nameMany = name + "-many"; Parent parent = new Parent(name); parent.setOne(new OneToOne(nameOne)); parent.add(new OneToMany(nameMany)); getEntityManager().persist(parent); getEntityManager().flush(); // when List result = parentRepo.joinQuery(name, nameOne, nameMany); // then assertEquals(1, result.size()); assertNotNull(result.get(0)); Parent queried = result.get(0); assertEquals(name, queried.getName()); assertNotNull(queried.getOne()); assertEquals(nameOne, queried.getOne().getName()); assertEquals(1, queried.getMany().size()); assertEquals(nameMany, queried.getMany().get(0).getName()); } @Test public void should_create_or_query() { // given final String name = "testCreateOrQuery"; Parent parent1 = new Parent(name + "1"); parent1.setValue(25L); Parent parent2 = new Parent(name + "2"); parent2.setValue(75L); Parent parent3 = new Parent(name + "3"); parent3.setValue(25L); Parent parent4 = new Parent(name + "1"); parent4.setValue(75L); getEntityManager().persist(parent1); getEntityManager().persist(parent2); getEntityManager().persist(parent3); getEntityManager().persist(parent4); getEntityManager().flush(); // when List result = parentRepo.orQuery(name + "1", name + "2"); // then assertEquals(2, result.size()); } @Test public void should_create_ordered_query() { // given final String name = "testCreateOrderedQuery"; Parent parent1 = new Parent(name + "99"); Parent parent2 = new Parent(name + "12"); Parent parent3 = new Parent(name + "19"); Parent parent4 = new Parent(name + "02"); getEntityManager().persist(parent1); getEntityManager().persist(parent2); getEntityManager().persist(parent3); getEntityManager().persist(parent4); getEntityManager().flush(); // when List result = parentRepo.orderedQuery(); // then assertEquals(4, result.size()); assertEquals(name + "02", result.get(0).getName()); assertEquals(name + "12", result.get(1).getName()); assertEquals(name + "19", result.get(2).getName()); assertEquals(name + "99", result.get(3).getName()); } @Test public void should_create_query_wihtout_nulls() { // given final String name = "testCreateQueryWihtoutNulls"; Parent parent = new Parent(name); getEntityManager().persist(parent); getEntityManager().flush(); // when List result = parentRepo.nullAwareQuery(name, null, null); // then assertEquals(1, result.size()); assertEquals(name, result.get(0).getName()); } @Test public void should_create_fetch_query() { // given final String name = "testCreateFetchQuery"; Parent parent = new Parent(name); parent.add(new OneToMany(name + "-1")); parent.add(new OneToMany(name + "-2")); getEntityManager().persist(parent); getEntityManager().flush(); // when Parent result = parentRepo.fetchQuery(name); // then assertNotNull(result); assertEquals(name, result.getName()); assertNotNull(result.getMany()); assertEquals(2, result.getMany().size()); } @Test public void should_create_in_query() { // given final String name = "testCreateInQuery"; Parent parent1 = new Parent(name + "-1"); Parent parent2 = new Parent(name + "-2"); Parent parent3 = new Parent(name + "-3"); getEntityManager().persist(parent1); getEntityManager().persist(parent2); getEntityManager().persist(parent3); getEntityManager().flush(); // when List result = parentRepo.fetchByName(name + "-1", name + "-2", name + "-3"); // then assertNotNull(result); assertEquals(3, result.size()); } @Test public void should_create_select_criteria_with_result_type() { // given final String name = "testCreateSelectCriteriaWithResultType"; createSimple(name, 1); createSimple(name, 2); createSimple(name, 3); createSimple(name, 4); createSimple(name, 99); // when Statistics result = repo.queryWithSelect(name); // then assertNotNull(result.getAverage()); assertEquals(Long.valueOf(5l), result.getCount()); } @Test public void should_create_select_criteria_without_result_type() { // given final String name = "testCreateSelectCriteriaWithoutResultType"; createSimple(name, 10); createSimple(name, 99); // when Object[] result = repo.queryWithSelectAggregateReturnArray(name); // then assertEquals(Integer.valueOf(10), result[0]); assertEquals(Integer.valueOf(99), result[1]); assertTrue(result[2] instanceof java.sql.Date); assertTrue(result[3] instanceof java.sql.Time || result[3] instanceof java.time.OffsetTime); assertTrue(result[4] instanceof java.sql.Timestamp || result[4] instanceof java.time.OffsetDateTime); } @Test public void should_create_select_criteria_with_attributes() { // given final String name = "testCreateSelectCriteriaWithAttributes"; createSimple(name, 10); createSimple(name, 99); // when List results = repo.queryWithSelectAttributes(name); // then for (Object[] result : results) { assertEquals(name, result[0]); assertEquals(name.toUpperCase(), result[1]); assertEquals(name.toLowerCase(), result[2]); assertEquals(name.substring(1), result[3]); assertEquals(name.substring(1, 1 + 2), result[4]); } } @Test public void should_create_select_criteria_with_optional_result() { // given final String name = "should_create_select_criteria_with_optional_result"; createSimple(name, 10); // when Simple result1 = repo.queryOptional(name); Simple result2 = repo.queryOptional(name + "_doesnt exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test(expected = NonUniqueResultException.class) public void should_fail_with_optional_nonunique_result() { // given final String name = "should_fail_with_optional_nonunique_result"; createSimple(name, 10); createSimple(name, 10); // when repo.queryOptional(name); } @Test public void should_create_select_criteria_with_any_result() { // given final String name = "should_create_select_criteria_with_any_result"; createSimple(name, 10); createSimple(name, 10); // when Simple result1 = repo.queryAny(name); Simple result2 = repo.queryAny(name + "_doesnt exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test // SELECT COUNT(DISTINCT(s.name)) FROM Simple s WHERE s.name = 'should_create_count_criteria' public void should_create_count_criteria() { // given final String name = "should_create_count_criteria"; createSimple(name, 10); createSimple(name, 11); // when Long result = repo.criteriaCount(name); // then assertNotNull(result); assertEquals(1l, result.longValue()); } @Test public void should_create_date_criteria() { // given final String name = "should_create_date_criteria"; final Simple simple = new Simple(name); simple.setTemporal(new Date()); getEntityManager().persist(simple); getEntityManager().flush(); Calendar cal = Calendar.getInstance(); cal.setTime(simple.getTemporal()); cal.add(Calendar.MINUTE, -1); Date from = cal.getTime(); cal.add(Calendar.MINUTE, 2); Date to = cal.getTime(); // when final List result = repo.findByTimeBetween(from, to); // then assertNotNull(result); assertEquals(1, result.size()); } @Test public void should_query_with_att_from_mapped_super() { // given final String name = "should_create_date_criteria"; final String superName = "super_should_create_date_criteria"; final Simple simple = new Simple(name); simple.setSuperName(superName); getEntityManager().persist(simple); getEntityManager().flush(); // when final Simple result = repo.findBySuperName(superName); // then assertEquals(superName, result.getSuperName()); } @Test public void should_apply_multiply_orderby() { // given createSimple("a", 1); createSimple("b", 2); // when final List orderByNameAndCounter = repo.findOrderByNameAndCounter(); // then assertEquals(new Integer(2), orderByNameAndCounter.get(0).getCounter()); assertEquals(new Integer(1), orderByNameAndCounter.get(1).getCounter()); } @Test public void should_apply_trim() { // given final String name = " should_apply_trim "; createSimple(name, 10); // when Object[] objects = repo.queryWithSelectAttributesAndTrim(name); assertNotNull(objects); assertEquals(name, objects[0]); assertEquals(name.trim(), objects[1]); assertEquals("should_apply_trim ", objects[2]); } private Simple createSimple(String name, Integer counter) { Simple result = new Simple(name); result.setCounter(counter); getEntityManager().persist(result); getEntityManager().flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/CdiQueryContextHolderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.lang.reflect.Method; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.impl.meta.RepositoryMethodPrefix; import org.apache.deltaspike.data.impl.meta.EntityMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMetadata; import org.apache.deltaspike.data.impl.meta.RepositoryMethodMetadata; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.junit.Test; public class CdiQueryContextHolderTest { @Test public void should_dispose_tl_when_all_empty() { // given CdiQueryContextHolder holder = new CdiQueryContextHolder(); CdiQueryInvocationContext context = dummyInvocationContext(); // when holder.set(context); CdiQueryInvocationContext temp1 = holder.get(); CdiQueryInvocationContext temp2 = holder.get(); holder.dispose(); // then assertEquals(context, temp1); assertEquals(context, temp2); assertNull(holder.get()); } @Test public void should_not_dispose_when_stack_not_empty() { // given CdiQueryContextHolder holder = new CdiQueryContextHolder(); CdiQueryInvocationContext context1 = dummyInvocationContext(); CdiQueryInvocationContext context2 = dummyInvocationContext(); // when holder.set(context1); holder.set(context2); CdiQueryInvocationContext temp1 = holder.get(); holder.dispose(); CdiQueryInvocationContext temp2 = holder.get(); holder.dispose(); // then assertEquals(context2, temp1); assertEquals(context1, temp2); assertNull(holder.get()); } private CdiQueryInvocationContext dummyInvocationContext() { return new CdiQueryInvocationContext(null, dummyMethod(), null, dummyRepo(), dummyRepoMethod(dummyRepo()), null); } private Method dummyMethod() { try { return SimpleRepository.class.getMethod("findAnyByName", String.class); } catch (Exception e) { throw new RuntimeException(e); } } private RepositoryMethodMetadata dummyRepoMethod(RepositoryMetadata metadata) { RepositoryMethodMetadata methodMetadata = new RepositoryMethodMetadata(dummyMethod()); methodMetadata.setMethodPrefix(new RepositoryMethodPrefix( metadata.getRepositoryClass().getAnnotation(Repository.class).methodPrefix(), dummyMethod().getName())); return methodMetadata; } private RepositoryMetadata dummyRepo() { return new RepositoryMetadata(SimpleRepository.class, new EntityMetadata(Simple.class)); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/EntityManagerDelegateHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.ExtendedRepositoryInterface; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class EntityManagerDelegateHandlerTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(ExtendedRepositoryInterface.class) .addPackage(Simple.class.getPackage()); } @Inject private ExtendedRepositoryInterface repository; @Test public void should_delete_detached_entity() { // given Simple simple = testData.createSimple("should_merge_entity"); Long id = simple.getId(); // when repository.detach(simple); repository.remove(repository.merge(simple)); // then assertNotNull(id); Simple search = repository.findBy(id); assertNull(search); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/EntityManagerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.List; import jakarta.inject.Inject; import org.apache.deltaspike.data.api.QueryInvocationException; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.*; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class EntityManagerTest { @Deployment public static Archive deployment() { return initDeployment(false) .addPackage(Simple.class.getPackage()) .addClasses(SimpleRepositoryWithEntityManager.class, SimpleRepositoryWithEntityManagerResolver.class, QualifiedEntityManagerTestProducer.class, NonQualifiedEntityManagerTestProducer.class, BasicEntityManagerResolver.class, LegacyRepositoryWithEntityManagerResolver.class, Simplistic.class, SimplisticEntityManagerResolver.class); } @Inject private SimpleRepositoryWithEntityManager repoWithDefaultEm; @Inject private SimpleRepositoryWithEntityManagerResolver repoWithInjection; @Test public void should_use_default_entity_manager() { // when List result = repoWithDefaultEm.findByName("testUseQualifiedEntityManager"); // then assertNotNull(result); assertEquals(0, result.size()); } /* * Injected EM throws UnsupportedOperationException on all methods. * Shortcutting the creation of multiple PUs (lazy guy...) */ @Test(expected = QueryInvocationException.class) public void should_use_entity_manager_from_resolver() { // when repoWithInjection.findByName("testUseQualifiedEntityManager"); // then fail("Fake EM should have thrown Exception"); } @Test public void shouldWorkWithLegacyConfigAsWell() { // when List result = repoWithDefaultEm.findByName("testUseQualifiedEntityManager"); // then assertNotNull(result); assertEquals(0, result.size()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandlerInheritedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple5; import org.apache.deltaspike.data.test.service.ExtendedRepositoryAbstractInherited; import org.apache.deltaspike.data.test.service.ExtendedRepositoryAbstractIntermediate; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.utils.BeansXmlUtil; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.junit.Test; import org.junit.experimental.categories.Category; import jakarta.inject.Inject; @Category(WebProfileCategory.class) public class EntityRepositoryHandlerInheritedTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment(true) .addClasses(ExtendedRepositoryAbstractIntermediate.class, ExtendedRepositoryAbstractInherited.class, NamedQualifiedEntityManagerTestProducer.class) .addPackage(Simple.class.getPackage()); } @Inject private ExtendedRepositoryAbstractInherited repo; @Test public void should_return_entity_name() { final String entityName = repo.getEntityName(); assertEquals("EntitySimple5", entityName); } @Test public void should_return_null_entity() { final Simple5 entity = repo.findByIdAndName(-1L, "any"); assertNull(entity); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/EntityRepositoryHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.util.List; import java.util.Optional; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple2; import org.apache.deltaspike.data.test.domain.SimpleStringId; import org.apache.deltaspike.data.test.domain.Simple_; import org.apache.deltaspike.data.test.service.ExtendedRepositoryAbstract; import org.apache.deltaspike.data.test.service.ExtendedRepositoryAbstract2; import org.apache.deltaspike.data.test.service.ExtendedRepositoryAbstract4; import org.apache.deltaspike.data.test.service.ExtendedRepositoryInterface; import org.apache.deltaspike.data.test.service.SimpleIntermediateRepository; import org.apache.deltaspike.data.test.service.SimpleStringIdRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; import jakarta.inject.Inject; import jakarta.persistence.metamodel.SingularAttribute; @Category(WebProfileCategory.class) public class EntityRepositoryHandlerTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(ExtendedRepositoryInterface.class) .addClasses(ExtendedRepositoryAbstract.class) .addClasses(ExtendedRepositoryAbstract2.class) .addClasses(ExtendedRepositoryAbstract4.class) .addClasses(SimpleStringIdRepository.class, SimpleIntermediateRepository.class) .addPackage(Simple.class.getPackage()); } @Inject private ExtendedRepositoryInterface repo; @Inject private ExtendedRepositoryAbstract repoAbstract; @Inject private ExtendedRepositoryAbstract2 repoAbstract2; @Inject private ExtendedRepositoryAbstract4 repoAbstract4; @Inject private SimpleStringIdRepository stringIdRepo; @Inject private SimpleIntermediateRepository intermediate; @Test public void should_save() throws Exception { // given Simple simple = new Simple("test"); // when simple = repo.save(simple); // then assertNotNull(simple.getId()); } @Test public void should_merge() throws Exception { // given Simple simple = testData.createSimple("testMerge"); Long id = simple.getId(); // when final String newName = "testMergeUpdated"; simple.setName(newName); simple = repo.save(simple); // then assertEquals(id, simple.getId()); assertEquals(newName, simple.getName()); } @Test public void should_save_and_flush() throws Exception { // given Simple simple = new Simple("test"); // when simple = repo.saveAndFlush(simple); Simple fetch = (Simple) getEntityManager() .createNativeQuery("select * from SIMPLE_TABLE where id = ?", Simple.class) .setParameter(1, simple.getId()) .getSingleResult(); // then assertEquals(simple.getId(), fetch.getId()); } @Test public void should_save_with_string_id() { // given SimpleStringId foo = new SimpleStringId("foo", "bar"); // when foo = stringIdRepo.save(foo); // then assertNotNull(foo); } @Test public void should_refresh() throws Exception { // given final String name = "testRefresh"; Simple simple = testData.createSimple(name); // when simple.setName("override"); repo.refresh(simple); // then assertEquals(name, simple.getName()); } @Test public void should_find_by_pk() throws Exception { // given Simple simple = testData.createSimple("testFindByPk"); // when Simple find = repo.findBy(simple.getId()); // then assertEquals(simple.getName(), find.getName()); } @Test public void should_find__by_pk() throws Exception { // given Simple simple = testData.createSimple("testFindByPk"); // when Optional find = repo.findOptionalBy(simple.getId()); // then assertEquals(simple.getName(), find.get().getName()); } @Test @SuppressWarnings("unchecked") public void should_find_by_example() throws Exception { // given Simple simple = testData.createSimple("testFindByExample"); // when List find = repo.findBy(simple, Simple_.name); // then assertNotNull(find); assertFalse(find.isEmpty()); assertEquals(simple.getName(), find.get(0).getName()); } @Test @SuppressWarnings("unchecked") public void should_find_by_example_with_start_and_max() throws Exception { // given Simple simple = testData.createSimple("testFindByExample1", Integer.valueOf(10)); testData.createSimple("testFindByExample1", Integer.valueOf(10)); // when List find = repo.findBy(simple, 0, 1, Simple_.name, Simple_.counter); // then assertNotNull(find); assertFalse(find.isEmpty()); assertEquals(1, find.size()); assertEquals(simple.getName(), find.get(0).getName()); } @Test @SuppressWarnings("unchecked") public void should_find_by_example_with_no_attributes() throws Exception { // given Simple simple = testData.createSimple("testFindByExample"); SingularAttribute[] attributes = new SingularAttribute[] {}; // when List find = repo.findBy(simple, attributes); // then assertNotNull(find); assertFalse(find.isEmpty()); assertEquals(simple.getName(), find.get(0).getName()); } @Test public void should_find_all() { // given testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); // when List find = repo.findAll(); // then assertEquals(2, find.size()); } @Test public void should_find_by_all_with_start_and_max() { // given testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); // when List find = repo.findAll(0, 1); // then assertEquals(1, find.size()); } @Test @SuppressWarnings({ "unchecked" }) public void should_find_by_like() { // given testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); Simple example = new Simple("test"); // when List find = repo.findByLike(example, Simple_.name); // then assertEquals(2, find.size()); } @Test @SuppressWarnings("unchecked") public void should_find_by_like_with_start_and_max() { // given testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); Simple example = new Simple("test"); // when List find = repo.findByLike(example, 1, 10, Simple_.name); // then assertEquals(1, find.size()); } @Test @SuppressWarnings("unchecked") public void should_find_by_like_non_string() { // given testData.createSimple("testFindAll1", 1); testData.createSimple("testFindAll2", 2); Simple example = new Simple("test"); example.setCounter(1); // when List find = repo.findByLike(example, Simple_.name, Simple_.counter); // then assertEquals(1, find.size()); } @Test public void should_count_all() { // given testData.createSimple("testCountAll"); // when Long result = repo.count(); // then assertEquals(Long.valueOf(1), result); } @Test @SuppressWarnings("unchecked") public void should_count_with_attributes() { // given Simple simple = testData.createSimple("testFindAll1", Integer.valueOf(55)); testData.createSimple("testFindAll2", Integer.valueOf(55)); // when Long result = repo.count(simple, Simple_.name, Simple_.counter); // then assertEquals(Long.valueOf(1), result); } @Test @SuppressWarnings("unchecked") public void should_count_with_no_attributes() { // given Simple simple = testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); SingularAttribute[] attributes = new SingularAttribute[] {}; // when Long result = repo.count(simple, attributes); // then assertEquals(Long.valueOf(2), result); } @Test @SuppressWarnings("unchecked") public void should_count_by_like() { // given testData.createSimple("testFindAll1"); testData.createSimple("testFindAll2"); Simple example = new Simple("test"); // when Long count = repo.countLike(example, Simple_.name); // then assertEquals(Long.valueOf(2), count); } @Test public void should_remove() { // given Simple simple = testData.createSimple("testRemove"); // when repo.remove(simple); repo.flush(); Simple lookup = getEntityManager().find(Simple.class, simple.getId()); // then assertNull(lookup); } @Test public void should_remove_and_flush() { // given Simple simple = testData.createSimple("testRemoveAndFlush"); // when repo.removeAndFlush(simple); Simple lookup = getEntityManager().find(Simple.class, simple.getId()); // then assertNull(lookup); } @Test public void should_remove_detach_entity() { //given Simple simple = testData.createSimple("testeAttachAndRemove"); //when repo.detach(simple); repo.attachAndRemove(simple); repo.flush(); Simple lookup = getEntityManager().find(Simple.class, simple.getId()); // then assertNull(lookup); } @Test public void should_return_table_name() { final String tableName = repoAbstract.getTableName(); final String tableName2 = repoAbstract2.getTableName(); assertEquals("SIMPLE_TABLE", tableName); assertEquals(Simple2.class.getSimpleName(), tableName2); } @Test public void should_return_entity_name() { final String entityName = repoAbstract.getEntityName(); final String entityName2 = repoAbstract4.getEntityName(); assertEquals("Simple", entityName); assertEquals("EntitySimple4", entityName2); } @Test public void should_return_entity_primary_key() { //given Simple simple = testData.createSimple("should_return_entity_primary_key"); Long id = simple.getId(); //when Long primaryKey = repo.getPrimaryKey(simple); // then assertNotNull(primaryKey); assertEquals(id, primaryKey); } @Test public void should_return_null_primary_key() { //given Simple simple = new Simple("should_return_null_primary_key"); //when Long primaryKey = repo.getPrimaryKey(simple); // then assertNull(primaryKey); } @Test public void should_return_entity_primary_key_detached_entity() { //given Simple simple = testData.createSimple("should_return_entity_primary_key"); Long id = simple.getId(); //when getEntityManager().detach(simple); Long primaryKey = repo.getPrimaryKey(simple); // then assertNotNull(primaryKey); assertEquals(id, primaryKey); } @Test public void should_query_with_hints() { Simple simple = testData.createSimple("should_return_entity_primary_key"); Long id = simple.getId(); getEntityManager().flush(); getEntityManager().clear(); Simple found = intermediate.findBy(id); assertEquals(id, found.getId()); } @Test public void should_query_names() { String name = "should_return_entity_primary_key"; testData.createSimple(name); List names = intermediate.findAllNames(); assertEquals(name, names.get(0)); } @Test public void should_query_by_name() { String name = "should_return_entity_primary_key"; Simple simple = testData.createSimple(name); Simple byName = stringIdRepo.findByName(name); assertEquals(simple, byName); } @Test public void should_query_list_by_name() { String name = "should_return_entity_primary_key"; Simple simple = testData.createSimple(name); List byName = stringIdRepo.findByName2(name); assertEquals(byName.size(), 1); assertEquals(simple, byName.get(0)); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/FullEntityRepositoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.FullRepositoryAbstract; import org.apache.deltaspike.data.test.service.FullRepositoryInterface; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class FullEntityRepositoryTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(FullRepositoryInterface.class) .addClasses(FullRepositoryAbstract.class) .addPackage(Simple.class.getPackage()); } @Inject private FullRepositoryInterface repo; @Inject private FullRepositoryAbstract repoAbstract; @Test public void should_save() throws Exception { // given Simple simple = new Simple("test"); // when simple = repo.save(simple); // then assertNotNull(simple.getId()); } @Test public void should_save_abstract() throws Exception { // given Simple simple = new Simple("test"); // when simple = repoAbstract.save(simple); // then assertNotNull(simple.getId()); } @Test public void should_persist() throws Exception { // given Simple simple = new Simple("test"); // when repo.persist(simple); // then assertNotNull(simple.getId()); } @Test public void should_persist_abstract() throws Exception { // given Simple simple = new Simple("test"); // when repoAbstract.persist(simple); // then assertNotNull(simple.getId()); } @Test public void should_save_with_merge() throws Exception { // given Simple simple = testData.createSimple("testMerge"); Long id = simple.getId(); // when final String newName = "testMergeUpdated"; simple.setName(newName); simple = repo.save(simple); // then assertEquals(id, simple.getId()); assertEquals(newName, simple.getName()); } @Test public void should_save_with_merge_abstract() throws Exception { // given Simple simple = testData.createSimple("testMerge"); Long id = simple.getId(); // when final String newName = "testMergeUpdated"; simple.setName(newName); simple = repoAbstract.save(simple); // then assertEquals(id, simple.getId()); assertEquals(newName, simple.getName()); } @Test public void should_merge() throws Exception { // given Simple simple = testData.createSimple("testMerge"); Long id = simple.getId(); // when final String newName = "testMergeUpdated"; simple.setName(newName); simple = repo.merge(simple); // then assertEquals(id, simple.getId()); assertEquals(newName, simple.getName()); } @Test public void should_merge_abstract() throws Exception { // given Simple simple = testData.createSimple("testMerge"); Long id = simple.getId(); // when final String newName = "testMergeUpdated"; simple.setName(newName); simple = repoAbstract.merge(simple); // then assertEquals(id, simple.getId()); assertEquals(newName, simple.getName()); } @Test public void should_save_and_flush() throws Exception { // given Simple simple = new Simple("test"); // when simple = repo.saveAndFlush(simple); Simple fetch = (Simple) getEntityManager() .createNativeQuery("select * from SIMPLE_TABLE where id = ?", Simple.class) .setParameter(1, simple.getId()) .getSingleResult(); // then assertEquals(simple.getId(), fetch.getId()); } @Test public void should_find_by_criteria() throws Exception { // given Simple simple = new Simple("criteria"); // when simple = repoAbstract.saveAndFlush(simple); Simple fetch = repoAbstract.fetchByName("criteria"); // then assertEquals(simple.getId(), fetch.getId()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/NamedQualifiedEntityManagerTestProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import org.apache.deltaspike.data.test.util.EntityManagerProducer; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Specializes; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; @Specializes public class NamedQualifiedEntityManagerTestProducer extends EntityManagerProducer { @Produces @PersistenceContext(unitName = "test") private EntityManager entityManager; } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/NonQualifiedEntityManagerTestProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; @Default public class NonQualifiedEntityManagerTestProducer { @Produces @PersistenceContext private EntityManager entityManager; } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QualifiedEntityManagerTestProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import java.util.Map; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.Query; import jakarta.persistence.StoredProcedureQuery; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Metamodel; import java.util.List; import org.apache.deltaspike.data.test.service.Simplistic; public class QualifiedEntityManagerTestProducer { @Produces @Simplistic private final EntityManager entityManager = new EntityManager() { @Override public T unwrap(Class arg0) { throw new UnsupportedOperationException(); } @Override public void setProperty(String arg0, Object arg1) { throw new UnsupportedOperationException(); } @Override public void setFlushMode(FlushModeType arg0) { throw new UnsupportedOperationException(); } @Override public void remove(Object arg0) { throw new UnsupportedOperationException(); } @Override public void refresh(Object arg0, LockModeType arg1, Map arg2) { throw new UnsupportedOperationException(); } @Override public void refresh(Object arg0, LockModeType arg1) { throw new UnsupportedOperationException(); } @Override public void refresh(Object arg0, Map arg1) { throw new UnsupportedOperationException(); } @Override public void refresh(Object arg0) { throw new UnsupportedOperationException(); } @Override public void persist(Object arg0) { throw new UnsupportedOperationException(); } @Override public T merge(T arg0) { throw new UnsupportedOperationException(); } @Override public void lock(Object arg0, LockModeType arg1, Map arg2) { throw new UnsupportedOperationException(); } @Override public void lock(Object arg0, LockModeType arg1) { throw new UnsupportedOperationException(); } @Override public void joinTransaction() { throw new UnsupportedOperationException(); } @Override public boolean isOpen() { throw new UnsupportedOperationException(); } @Override public EntityTransaction getTransaction() { throw new UnsupportedOperationException(); } @Override public T getReference(Class arg0, Object arg1) { throw new UnsupportedOperationException(); } @Override public Map getProperties() { throw new UnsupportedOperationException(); } @Override public Metamodel getMetamodel() { throw new UnsupportedOperationException(); } @Override public LockModeType getLockMode(Object arg0) { throw new UnsupportedOperationException(); } @Override public FlushModeType getFlushMode() { throw new UnsupportedOperationException(); } @Override public EntityManagerFactory getEntityManagerFactory() { throw new UnsupportedOperationException(); } @Override public Object getDelegate() { throw new UnsupportedOperationException(); } @Override public CriteriaBuilder getCriteriaBuilder() { throw new UnsupportedOperationException(); } @Override public void flush() { throw new UnsupportedOperationException(); } @Override public T find(Class arg0, Object arg1, LockModeType arg2, Map arg3) { throw new UnsupportedOperationException(); } @Override public T find(Class arg0, Object arg1, LockModeType arg2) { throw new UnsupportedOperationException(); } @Override public T find(Class arg0, Object arg1, Map arg2) { throw new UnsupportedOperationException(); } @Override public T find(Class arg0, Object arg1) { throw new UnsupportedOperationException(); } @Override public void detach(Object arg0) { throw new UnsupportedOperationException(); } @Override public TypedQuery createQuery(String arg0, Class arg1) { throw new UnsupportedOperationException(); } @Override public TypedQuery createQuery(CriteriaQuery arg0) { throw new UnsupportedOperationException(); } @Override public Query createQuery(String arg0) { throw new UnsupportedOperationException(); } @Override public Query createNativeQuery(String arg0, String arg1) { throw new UnsupportedOperationException(); } @SuppressWarnings("rawtypes") @Override public Query createNativeQuery(String arg0, Class arg1) { throw new UnsupportedOperationException(); } @Override public Query createNativeQuery(String arg0) { throw new UnsupportedOperationException(); } @Override public TypedQuery createNamedQuery(String arg0, Class arg1) { throw new UnsupportedOperationException(); } @Override public Query createNamedQuery(String arg0) { throw new UnsupportedOperationException(); } @Override public boolean contains(Object arg0) { throw new UnsupportedOperationException(); } @Override public void close() { throw new UnsupportedOperationException(); } @Override public void clear() { throw new UnsupportedOperationException(); } @Override public Query createQuery(CriteriaUpdate arg0) { throw new UnsupportedOperationException(); } @Override public Query createQuery(CriteriaDelete arg0) { throw new UnsupportedOperationException(); } @Override public StoredProcedureQuery createNamedStoredProcedureQuery(String arg0) { throw new UnsupportedOperationException(); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0) { throw new UnsupportedOperationException(); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0, Class... arg1) { throw new UnsupportedOperationException(); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0, String... arg1) { throw new UnsupportedOperationException(); } @Override public boolean isJoinedToTransaction() { throw new UnsupportedOperationException(); } @Override public EntityGraph createEntityGraph(Class arg0) { throw new UnsupportedOperationException(); } @Override public EntityGraph createEntityGraph(String arg0) { throw new UnsupportedOperationException(); } @Override public EntityGraph getEntityGraph(String arg0) { throw new UnsupportedOperationException(); } @Override public List> getEntityGraphs(Class arg0) { throw new UnsupportedOperationException(); } }; } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/handler/QueryHandlerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.handler; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.List; import jakarta.inject.Inject; import jakarta.persistence.NonUniqueResultException; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple2; import org.apache.deltaspike.data.test.domain.SimpleBuilder; import org.apache.deltaspike.data.test.service.Simple2Repository; import org.apache.deltaspike.data.test.service.SimpleRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class QueryHandlerTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(SimpleRepository.class, Simple2Repository.class) .addPackage(Simple.class.getPackage()); } @Inject private SimpleRepository repo; @Inject private Simple2Repository repo2; private SimpleBuilder builder; @Test public void should_delegate_to_implementation() { // given final String name = "testDelegateToImplementation"; builder.createSimple(name); // when List result = repo.implementedQueryByName(name); // then assertNotNull(result); assertEquals(1, result.size()); } @Test public void should_create_named_query_index() { // given final String name = "testCreateNamedQueryIndex"; builder.createSimple(name); // when List result = repo.findByNamedQueryIndexed(name, Boolean.TRUE); // then assertNotNull(result); assertEquals(1, result.size()); assertEquals(name, result.get(0).getName()); } @Test public void should_create_named_query_named() { // given final String name = "testCreateNamedQueryNamed"; Simple simple = builder.createSimple(name); // when Simple result = repo.findByNamedQueryNamed(simple.getId(), Boolean.TRUE); // then assertNotNull(result); assertEquals(name, result.getName()); } @Test public void should_run_annotated_query() { // given final String name = "testRunAnnotatedQuery"; builder.createSimple(name); // when Simple result = repo.findByQuery(name); // then assertNotNull(result); assertEquals(name, result.getName()); } @Test public void should_create_query_by_method_name() { // given final String name = "testCreateQueryByMethodName"; builder.createSimple(name); // when Simple result = repo.findByNameAndEnabled(name, Boolean.TRUE); // then assertNotNull(result); assertEquals(name, result.getName()); } @Test public void should_create_query_delete_by_method_name() { // given final String name = "testCreateQueryByMethodName"; builder.createSimple(name); // when repo.deleteByName(name); repo.flush(); Simple result = repo.findAnyByName(name); // then assertNull(result); } @Test public void should_create_query_remove_by_method_name() { // given final String name = "testCreateQueryByMethodName"; builder.createSimple(name); // when repo.removeByName(name); repo.flush(); Simple result = repo.findAnyByName(name); // then assertNull(result); } @Test public void should_create_query_remove_by_method_name_with_multiply_params() { // given final String name = "testCreateQueryByMethodName"; builder.createSimple(name); // when repo.removeByNameAndEnabled(name, Boolean.TRUE); repo.flush(); Simple result = repo.findAnyByName(name); // then assertNull(result); } @Test public void should_create_query_delete_by_method_name_with_multiply_params() { // given final String name = "testCreateQueryByMethodName"; builder.createSimple(name); // when repo.deleteByNameAndEnabled(name, Boolean.TRUE); repo.flush(); Simple result = repo.findAnyByName(name); // then assertNull(result); } @Test public void should_restrict_result_size_by_annotation() { // given final String name = "testRestrictResultSizeByAnnotation"; builder.createSimple(name); builder.createSimple(name); // when List result = repo.findByNamedQueryIndexed(name, Boolean.TRUE); // then assertNotNull(result); assertEquals(1, result.size()); } @Test public void should_restrict_result_size_by_parameters() { // given final String name = "testRestrictResultSizeByParameters"; builder.createSimple(name); Simple second = builder.createSimple(name); // when List result = repo.findByNamedQueryRestricted(name, Boolean.TRUE, 1, 1); // then assertNotNull(result); assertEquals(1, result.size()); assertEquals(second.getId(), result.get(0).getId()); } @Test public void should_work_with_2nd_repo() { // given final String name = "testWorkWith2ndRepository"; Simple2 simple = createSimple2(name); // when Simple2 result = repo2.findByName(name); // then assertNotNull(result); assertEquals(simple.getId(), result.getId()); assertEquals(name, result.getName()); } @Test public void should_return_aggregate() { // given final String name = "testReturnAggregate"; builder.createSimple(name); // when Long result = repo.findCountByQuery(name); // then assertNotNull(result); } @Test public void should_find_with_native_query() { // given final String name = "testFindWithNativeQuery"; builder.createSimple(name); builder.createSimple(name); // when List result = repo.findWithNative(name); // then assertNotNull(result); assertEquals(2, result.size()); assertTrue(result.get(0) instanceof Simple); assertEquals(name, result.get(0).getName()); } @Test public void should_order_result_by_method_order_by() { // given final String name = "testFindWithNativeQuery"; builder.createSimple(name, Integer.valueOf(33)); builder.createSimple(name, Integer.valueOf(66)); builder.createSimple(name, Integer.valueOf(66)); builder.createSimple(name, Integer.valueOf(22)); builder.createSimple(name, Integer.valueOf(55)); // when List result = repo.findByOrderByCounterAscIdDesc(); // then assertNotNull(result); assertFalse(result.isEmpty()); long lastId = Long.MAX_VALUE; int lastCounter = Integer.MIN_VALUE; for (Simple simple : result) { long currentId = simple.getId().longValue(); int currentCounter = simple.getCounter().intValue(); if (currentCounter == lastCounter) { assertTrue(currentId < lastId); } else { assertTrue(currentCounter > lastCounter); } lastId = currentId; lastCounter = currentCounter; } } @Test public void should_execute_update() { // given final String name = "testFindWithNativeQuery"; final String newName = "testFindWithNativeQueryUpdated" + System.currentTimeMillis(); Simple s = builder.createSimple(name); // when int count = repo.updateNameForId(newName, s.getId()); // then assertEquals(1, count); } @Test public void should_create_optinal_query_by_name() { // given final String name = "should_create_optinal_query_by_name"; builder.createSimple(name); // when Simple result1 = repo.findOptionalByName(name); Simple result2 = repo.findOptionalByName(name + "_doesnt_exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test public void should_create_optinal_query_by_annotation() { // given final String name = "should_create_optinal_query_by_annotation"; builder.createSimple(name); // when Simple result1 = repo.findByNameOptional(name); Simple result2 = repo.findByNameOptional(name + "_doesnt_exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test(expected = NonUniqueResultException.class) public void should_fail_optinal_query_by_name_with_nonunique() { // given final String name = "should_fail_optinal_query_by_name_with_nonunique"; builder.createSimple(name); builder.createSimple(name); // when repo.findOptionalByName(name); } @Test(expected = NonUniqueResultException.class) public void should_fail_optinal_query_by_annotation_with_nonunique() { // given final String name = "should_fail_optinal_query_by_annotation_with_nonunique"; builder.createSimple(name); builder.createSimple(name); // when repo.findByNameOptional(name); } @Test public void should_create_any_query_by_name() { // given final String name = "should_create_any_query_by_name"; builder.createSimple(name); builder.createSimple(name); // when Simple result1 = repo.findAnyByName(name); Simple result2 = repo.findAnyByName(name + "_doesnt_exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test public void should_create_any_query_by_annotation() { // given final String name = "should_create_any_query_by_annotation"; builder.createSimple(name); builder.createSimple(name); // when Simple result1 = repo.findByNameAny(name); Simple result2 = repo.findByNameAny(name + "_doesnt_exist"); // then assertNotNull(result1); assertEquals(name, result1.getName()); assertNull(result2); } @Test public void should_create_case_insensitive_query_for_like_comparator() { // given final String name = "Should_Create_Case_Insensitive_Query_For_Like"; builder.createSimple(name); // when Simple result = repo.findByNameLikeIgnoreCase("should_create_CASE_Insensitive_QUERY_for_l%"); // then assertEquals(name, result.getName()); } @Test public void should_create_case_insensitive_query_for_equals_comparator() { // given final String name = "Should_Create_Case_Insensitive_Query_for_Equals"; builder.createSimple(name); // when Simple result = repo.findByNameIgnoreCase(name.toLowerCase()); // then assertEquals(name, result.getName()); } @Test public void should_find_first_2() { final String name = "Should_Create_Case_Insensitive_Query_for_Equals"; builder.createSimple(name); builder.createSimple(name); builder.createSimple(name); builder.createSimple("this is something else"); List result = repo.findFirst2ByName(name); assertEquals(2, result.size()); } @Test public void should_find_top_2() { final String name = "Should_Create_Case_Insensitive_Query_for_Equals"; builder.createSimple(name); builder.createSimple(name); builder.createSimple(name); builder.createSimple("this is something else"); List result = repo.findTop2ByName(name); assertEquals(2, result.size()); } @Test public void should_find_top_3_ordered() { builder.createSimple("zebra"); builder.createSimple("willow"); builder.createSimple("kangaroo"); builder.createSimple("bologna"); List result = repo.findFirst3OrderByName(); assertEquals("bologna", result.get(0).getName()); assertEquals("kangaroo", result.get(1).getName()); assertEquals("willow", result.get(2).getName()); } @Test public void should_find_all_ordered() { builder.createSimple("zebra"); builder.createSimple("willow"); builder.createSimple("kangaroo"); builder.createSimple("bologna"); List result = repo.findAllOrderByName(); assertEquals("bologna", result.get(0).getName()); assertEquals("kangaroo", result.get(1).getName()); assertEquals("willow", result.get(2).getName()); assertEquals("zebra", result.get(3).getName()); } @Test public void should_count_by_name() { builder.createSimple("zebra"); builder.createSimple("zebra"); builder.createSimple("willow"); builder.createSimple("kangaroo"); builder.createSimple("kangaroo"); builder.createSimple("kangaroo"); builder.createSimple("bologna"); assertEquals(repo.countByName("bologna"), 1); assertEquals(repo.countByName("kangaroo"), 3); assertEquals(repo.countByName("willow"), 1); assertEquals(repo.countByName("zebra"), 2); } @Before public void setup() { builder = new SimpleBuilder(getEntityManager()); } private Simple2 createSimple2(String name) { Simple2 result = new Simple2(name); getEntityManager().persist(result); getEntityManager().flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/mapping/MappedRepositoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.mapping; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple_; import org.apache.deltaspike.data.test.domain.dto.BooleanWrapper; import org.apache.deltaspike.data.test.domain.dto.SimpleDto; import org.apache.deltaspike.data.test.domain.dto.SimpleId; import org.apache.deltaspike.data.test.service.SimpleMappedDtoRepository; import org.apache.deltaspike.data.test.service.SimpleMappedRepository; import org.apache.deltaspike.data.test.service.SimpleMapper; import org.apache.deltaspike.data.test.service.SimpleQueryInOutMapper; import org.apache.deltaspike.data.test.service.WrappedMapper; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class MappedRepositoryTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses( SimpleMappedRepository.class, SimpleMappedDtoRepository.class, SimpleMapper.class, WrappedMapper.class, SimpleQueryInOutMapper.class) .addPackages(false, Simple.class.getPackage(), SimpleDto.class.getPackage()); } @Inject private SimpleMappedRepository repository; @Inject private SimpleMappedDtoRepository dtoRepository; @Test public void should_map_entityrepo_methods() { // given SimpleDto dto = new SimpleDto(); dto.setName("should_map_entityrepo_methods"); dto.setEnabled(Boolean.TRUE); // when SimpleDto saved = repository.saveAndFlush(dto); SimpleDto loadedDto = repository.findBy(saved.getId()); Simple loaded = getEntityManager().find(Simple.class, saved.getId().getId()); // then assertNotNull(loadedDto); assertNotNull(loaded); assertEquals(saved.getName(), loaded.getName()); assertEquals(saved.getEnabled(), loaded.getEnabled()); } @Test public void should_map_method_expression() { // given Simple simple = new Simple("should_map_method_expression"); simple.setEnabled(Boolean.TRUE); getEntityManager().persist(simple); // when List result = repository.findByEnabled(Boolean.TRUE); // then boolean found = false; for (SimpleDto dto : result) { if (dto.getName().equals(simple.getName())) { found = true; break; } } assertTrue(found); } @Test public void should_override_class_config_with_method_config() { // given Simple simple = new Simple("should_map_method_expression"); simple.setEnabled(Boolean.TRUE); getEntityManager().persist(simple); // when List result = repository.findByEnabled(new BooleanWrapper(Boolean.TRUE)); // then boolean found = false; for (SimpleDto dto : result) { if (dto.getName().equals(simple.getName())) { found = true; break; } } assertTrue(found); } @Test public void should_find_with_queryresult() { // given final String name = "should_find_with_queryresult"; Simple simple = new Simple(name); simple.setEnabled(Boolean.TRUE); getEntityManager().persist(simple); // when List result = repository.findByNameToo(name) .changeOrder(Simple_.name.getName()) .getResultList(); // then assertTrue(result.size() > 0); } @Test public void should_save_new_entity_with_simplemapper() { // given SimpleDto dto = new SimpleDto(); dto.setName("should_save_new_entity_with_simplemapper"); dto.setEnabled(Boolean.TRUE); // when SimpleDto result = dtoRepository.save(dto); // then assertNotNull(result); assertNotNull(result.getId()); } @Test public void should_update_existing_entity_with_simplemapper() { // given final String name = "should_update_existing_entity_with_simplemapper"; Simple simple = new Simple(name); simple.setEnabled(Boolean.TRUE); getEntityManager().persist(simple); SimpleDto dto = new SimpleDto(); dto.setName(name + "_updated"); dto.setEnabled(Boolean.TRUE); dto.setId(new SimpleId(simple.getId())); // when dtoRepository.save(dto); Simple lookup = getEntityManager().find(Simple.class, simple.getId()); // then assertNotNull(lookup); assertEquals(name + "_updated", lookup.getName()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/meta/MethodPrefixTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta; import org.junit.Test; import static org.junit.Assert.assertEquals; public class MethodPrefixTest { @Test public void shouldParseArbitraryMethodFindPrefix() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findTop20ByName"); String resultingQuery = methodPrefix.removePrefix("findTop20ByName"); assertEquals("Name", resultingQuery); } @Test public void shouldParseFirst20MethodFindPrefix() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findFirst20ByName"); String resultingQuery = methodPrefix.removePrefix("findFirst20ByName"); assertEquals("Name", resultingQuery); } @Test public void shouldParseDefinedMaxResults() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findFirst20ByName"); int maxResults = methodPrefix.getDefinedMaxResults(); assertEquals(20, maxResults); } @Test public void shouldNotParseNonMatchingMethodName() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findAnyByName"); int maxResults = methodPrefix.getDefinedMaxResults(); assertEquals(0, maxResults); } @Test public void shouldParseOrderByEmailDesc() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findFirst3OrderByEmailDesc"); String resultingQuery = methodPrefix.removePrefix("findFirst3OrderByEmailDesc"); assertEquals("OrderByEmailDesc", resultingQuery); } @Test public void shouldParseOrderByEmail() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findFirst3OrderByEmail"); String resultingQuery = methodPrefix.removePrefix("findFirst3OrderByEmail"); assertEquals("OrderByEmail", resultingQuery); } @Test public void shouldParseFindAllOrderByName() { RepositoryMethodPrefix methodPrefix = new RepositoryMethodPrefix("","findAllOrderByName"); String resultingQuery = methodPrefix.removePrefix("findAllOrderByName"); assertEquals("OrderByName", resultingQuery); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/meta/unit/DescriptorHierarchyBuilderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta.unit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import java.util.LinkedList; import java.util.List; import org.apache.deltaspike.jpa.spi.descriptor.xml.AbstractEntityHierarchyBuilder; import org.apache.deltaspike.jpa.spi.descriptor.xml.EntityDescriptor; import org.apache.deltaspike.jpa.spi.descriptor.xml.MappedSuperclassDescriptor; import org.junit.Before; import org.junit.Test; public class DescriptorHierarchyBuilderTest { private final List entities = new LinkedList(); private final List superClasses = new LinkedList(); @Before public void before() { entities.add(new EntityDescriptor(null, null, "test", EntityLevel3.class, null, null, null)); entities.add(new EntityDescriptor(null, null, "test", EntityLevel5.class, null, null, null)); superClasses.add(new MappedSuperclassDescriptor(new String[] { "id" }, null, "test", MappedLevel1.class, null, null)); superClasses.add(new MappedSuperclassDescriptor(null, null, "test", MappedLevel4.class, null, null)); superClasses.add(new MappedSuperclassDescriptor(null, null, "test", MappedUnrelated.class, null, null)); superClasses.add(new MappedSuperclassDescriptor(null, null, "test", MappedLevel2.class, null, null)); } @Test public void should_build_hierarchy() { // when AbstractEntityHierarchyBuilder.buildHierarchy(entities, superClasses); // then assertEquals(entities.size(), 2); assertEquals(EntityLevel3.class, entities.get(0).getEntityClass()); assertEquals(EntityLevel5.class, entities.get(1).getEntityClass()); assertEquals(MappedLevel2.class, entities.get(0).getParent().getEntityClass()); assertEquals(MappedLevel4.class, entities.get(1).getParent().getEntityClass()); assertEquals(superClasses.size(), 4); assertNull(superClasses.get(0).getParent()); assertEquals(EntityLevel3.class, superClasses.get(1).getParent().getEntityClass()); assertNull(superClasses.get(2).getParent()); assertEquals(MappedLevel1.class, superClasses.get(3).getParent().getEntityClass()); } private static class MappedLevel1 { @SuppressWarnings("unused") private Long id; } private static class MappedLevel2 extends MappedLevel1 { } private static class EntityLevel3 extends MappedLevel2 { } private static class MappedLevel4 extends EntityLevel3 { } private static class EntityLevel5 extends MappedLevel4 { } private static class MappedUnrelated { } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/meta/unit/OrmXmlBasedRepositoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta.unit; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.mapped.MappedOne; import org.apache.deltaspike.data.test.service.MappedOneRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ArchivePaths; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class OrmXmlBasedRepositoryTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(MappedOneRepository.class) .addAsLibraries( ShrinkWrap.create(JavaArchive.class, "domain.jar") .addPackage(MappedOne.class.getPackage()) .addAsResource("test-custom-orm.xml", ArchivePaths.create("META-INF/custom-orm.xml")) ) .addAsWebInfResource("test-mapped-persistence.xml", ArchivePaths.create("classes/META-INF/persistence.xml")) .addAsWebInfResource("test-default-orm.xml", ArchivePaths.create("classes/META-INF/orm.xml")); } @Inject private MappedOneRepository mappedOneRepository; @Test public void should_find_by() { // given MappedOne one = createMappedOne("shouldFindBy"); // when MappedOne byPk = mappedOneRepository.findBy(one.getId()); MappedOne byName = mappedOneRepository.findByName("shouldFindBy"); // then assertEquals(one.getId(), byPk.getId()); assertEquals(one.getId(), byName.getId()); } private MappedOne createMappedOne(String name) { MappedOne result = new MappedOne(name); getEntityManager().persist(result); getEntityManager().flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/meta/unit/PersistenceUnitsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.meta.unit; import org.apache.deltaspike.data.impl.meta.EntityMetadata; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import org.apache.deltaspike.data.impl.util.EntityUtils; import org.apache.deltaspike.data.test.domain.Parent; import org.apache.deltaspike.data.test.domain.TeeId; import org.apache.deltaspike.data.test.domain.mapped.MappedOne; import org.apache.deltaspike.data.test.domain.mapped.MappedThree; import org.apache.deltaspike.data.test.domain.mapped.MappedTwo; import org.apache.deltaspike.data.test.service.MappedOneRepository; import org.apache.deltaspike.data.test.util.TestDeployments; import org.apache.deltaspike.jpa.spi.descriptor.xml.EntityDescriptor; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptorProvider; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class PersistenceUnitsTest { @Deployment public static Archive deployment() { WebArchive war = TestDeployments.initDeployment(); war.delete("WEB-INF/classes/META-INF/persistence.xml"); return war.addPackages(true, Parent.class.getPackage()) .addClasses(MappedOneRepository.class) .addAsWebInfResource("test-mapped-persistence.xml", "classes/META-INF/persistence.xml") .addAsWebInfResource("test-default-orm.xml", "classes/META-INF/orm.xml") .addAsWebInfResource("test-custom-orm.xml", "classes/META-INF/custom-orm.xml"); } @Test public void should_recognize_entity_data() { // given // when boolean positive1 = PersistenceUnitDescriptorProvider.getInstance().isEntity(MappedOne.class); boolean positive2 = PersistenceUnitDescriptorProvider.getInstance().isEntity(MappedTwo.class); boolean positive3 = PersistenceUnitDescriptorProvider.getInstance().isEntity(MappedThree.class); boolean negative = PersistenceUnitDescriptorProvider.getInstance().isEntity(Long.class); // then assertTrue(positive1); assertTrue(positive2); assertTrue(positive3); assertFalse(negative); } @Test public void should_recognize_ids() { // given // when String[] idField1 = PersistenceUnitDescriptorProvider.getInstance().primaryKeyFields(MappedOne.class); String[] idField2 = PersistenceUnitDescriptorProvider.getInstance().primaryKeyFields(MappedThree.class); // then assertEquals(1, idField1.length); assertEquals("id", idField1[0]); assertEquals(1, idField2.length); assertEquals("id", idField2[0]); } @Test public void should_recognize_name() { // given // when String name = PersistenceUnitDescriptorProvider.getInstance().entityName(MappedOne.class); // then assertEquals("Mapped_One", name); } @Test public void should_recognize_id_class() { // given // when Class idClass = PersistenceUnitDescriptorProvider.getInstance().primaryKeyIdClass(MappedTwo.class); // then assertEquals(TeeId.class, idClass); } @Test public void should_prepare_repo_entity() { // given // when EntityMetadata entity1 = lookupMetadata(MappedOne.class); EntityMetadata entity2 = lookupMetadata(MappedTwo.class); EntityMetadata entity3 = lookupMetadata(MappedThree.class); // then assertNotNull(entity1); assertNotNull(entity2); assertEquals(Long.class, entity1.getPrimaryKeyClass()); assertEquals(TeeId.class, entity2.getPrimaryKeyClass()); assertEquals(Long.class, entity3.getPrimaryKeyClass()); } protected EntityMetadata lookupMetadata(Class entityClass) { EntityDescriptor entity = PersistenceUnitDescriptorProvider.getInstance().find(entityClass); if (entity != null) { return new EntityMetadata(entityClass, EntityUtils.primaryKeyClass(entityClass)); } return null; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/property/ClassToIntrospect.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.net.URL; public class ClassToIntrospect { private String name; private String p; private URL URL; public long primitiveProperty = 0; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getP() { return p; } public void setP(String p) { this.p = p; } public String getTitle() { return "Hero"; } public String get() { return null; } public boolean is() { return false; } public void getFooBar() { } public void setSalary(Double base, Double bonus) { } public URL getURL() { return URL; } public void setURL(URL URL) { this.URL = URL; } public Boolean isValid() { return false; } public boolean isValidPrimitiveBoolean() { return false; } public long getPrimitiveProperty() { return 0l; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/property/PropertyFromFieldTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import java.lang.reflect.Field; import org.apache.deltaspike.data.impl.property.FieldProperty; import org.apache.deltaspike.data.impl.property.Properties; import org.junit.Test; /** * Verify that only valid properties are permitted, as per the JavaBean specification. */ public class PropertyFromFieldTest { @Test public void testAccessingPrimitiveTypedFieldProperty() throws Exception { final Field field = ClassToIntrospect.class.getField("primitiveProperty"); FieldProperty propertyUT = Properties.createProperty(field); propertyUT.getValue(new ClassToIntrospect()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/property/PropertyFromMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.reflect.Method; import java.net.URL; import org.apache.deltaspike.data.impl.property.MethodProperty; import org.apache.deltaspike.data.impl.property.Properties; import org.apache.deltaspike.data.impl.property.Property; import org.junit.Test; /** * Verify that only valid properties are permitted, as per the JavaBean specification. * @see http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html */ public class PropertyFromMethodTest { @Test public void testValidPropertyGetterMethod() throws Exception { Method getter = ClassToIntrospect.class.getMethod("getName"); Property p = Properties.createProperty(getter); assertNotNull(p); assertEquals("name", p.getName()); assertEquals(getter, p.getMember()); } @Test public void testValidPropertySetterMethod() throws Exception { Property p = Properties.createProperty(ClassToIntrospect.class.getMethod("setName", String.class)); assertNotNull(p); assertEquals("name", p.getName()); } @Test public void testReadOnlyProperty() throws Exception { Property p = Properties.createProperty(ClassToIntrospect.class.getMethod("getTitle")); assertNotNull(p); assertEquals("title", p.getName()); assertTrue(p.isReadOnly()); } @Test(expected = IllegalArgumentException.class) public void testEmptyPropertyGetterMethod() throws Exception { Properties.createProperty(ClassToIntrospect.class.getMethod("get")); } @Test(expected = IllegalArgumentException.class) public void testEmptyBooleanPropertyGetterMethod() throws Exception { Properties.createProperty(ClassToIntrospect.class.getMethod("is")); } @Test(expected = IllegalArgumentException.class) public void testNonPrimitiveBooleanPropertyIsMethod() throws Exception { Properties.createProperty(ClassToIntrospect.class.getMethod("isValid")); } @Test public void testSingleCharPropertyGetterMethod() throws Exception { Method getter = ClassToIntrospect.class.getMethod("getP"); Property p = Properties.createProperty(getter); assertNotNull(p); assertEquals("p", p.getName()); assertEquals(getter, p.getMember()); } @Test public void testSingleCharPropertySetterMethod() throws Exception { Property p = Properties.createProperty(ClassToIntrospect.class.getMethod("setP", String.class)); assertNotNull(p); assertEquals("p", p.getName()); } @Test(expected = IllegalArgumentException.class) public void testGetterMethodWithVoidReturnType() throws Exception { Properties.createProperty(ClassToIntrospect.class.getMethod("getFooBar")); } @Test(expected = IllegalArgumentException.class) public void testSetterMethodWithMultipleParameters() throws Exception { Properties.createProperty(ClassToIntrospect.class.getMethod("setSalary", Double.class, Double.class)); } @Test public void testAcronymProperty() throws Exception { Method getter = ClassToIntrospect.class.getMethod("getURL"); Property p = Properties.createProperty(getter); assertNotNull(p); assertEquals("URL", p.getName()); assertEquals(getter, p.getMember()); } // SOLDER-298 @Test public void testPrimitiveBooleanProperty() throws Exception { Property p = Properties.createProperty(ClassToIntrospect.class.getMethod("isValidPrimitiveBoolean")); assertNotNull(p); } @Test public void testAccessingPrimitiveTypedMethodProperty() throws Exception { final Method method = ClassToIntrospect.class.getMethod("getPrimitiveProperty"); MethodProperty propertyUT = Properties.createProperty(method); propertyUT.getValue(new ClassToIntrospect()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/property/query/PropertyQueryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.property.query; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.apache.deltaspike.data.impl.property.Property; import org.apache.deltaspike.data.impl.property.query.NamedPropertyCriteria; import org.apache.deltaspike.data.impl.property.query.PropertyQueries; import org.apache.deltaspike.data.impl.property.query.PropertyQuery; import org.apache.deltaspike.data.impl.property.query.TypedPropertyCriteria; import org.junit.Test; /** * Validate the property query mechanism. */ public class PropertyQueryTest { /** * Querying for a single result with a criteria that matches multiple properties should throw an exception. * * @see PropertyQuery#getSingleResult() */ @Test(expected = RuntimeException.class) public void testNonUniqueSingleResultThrowsException() { PropertyQuery q = PropertyQueries. createQuery(Person.class); q.addCriteria(new TypedPropertyCriteria(String.class)); q.getSingleResult(); } /** * Querying for a single result with a criteria that does not match any properties should throw an exception. * * @see PropertyQuery#getSingleResult() */ @Test(expected = RuntimeException.class) public void testEmptySingleResultThrowsException() { PropertyQuery q = PropertyQueries. createQuery(Person.class); q.addCriteria(new TypedPropertyCriteria(Integer.class)); q.getSingleResult(); } /** * Querying for a single result with a criterai that matches exactly one property should return the property. * * @see PropertyQuery#getSingleResult() */ @Test public void testSingleResult() { PropertyQuery q = PropertyQueries. createQuery(Person.class); q.addCriteria(new NamedPropertyCriteria("name")); Property p = q.getSingleResult(); assertNotNull(p); Person o = new Person(); o.setName("Trap"); assertEquals("Trap", p.getValue(o)); } public static class Person { private String name; private String title; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/spi/CdiQuerySpiTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.spi; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertNotNull; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.MyEntityRepository; import org.apache.deltaspike.data.test.service.MyEntityRepositoryDelegate; import org.apache.deltaspike.data.test.service.MySimpleRepository; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; @Category(WebProfileCategory.class) public class CdiQuerySpiTest extends TransactionalTestCase { @Deployment public static Archive deployment() { return initDeployment() .addClasses(MySimpleRepository.class, MyEntityRepository.class, MyEntityRepositoryDelegate.class) .addPackage(Simple.class.getPackage()); } @Inject private MySimpleRepository repo; @Test public void should_call_delegate() { // given Simple simple = new Simple("test_call_delegate"); // when simple = repo.saveAndFlushAndRefresh(simple); // then assertNotNull(simple.getId()); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/tx/TransactionalQueryRunnerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.tx; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import jakarta.inject.Inject; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.service.ExtendedRepositoryInterface; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.junit.InSequence; import org.jboss.shrinkwrap.api.Archive; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @Category(WebProfileCategory.class) @RunWith(Arquillian.class) public class TransactionalQueryRunnerTest { private static final String NAME = "should_run_in_transaction"; @Deployment public static Archive deployment() { return initDeployment(true, false) .addClasses(ExtendedRepositoryInterface.class) .addClass(TransactionalQueryRunnerWrapper.class) .addPackage(Simple.class.getPackage()); } @Inject private ExtendedRepositoryInterface repository; @Inject private TransactionalQueryRunnerWrapper wrapper; @Test @InSequence(1) public void should_run_modifying_in_transaction() throws Exception { // when repository.deleteAll(); // then assertTrue(wrapper.isRunInTx()); } @Test @InSequence(2) public void should_save_in_transaction() throws Exception { // given Simple simple = new Simple(NAME); // when simple = repository.save(simple); // then assertNotNull(simple.getId()); assertTrue(wrapper.isRunInTx()); } @Test @InSequence(3) public void should_find_with_lockmode_in_transaction() throws Exception { // when Simple simple = repository.findByName(NAME); // then assertNotNull(simple); assertTrue(wrapper.isRunInTx()); } @Test @InSequence(4) public void should_find_no_lock_without_transaction() throws Exception { // when Simple simple = repository.findByNameNoLock(NAME); // then assertNotNull(simple); assertTrue(wrapper.isRunInNonTx()); } @Test @InSequence(10) public void should_cleanup() throws Exception { repository.deleteAll(); } @Before public void init() { wrapper.reset(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/tx/TransactionalQueryRunnerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.tx; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; import org.apache.deltaspike.data.impl.builder.QueryBuilder; import org.apache.deltaspike.data.impl.handler.CdiQueryInvocationContext; @Specializes @ApplicationScoped public class TransactionalQueryRunnerWrapper extends TransactionalQueryRunner { private boolean runInTx = false; private boolean runInNonTx = false; public void reset() { runInTx = false; runInNonTx = false; } @Override protected Object executeNonTransactional(QueryBuilder builder, CdiQueryInvocationContext context) { runInNonTx = true; return super.executeNonTransactional(builder, context); } @Override protected Object executeTransactional(QueryBuilder builder, CdiQueryInvocationContext context) throws Exception { runInTx = true; return super.executeTransactional(builder, context); } public boolean isRunInTx() { return runInTx; } public boolean isRunInNonTx() { return runInNonTx; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/EntityUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util; import java.io.Serializable; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Tee; import org.apache.deltaspike.data.test.domain.Tee2; import org.apache.deltaspike.data.test.domain.TeeId; import org.junit.Assert; import org.junit.Test; public class EntityUtilsTest { @Test public void should_find_id_property_class() { // given // when Class pkClass = EntityUtils.primaryKeyClass(Tee.class); // then Assert.assertEquals(TeeId.class, pkClass); } @Test public void should_find_id_class() { // given // when Class pkClass = EntityUtils.primaryKeyClass(Tee2.class); // then Assert.assertEquals(TeeId.class, pkClass); } @Test public void should_accept_entity_class() { // given // when boolean isValid = EntityUtils.isEntityClass(Simple.class); // then Assert.assertTrue(isValid); } @Test public void should_not_accept_class_without_entity_annotation() { // given // when boolean isValid = EntityUtils.isEntityClass(EntityWithoutId.class); // then Assert.assertFalse(isValid); } private static class EntityWithoutId { } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/impl/util/jpa/QueryStringExtractorFactoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.impl.util.jpa; import static java.lang.Thread.currentThread; import static java.lang.reflect.Proxy.newProxyInstance; import static org.apache.deltaspike.data.test.util.TestDeployments.initDeployment; import static org.junit.Assert.assertEquals; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import jakarta.inject.Inject; import jakarta.persistence.PersistenceException; import jakarta.persistence.Query; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class QueryStringExtractorFactoryTest { private static final String QUERY_STRING = "it works"; @Inject private QueryStringExtractorFactory factory; @Deployment public static Archive deployment() { return initDeployment(); } @Test public void should_unwrap_query_even_proxied() { // when String extracted = factory.extract((Query) newProxyInstance(currentThread().getContextClassLoader(), new Class[] { Query.class }, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("toString")) { return "Unknown provider wrapper for tests."; } if (method.getName().equals("unwrap")) { Class clazz = (Class) args[0]; if (clazz.getName().contains("hibernate") || clazz.getName().contains("openjpa") || clazz.getName().contains("eclipse")) { return createProxy(clazz); } else { throw new PersistenceException("Unable to unwrap for " + clazz); } } return null; } }) ); // then assertEquals(QUERY_STRING, extracted); } private static Object createProxy(Class forClass) { return Proxy.newProxyInstance(currentThread().getContextClassLoader(), new Class[] { forClass }, new FakeQueryInvocationHandler()); } private static Object createInstance(Method method) throws Exception { // EclipseLink specific Class returnType = Class.forName("org.eclipse.persistence.queries.DataReadQuery"); Object instance = returnType.newInstance(); Method setter = returnType.getMethod("setJPQLString", String.class); setter.invoke(instance, QUERY_STRING); return instance; } private static class FakeQueryInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!method.getReturnType().equals(String.class)) { if (method.getReturnType().isInterface()) { return createProxy(method.getReturnType()); } return createInstance(method); } return QUERY_STRING; // we don't care of the result actually } } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/BMTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test; import jakarta.annotation.Priority; import jakarta.enterprise.inject.Alternative; import jakarta.interceptor.Interceptor; import org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy; import org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy; @Alternative @Priority(Interceptor.Priority.APPLICATION+1) public class BMTransactionStrategy extends BeanManagedUserTransactionStrategy { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/JpaTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test; import jakarta.annotation.Priority; import jakarta.enterprise.inject.Alternative; import jakarta.interceptor.Interceptor; import org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy; @Alternative @Priority(Interceptor.Priority.APPLICATION+1) public class JpaTransactionStrategy extends ContainerManagedTransactionStrategy { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/TestTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test; import jakarta.annotation.Priority; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.interceptor.Interceptor; import org.apache.deltaspike.jpa.impl.transaction.ResourceLocalTransactionStrategy; @Dependent @Alternative @Priority(Interceptor.Priority.APPLICATION + 1) public class TestTransactionStrategy extends ResourceLocalTransactionStrategy { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/TransactionalTestCase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test; import jakarta.annotation.Resource; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.transaction.UserTransaction; import org.apache.deltaspike.data.test.util.TestData; import org.jboss.arquillian.junit.Arquillian; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public abstract class TransactionalTestCase { @Resource protected UserTransaction ut; protected TestData testData; @Before public void startTransaction() throws Exception { ut.begin(); // Required by OpenJPA getEntityManager().getMetamodel(); } @Before public void initTestData() { testData = new TestData(getEntityManager()); } @After public void rollbackTransaction() throws Exception { ut.rollback(); } @Inject private EntityManager entityManager; protected EntityManager getEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/AuditedEntity.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import java.io.Serializable; import java.sql.Timestamp; import java.util.Calendar; import jakarta.persistence.CascadeType; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.ManyToOne; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; import org.apache.deltaspike.data.api.audit.CreatedBy; import org.apache.deltaspike.data.api.audit.CreatedOn; import org.apache.deltaspike.data.api.audit.ModifiedBy; import org.apache.deltaspike.data.api.audit.ModifiedOn; @Entity @SuppressWarnings("serial") public class AuditedEntity implements Serializable { @Id @GeneratedValue private Long id; @Temporal(TemporalType.TIMESTAMP) @CreatedOn private Calendar created; private String name; @CreatedBy private String creator; @CreatedBy @ManyToOne(targetEntity = Principal.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Principal creatorPrincipal; @ModifiedBy private String changer; @ModifiedBy @ManyToOne(targetEntity = Principal.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Principal principal; @ModifiedBy(onCreate = false) private String changerOnly; @ModifiedBy(onCreate = false) @ManyToOne(targetEntity = Principal.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Principal changerOnlyPrincipal; @Temporal(TemporalType.TIME) @ModifiedOn(onCreate = true) private java.util.Date modified; @Temporal(TemporalType.DATE) @ModifiedOn private Calendar gregorianModified; @ModifiedOn private Timestamp timestamp; public AuditedEntity() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Calendar getCreated() { return created; } public java.util.Date getModified() { return modified; } public Calendar getGregorianModified() { return gregorianModified; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Timestamp getTimestamp() { return timestamp; } public String getChanger() { return changer; } public void setChanger(String changer) { this.changer = changer; } public Principal getPrincipal() { return principal; } public String getCreator() { return creator; } public Principal getCreatorPrincipal() { return creatorPrincipal; } public String getChangerOnly() { return changerOnly; } public Principal getChangerOnlyPrincipal() { return changerOnlyPrincipal; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/EmbeddedSimple.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Embeddable; @Embeddable public class EmbeddedSimple { private String embedd; public String getEmbedd() { return embedd; } public void setEmbedd(String embedd) { this.embedd = embedd; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Home.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Home { @Id @GeneratedValue private Long id; private String name; public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/NamedEntity.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; @MappedSuperclass public class NamedEntity { @Id @GeneratedValue private Long id; private String name; public NamedEntity() { } public NamedEntity(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/OneToMany.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; @Entity public class OneToMany extends NamedEntity { public OneToMany() { super(); } public OneToMany(String name) { super(name); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/OneToOne.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; @Entity public class OneToOne extends NamedEntity { public OneToOne() { super(); } public OneToOne(String name) { super(name); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Parent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import java.util.LinkedList; import java.util.List; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; @Entity public class Parent extends NamedEntity { @jakarta.persistence.OneToOne(cascade = CascadeType.ALL) private OneToOne one; @jakarta.persistence.OneToMany(cascade = CascadeType.ALL, targetEntity = OneToMany.class) private List many = new LinkedList(); @Column(name = "p_value") private Long value = Long.valueOf(0); public Parent() { super(); } public Parent(String name) { super(name); } @Override public String toString() { return "Parent [value=" + value + ", getName()=" + getName() + ", getId()=" + getId() + "]"; } public void add(OneToMany otm) { many.add(otm); } public OneToOne getOne() { return one; } public void setOne(OneToOne one) { this.one = one; } public List getMany() { return many; } public void setMany(List many) { this.many = many; } public Long getValue() { return value; } public void setValue(Long value) { this.value = value; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Principal.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Principal { @Id @GeneratedValue private Long id; private String name; public Principal() { } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Principal [id=").append(id) .append(", name=").append(name).append("]"); return builder.toString(); } public Principal(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Simple.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import java.util.Date; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.NamedQueries; import jakarta.persistence.NamedQuery; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; @Entity @NamedQueries({ @NamedQuery(name = Simple.BY_NAME_LIKE, query = "select e from Simple e where e.name like ?1"), @NamedQuery(name = Simple.BY_NAME_ENABLED, query = "select s from Simple s where s.name = ?1 and s.enabled = ?2 order by s.id asc"), @NamedQuery(name = Simple.BY_ID, query = "select s from Simple s where s.id = :id and s.enabled = :enabled") }) @Table(name = "SIMPLE_TABLE") public class Simple extends SuperSimple { public static final String BY_NAME_LIKE = "simple.byNameLike"; public static final String BY_NAME_ENABLED = "simple.byNameAndEnabled"; public static final String BY_ID = "simple.byId"; @Id @GeneratedValue private Long id; private String name; private String camelCase; private Boolean enabled = Boolean.TRUE; private Integer counter = Integer.valueOf(0); @Temporal(TemporalType.TIMESTAMP) private Date temporal; private EmbeddedSimple embedded; protected Simple() { } public Simple(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Boolean getEnabled() { return enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public Integer getCounter() { return counter; } public void setCounter(Integer counter) { this.counter = counter; } public String getCamelCase() { return camelCase; } public void setCamelCase(String camelCase) { this.camelCase = camelCase; } public Date getTemporal() { return temporal; } public void setTemporal(Date temporal) { this.temporal = temporal; } public EmbeddedSimple getEmbedded() { return embedded; } public void setEmbedded(EmbeddedSimple embedded) { this.embedded = embedded; } @Override public String toString() { return "Simple [id=" + id + ", name=" + name + ", camelCase=" + camelCase + ", enabled=" + enabled + ", counter=" + counter + ", temporal=" + temporal + ", embedded=" + embedded + "]"; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Simple2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Simple2 { @Id @GeneratedValue private Long id; private String name; public Simple2() { } public Simple2(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Simple3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity public class Simple3 { @GeneratedValue @Id private long id; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getId() { return id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Simple4.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity(name = "EntitySimple4") public class Simple4 { @GeneratedValue @Id private long id; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getId() { return id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Simple5.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; @Entity(name = "EntitySimple5") public class Simple5 extends SimpleBase { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/SimpleBase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; @MappedSuperclass public class SimpleBase { @GeneratedValue @Id private long id; private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public long getId() { return id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/SimpleBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.EntityManager; public class SimpleBuilder { private final EntityManager entityManager; public SimpleBuilder(EntityManager entityManager) { this.entityManager = entityManager; } public Simple createSimple(String name, Integer counter) { Simple result = new Simple(name); result.setCounter(counter); return persistSimple(result); } public Simple createSimple(String name) { Simple result = new Simple(name); return persistSimple(result); } public Simple persistSimple(Simple result) { entityManager.persist(result); entityManager.flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/SimpleStringId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.*; @Entity @NamedQueries({ @NamedQuery(name = SimpleStringId.FIND_ALL_ORDER_BY_ID, query = "SELECT e FROM SimpleStringId e ORDER BY e.id") }) @Table(name = "SIMPLE_TABLE_STRING") public class SimpleStringId extends SuperSimple { public static final String FIND_ALL_ORDER_BY_ID = "SimpleStringId.findAllOrderById"; @Id private String id; private String name; public SimpleStringId() { } public SimpleStringId(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Simple [id=" + id + ", name=" + name + "]"; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/SimpleStringIdBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.EntityManager; public class SimpleStringIdBuilder { private final EntityManager entityManager; public SimpleStringIdBuilder(EntityManager entityManager) { this.entityManager = entityManager; } public SimpleStringId createSimple(String id, String name) { SimpleStringId result = new SimpleStringId(id, name); return persistSimple(result); } public SimpleStringId persistSimple(SimpleStringId result) { entityManager.persist(result); entityManager.flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/SuperSimple.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.MappedSuperclass; @MappedSuperclass public class SuperSimple { private String superName; public String getSuperName() { return superName; } public void setSuperName(String superName) { this.superName = superName; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Tee.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import java.io.Serializable; import jakarta.persistence.EmbeddedId; import jakarta.persistence.Entity; @Entity @SuppressWarnings("serial") public class Tee implements Serializable { @EmbeddedId private TeeId id; private int distance; public TeeId getId() { return id; } public void setId(TeeId id) { this.id = id; } public int getDistance() { return distance; } public void setDistance(int distance) { this.distance = distance; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/Tee2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.IdClass; @IdClass(TeeId.class) @Entity public class Tee2 { @Column(nullable = false) @Id private Long teeSetId; @Column(nullable = false) @Id private Long holeId; public long getTeeSetId() { return teeSetId; } public void setTeeSetId(long teeSetId) { this.teeSetId = teeSetId; } public long getHoleId() { return holeId; } public void setHoleId(long holeId) { this.holeId = holeId; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/TeeId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain; import java.io.Serializable; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @Embeddable @SuppressWarnings("serial") public class TeeId implements Serializable { @Column(nullable = false) private Long teeSetId; @Column(nullable = false) private Long holeId; public TeeId() { } public TeeId(long teeSetId, long holeId) { this.teeSetId = teeSetId; this.holeId = holeId; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (holeId ^ (holeId >>> 32)); result = prime * result + (int) (teeSetId ^ (teeSetId >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } TeeId other = (TeeId) obj; if (holeId != other.holeId) { return false; } if (teeSetId != other.teeSetId) { return false; } return true; } public long getTeeSetId() { return teeSetId; } public void setTeeSetId(long teeSetId) { this.teeSetId = teeSetId; } public long getHoleId() { return holeId; } public void setHoleId(long holeId) { this.holeId = holeId; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/dto/BooleanWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.dto; public class BooleanWrapper { private Boolean wrapped; public BooleanWrapper(Boolean wrapped) { this.wrapped = wrapped; } public Boolean getWrapped() { return wrapped; } public void setWrapped(Boolean wrapped) { this.wrapped = wrapped; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/dto/SimpleDto.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.dto; public class SimpleDto { private SimpleId id; private String name; private Boolean enabled; public SimpleId getId() { return id; } public void setId(SimpleId id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Boolean getEnabled() { return enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/dto/SimpleId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.dto; import java.io.Serializable; public class SimpleId implements Serializable { private static final long serialVersionUID = 1L; private Long id; public SimpleId(Long id) { this.id = id; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/mapped/MappedId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.mapped; public class MappedId { private Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/mapped/MappedOne.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.mapped; public class MappedOne { private Long id; private String name; public MappedOne() { } public MappedOne(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/mapped/MappedSuperclass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.mapped; public class MappedSuperclass extends MappedId { private Long counter; public Long getCounter() { return counter; } public void setCounter(Long id) { this.counter = id; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/mapped/MappedThree.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.mapped; public class MappedThree extends MappedSuperclass { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/domain/mapped/MappedTwo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.domain.mapped; public class MappedTwo { private Long teeSetId; private Long holeId; private String name; public Long getTeeSetId() { return teeSetId; } public void setTeeSetId(Long teeSetId) { this.teeSetId = teeSetId; } public Long getHoleId() { return holeId; } public void setHoleId(Long holeId) { this.holeId = holeId; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/entity/Simple.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.entity; import java.util.Date; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.NamedQueries; import jakarta.persistence.NamedQuery; import jakarta.persistence.Table; import jakarta.persistence.Temporal; import jakarta.persistence.TemporalType; @Entity @NamedQueries({ @NamedQuery(name = Simple.BY_NAME_LIKE, query = "select e from Simple e where e.name like ?1"), @NamedQuery(name = Simple.BY_NAME_ENABLED, query = "select s from Simple s where s.name = ?1 and s.enabled = ?2 order by s.id asc"), @NamedQuery(name = Simple.BY_ID, query = "select s from Simple s where s.id = :id and s.enabled = :enabled") }) @Table(name = "SIMPLE_TABLE") public class Simple { public static final String BY_NAME_LIKE = "simple.byNameLike"; public static final String BY_NAME_ENABLED = "simple.byNameAndEnabled"; public static final String BY_ID = "simple.byId"; private static final long serialVersionUID = 1L; @Id @GeneratedValue private Long id; private String name; private String camelCase; private Boolean enabled = Boolean.TRUE; private Integer counter = Integer.valueOf(0); @Temporal(TemporalType.TIMESTAMP) private Date temporal; protected Simple() { } public Simple(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Boolean getEnabled() { return enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public Integer getCounter() { return counter; } public void setCounter(Integer counter) { this.counter = counter; } public String getCamelCase() { return camelCase; } public void setCamelCase(String camelCase) { this.camelCase = camelCase; } public Date getTemporal() { return temporal; } public void setTemporal(Date temporal) { this.temporal = temporal; } @Override public String toString() { return "Simple [id=" + id + ", name=" + name + ", camelCase=" + camelCase + ", enabled=" + enabled + ", counter=" + counter + ", temporal=" + temporal + "]"; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/repo/SimpleRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.repo; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.java8.entity.Simple; import java.util.Optional; import java.util.stream.Stream; @Repository(forEntity = Simple.class) public interface SimpleRepository { Stream findByName(String name); Optional findOptionalBy(Long id); Stream findAll(); Optional findBy(Long id); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/repo/SimpleRepository2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.repo; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.SingleResultType; import org.apache.deltaspike.data.test.java8.entity.Simple; import java.util.Optional; import java.util.stream.Stream; @Repository(forEntity = Simple.class) public interface SimpleRepository2 { @Query(singleResult = SingleResultType.ANY) Optional findByName(String name); @Query(value = "select name from simple_table", isNative = true) Stream findSimpleNames(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/test/Java8Test.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.test; import org.apache.deltaspike.data.test.java8.entity.Simple; import org.apache.deltaspike.data.test.java8.repo.SimpleRepository; import org.apache.deltaspike.data.test.java8.repo.SimpleRepository2; import org.apache.deltaspike.test.category.WebProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.Archive; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.annotation.Resource; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import jakarta.transaction.UserTransaction; import java.util.Optional; import java.util.stream.Stream; import static java.util.Arrays.asList; import java.util.Collections; import java.util.List; import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; import static org.apache.deltaspike.data.test.java8.util.TestDeployments.initDeployment; @Category(WebProfileCategory.class) @RunWith(Arquillian.class) public class Java8Test { @Deployment public static Archive deployment() { return initDeployment() .addClasses(Java8Test.class, Simple.class, SimpleRepository.class, SimpleRepository2.class); } @Inject private SimpleRepository simpleRepository; @Inject private SimpleRepository2 simpleRepository2; @PersistenceContext private EntityManager entityManager; @Resource private UserTransaction ut; @Before public void setupTX() throws Exception { ut.begin(); } @After public void rollbackTX() throws Exception { ut.rollback(); } @Test public void shouldFindOptionalSimple() throws Exception { Simple s = new Simple("something"); entityManager.persist(s); Optional found = simpleRepository.findOptionalBy(s.getId()); Assert.assertTrue(found.isPresent()); } @Test public void shouldNotFindOptionalSimpleForMissing() throws Exception { Optional found = simpleRepository.findBy(-1L); Assert.assertFalse(found.isPresent()); } @Test public void shouldFindStreamOfSimples() { String name = "something"; Simple s = new Simple(name); entityManager.persist(s); Stream found = simpleRepository.findByName(name); Assert.assertEquals(1, found.count()); } @Test public void shouldFindEmptyStream() { String name = "something"; Simple s = new Simple(name); entityManager.persist(s); Stream found = simpleRepository.findByName("some other name"); Assert.assertEquals(emptyList(), found.collect(toList())); } @Test public void shouldFindAllAsStream() { String name = "something"; Simple s = new Simple(name); entityManager.persist(s); Stream found = simpleRepository.findAll(); Assert.assertEquals(1, found.count()); } @Test public void shouldFindByNameOptional() { String name = "jim"; entityManager.persist(new Simple(name)); entityManager.persist(new Simple(name)); Optional found = simpleRepository2.findByName(name); Assert.assertTrue(found.isPresent()); } @Test public void shouldFindNamesAsStream() { entityManager.persist(new Simple("a")); entityManager.persist(new Simple("b")); entityManager.flush(); Stream names = simpleRepository2.findSimpleNames(); final List actualSorted = names.collect(toList()); Collections.sort(actualSorted); Assert.assertEquals(asList("a","b"), actualSorted); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/util/EntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.util; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; public class EntityManagerProducer { @PersistenceContext @Produces private EntityManager entityManager; } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/java8/util/TestDeployments.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.java8.util; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import java.io.File; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; public class TestDeployments { /** * Create a basic deployment with dependencies, beans.xml and persistence descriptor. * * @return Basic web archive. */ public static WebArchive initDeployment() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "test.war") .addAsLibraries(getDeltaSpikeDataWithDependencies()) .addClasses(EntityManagerProducer.class) .addAsWebInfResource("test-persistence.xml", "classes/META-INF/persistence.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } private static File[] getDeltaSpikeDataWithDependencies() { return Maven.resolver().loadPomFromFile("pom.xml").resolve( "org.apache.deltaspike.core:deltaspike-core-api", "org.apache.deltaspike.core:deltaspike-core-impl", "org.apache.deltaspike.modules:deltaspike-partial-bean-module-api", "org.apache.deltaspike.modules:deltaspike-partial-bean-module-impl", "org.apache.deltaspike.modules:deltaspike-jpa-module-api", "org.apache.deltaspike.modules:deltaspike-jpa-module-impl", "org.apache.deltaspike.modules:deltaspike-data-module-api", "org.apache.deltaspike.modules:deltaspike-data-module-impl") .withTransitivity() .asFile(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/BaseRepositoryInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityManagerDelegate; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository public interface BaseRepositoryInterface extends EntityRepository, EntityManagerDelegate { Simple findByName( String name ); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/BasicEntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityManagerResolver; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; public class BasicEntityManagerResolver implements EntityManagerResolver { @Inject private EntityManager entityManager; @Override public EntityManager resolveEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/DisabledRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository(forEntity = Simple.class) public interface DisabledRepository extends EntityRepository, Deactivatable { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryAbstract.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository public abstract class ExtendedRepositoryAbstract extends AbstractEntityRepository { public String getTableName() { return tableName(); } public String getEntityName() { return entityName(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryAbstract2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple2; @Repository public abstract class ExtendedRepositoryAbstract2 extends AbstractEntityRepository { public String getTableName() { return tableName(); } public String getEntityName() { return entityName(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryAbstract4.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple4; @Repository public abstract class ExtendedRepositoryAbstract4 extends AbstractEntityRepository { public String getEntityName() { return entityName(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryAbstractInherited.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple5; @Repository public abstract class ExtendedRepositoryAbstractInherited extends ExtendedRepositoryAbstractIntermediate { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryAbstractIntermediate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.io.Serializable; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.SingleResultType; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.SimpleBase; @Repository public abstract class ExtendedRepositoryAbstractIntermediate extends AbstractEntityRepository { public String getTableName() { return tableName(); } public String getEntityName() { return entityName(); } @Query(singleResult = SingleResultType.OPTIONAL) public abstract E findByIdAndName(Long id, String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.*; import org.apache.deltaspike.data.test.domain.Simple; import static jakarta.persistence.LockModeType.PESSIMISTIC_READ; @Repository public interface ExtendedRepositoryInterface extends EntityRepository, EntityManagerDelegate { @Query(lock = PESSIMISTIC_READ) Simple findByName(String name); @Query(named = Simple.BY_NAME_LIKE) Simple findByNameNoLock(String name); @Modifying @Query("delete from Simple") int deleteAll(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ExtendedRepositoryInterface2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; @Repository public interface ExtendedRepositoryInterface2 extends BaseRepositoryInterface { @Modifying @Query( "delete from Simple") int deleteAll(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/FullRepositoryAbstract.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractFullEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple_; @Repository public abstract class FullRepositoryAbstract extends AbstractFullEntityRepository { public String getTableName() { return tableName(); } public String getEntityName() { return entityName(); } public Simple fetchByName(String name) { return criteria().eq(Simple_.name, name).getOptionalResult(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/FullRepositoryInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import static jakarta.persistence.LockModeType.PESSIMISTIC_READ; import org.apache.deltaspike.data.api.FullEntityRepository; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository public interface FullRepositoryInterface extends FullEntityRepository { @Query(lock = PESSIMISTIC_READ) Simple findByName(String name); @Query(named = Simple.BY_NAME_LIKE) Simple findByNameNoLock(String name); @Modifying @Query("delete from Simple") int deleteAll(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/HomeRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.test.domain.Home; public abstract class HomeRepository extends AbstractEntityRepository { public abstract QueryResult findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/LegacyRepositoryWithEntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.EntityManagerConfig; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import java.util.List; @Repository @EntityManagerConfig(entityManagerResolver = BasicEntityManagerResolver.class) public abstract class LegacyRepositoryWithEntityManagerResolver extends AbstractEntityRepository { public abstract List findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/MappedOneRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.mapped.MappedOne; @Repository public abstract class MappedOneRepository extends AbstractEntityRepository { public abstract MappedOne findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/MyEntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; public interface MyEntityRepository { E saveAndFlushAndRefresh(E entity); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/MyEntityRepositoryDelegate.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import org.apache.deltaspike.data.spi.DelegateQueryHandler; import org.apache.deltaspike.data.spi.QueryInvocationContext; @Dependent public class MyEntityRepositoryDelegate implements DelegateQueryHandler, MyEntityRepository { @Inject private QueryInvocationContext context; @Override public E saveAndFlushAndRefresh(E entity) { entityManager().persist(entity); entityManager().flush(); entityManager().refresh(entity); return entity; } private EntityManager entityManager() { return context.getEntityManager(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/MySimpleRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository public interface MySimpleRepository extends MyEntityRepository, EntityRepository { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/ParentRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import jakarta.persistence.criteria.JoinType; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.criteria.CriteriaSupport; import org.apache.deltaspike.data.test.domain.OneToMany; import org.apache.deltaspike.data.test.domain.OneToMany_; import org.apache.deltaspike.data.test.domain.OneToOne; import org.apache.deltaspike.data.test.domain.OneToOne_; import org.apache.deltaspike.data.test.domain.Parent; import org.apache.deltaspike.data.test.domain.Parent_; @Repository public abstract class ParentRepository extends AbstractEntityRepository implements CriteriaSupport { public List joinQuery(String name, String oneName, String manyName) { return criteria() .eq(Parent_.name, name) .join(Parent_.one, where(OneToOne.class, JoinType.LEFT) .eq(OneToOne_.name, oneName) ) .join(Parent_.many, where(OneToMany.class) .eq(OneToMany_.name, manyName) ) .createQuery() .getResultList(); } public List nullAwareQuery(String name1, String name2, Long counter) { return criteria() .eq(Parent_.name, name1) .eq(Parent_.name, name2) .eq(Parent_.value, counter) .createQuery() .getResultList(); } public Parent fetchQuery(String name) { return criteria() .eq(Parent_.name, name) .fetch(Parent_.many) .distinct() .createQuery() .getSingleResult(); } public List fetchByName(String name1, String name2, String name3) { return criteria() .in(Parent_.name, name1, name2, name3) .createQuery() .getResultList(); } @SuppressWarnings("unchecked") public List orQuery(String name1, String name2) { return criteria() .or( criteria() .eq(Parent_.name, name2) .between(Parent_.value, 50L, 100L), criteria() .eq(Parent_.name, name1) .between(Parent_.value, 0L, 50L), criteria() .eq(Parent_.name, "does not exist!") ) .createQuery() .getResultList(); } public List orderedQuery() { return criteria() .orderAsc(Parent_.name) .createQuery() .getResultList(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/RepositoryInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository(forEntity = Simple.class) public interface RepositoryInterface { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/Simple2Repository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple2; @Repository public interface Simple2Repository extends EntityRepository { Simple2 findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleCriteriaRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.Date; import java.util.List; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.criteria.CriteriaSupport; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.Simple_; import org.apache.deltaspike.data.test.domain.SuperSimple_; import jakarta.persistence.criteria.CriteriaBuilder; @Repository @SuppressWarnings("unchecked") public abstract class SimpleCriteriaRepository extends AbstractEntityRepository implements CriteriaSupport { public List queryByCriteria(String name, Boolean enabled, Integer from, Integer to) { return criteria() .eq(Simple_.name, name) .eq(Simple_.enabled, enabled) .between(Simple_.counter, from, to) .getResultList(); } public List queryByIgnoreCase(String name, String nameLike) { return criteria() .or( criteria() .eqIgnoreCase(Simple_.name, name) .notEqIgnoreCase(Simple_.name, nameLike), criteria() .likeIgnoreCase(Simple_.name, nameLike) .notLikeIgnoreCase(Simple_.name, name) ) .getResultList(); } public Simple queryOptional(String name) { return criteria() .eq(Simple_.name, name) .getOptionalResult(); } public Simple queryAny(String name) { return criteria() .eq(Simple_.name, name) .getAnyResult(); } public List findByTimeBetween(Date from, Date to) { return criteria() .gt(Simple_.temporal, from) .lt(Simple_.temporal, to) .getResultList(); } public Simple findBySuperName(String superName) { return criteria() .eq(SuperSimple_.superName, superName) .getSingleResult(); } public Long criteriaCount(String name) { return criteria() .select(Long.class, countDistinct(Simple_.name)) .eq(Simple_.name, name) .getSingleResult(); } public Statistics queryWithSelect(String name) { return criteria() .select(Statistics.class, avg(Simple_.counter), count(Simple_.counter)) .eq(Simple_.name, name) .getSingleResult(); } public Object[] queryWithSelectAggregateReturnArray(String name) { return criteria() .select(min(Simple_.counter), max(Simple_.counter), currDate(), currTime(), currTStamp()) .eq(Simple_.name, name) .createQuery() .getSingleResult(); } public List queryWithSelectAttributes(String name) { return criteria() .select(attribute(Simple_.name), upper(Simple_.name), lower(Simple_.name), substring(Simple_.name, 2), substring(Simple_.name, 2, 2)) .eq(Simple_.name, name) .createQuery() .getResultList(); } public List findOrderByNameAndCounter() { return criteria() .orderDesc(Simple_.counter) .orderAsc(Simple_.name) .getResultList(); } public Object[] queryWithSelectAttributesAndTrim(String name) { return criteria() .select(attribute(Simple_.name), trim(Simple_.name), trim(CriteriaBuilder.Trimspec.LEADING, Simple_.name)) .eq(Simple_.name, name) .createQuery() .getSingleResult(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleFetchRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository(methodPrefix = "fetchBy") public abstract class SimpleFetchRepository extends AbstractEntityRepository { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleIntermediateRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import jakarta.persistence.QueryHint; import java.util.List; @Repository public interface SimpleIntermediateRepository extends EntityRepository { @Query(hints = { @QueryHint(name = "openjpa.hint.OptimizeResultCount", value = "some.invalid.value"), @QueryHint(name = "org.hibernate.comment", value = "I'm a little comment short and stout") }) Simple findBy(Long id); @Query(value = "select name from simple_table", isNative = true) List findAllNames(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleMappedDtoRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.mapping.MappingConfig; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.dto.SimpleDto; import org.apache.deltaspike.data.test.domain.dto.SimpleId; @Repository(forEntity = Simple.class) @MappingConfig(SimpleQueryInOutMapper.class) public interface SimpleMappedDtoRepository extends EntityRepository { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleMappedRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.api.mapping.MappingConfig; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.dto.BooleanWrapper; import org.apache.deltaspike.data.test.domain.dto.SimpleDto; import org.apache.deltaspike.data.test.domain.dto.SimpleId; @Repository(forEntity = Simple.class) @MappingConfig(SimpleMapper.class) public interface SimpleMappedRepository extends EntityRepository { SimpleDto findByName(String name); List findByEnabled(Boolean enabled); @MappingConfig(WrappedMapper.class) List findByEnabled(BooleanWrapper enabled); @Query("select e from Simple e where e.name = ?1") QueryResult findByNameToo(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleMapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.ArrayList; import java.util.List; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.dto.SimpleDto; import org.apache.deltaspike.data.test.domain.dto.SimpleId; public class SimpleMapper implements QueryInOutMapper { @Override public Object mapResult(Simple result) { SimpleDto dto = new SimpleDto(); dto.setId(new SimpleId(result.getId())); dto.setName(result.getName()); dto.setEnabled(result.getEnabled()); return dto; } @Override public Object mapResultList(List result) { List dtos = new ArrayList(result.size()); for (Simple simple : result) { dtos.add((SimpleDto) mapResult(simple)); } return dtos; } @Override public boolean mapsParameter(Object parameter) { return parameter != null && ( parameter instanceof SimpleDto || parameter instanceof SimpleId); } @Override public Object mapParameter(Object parameter) { if (parameter instanceof SimpleDto) { SimpleDto dto = (SimpleDto) parameter; Simple simple = new Simple(dto.getName()); simple.setId(dto.getId() != null ? dto.getId().getId() : null); simple.setEnabled(dto.getEnabled()); return simple; } return ((SimpleId) parameter).getId(); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleQueryInOutMapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.mapping.SimpleQueryInOutMapperBase; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.dto.SimpleDto; import org.apache.deltaspike.data.test.domain.dto.SimpleId; public class SimpleQueryInOutMapper extends SimpleQueryInOutMapperBase { @Override protected Object getPrimaryKey(SimpleDto dto) { return dto.getId() != null ? dto.getId().getId() : null; } @Override protected SimpleDto toDto(Simple entity) { SimpleDto dto = new SimpleDto(); dto.setId(new SimpleId(entity.getId())); dto.setEnabled(entity.getEnabled()); dto.setName(entity.getName()); return dto; } @Override protected Simple toEntity(Simple entity, SimpleDto dto) { entity.setName(dto.getName()); entity.setEnabled(dto.getEnabled()); return entity; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import static jakarta.persistence.LockModeType.PESSIMISTIC_WRITE; import static org.apache.deltaspike.data.api.SingleResultType.ANY; import static org.apache.deltaspike.data.api.SingleResultType.OPTIONAL; import java.util.List; import jakarta.persistence.EntityManager; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.FirstResult; import org.apache.deltaspike.data.api.MaxResults; import org.apache.deltaspike.data.api.Modifying; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.QueryParam; import org.apache.deltaspike.data.api.QueryResult; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.SimpleStringId; @Repository public abstract class SimpleRepository extends AbstractEntityRepository { public List implementedQueryByName(String name) { String query = "select s from Simple s where s.name = :name"; return typedQuery(query) .setParameter("name", name) .getResultList(); } @Query(named = Simple.BY_NAME_ENABLED, max = 1) public abstract List findByNamedQueryIndexed(String name, Boolean enabled); @Query(named = Simple.BY_NAME_LIKE, singleResult = OPTIONAL) public abstract Simple findByNameOptional(String name); @Query(named = Simple.BY_NAME_LIKE, singleResult = ANY) public abstract Simple findByNameAny(String name); @Query(named = Simple.BY_NAME_ENABLED) public abstract List findByNamedQueryRestricted(String name, Boolean enabled, @MaxResults int max, @FirstResult Integer first); @Query(named = Simple.BY_ID, lock = PESSIMISTIC_WRITE) public abstract Simple findByNamedQueryNamed( @QueryParam("id") Long id, @QueryParam("enabled") Boolean enabled); @Query("select s from Simple s where s.name = ?1") public abstract Simple findByQuery(String name); @Query("select count(s) from Simple s where s.name = ?1") public abstract Long findCountByQuery(String name); @Query("select s from Simple s where s.name = ?1 order by s.counter desc") public abstract QueryResult findByQueryWithOrderBy(String name); public abstract Simple findByNameAndEnabled(String name, Boolean enabled); public abstract Simple findByNameLikeIgnoreCase(String name); public abstract Simple findByNameIgnoreCase(String name); public abstract Simple findOptionalByName(String name); public abstract Simple findAnyByName(String name); public abstract List findFirst2ByName(String name); public abstract List findTop2ByName(String name); public abstract List findFirst3OrderByName(); public abstract List findAllOrderByName(); public abstract long countByName(String name); public abstract List findByOrderByCounterAscIdDesc(); @Query(value = "SELECT * from SIMPLE_TABLE s WHERE s.name = ?1", isNative = true) public abstract List findWithNative(String name); @Modifying @Query("update Simple as s set s.name = ?1 where s.id = ?2") public abstract int updateNameForId(String name, Long id); @Query(named = Simple.BY_NAME_LIKE) public abstract QueryResult queryResultWithNamed(String name); @Query("select s from Simple s") public abstract QueryResult queryAll(); public abstract QueryResult findByName(String name); @Query(named = SimpleStringId.FIND_ALL_ORDER_BY_ID) public abstract QueryResult findAllOrderByIdPaginate(@FirstResult int start, @MaxResults int pageSize); public abstract void deleteByName(String name); public abstract void removeByName(String name); public abstract void deleteByNameAndEnabled(String name, boolean enable); public abstract void removeByNameAndEnabled(String name, Boolean aTrue); @Override protected abstract EntityManager entityManager(); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepositoryWithEntityManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; @Repository public interface SimpleRepositoryWithEntityManager extends EntityRepository { List findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleRepositoryWithEntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import org.apache.deltaspike.data.api.AbstractEntityRepository; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; @Repository @EntityManagerConfig(entityManagerResolver = SimplisticEntityManagerResolver.class) public abstract class SimpleRepositoryWithEntityManagerResolver extends AbstractEntityRepository { public abstract List findByName(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimpleStringIdRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import org.apache.deltaspike.data.api.EntityRepository; import org.apache.deltaspike.data.api.Query; import org.apache.deltaspike.data.api.Repository; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.SimpleStringId; @Repository public interface SimpleStringIdRepository extends EntityRepository { @Query("SELECT s FROM Simple s WHERE s.name = ?1") Simple findByName(String name); @Query("SELECT s FROM Simple s WHERE s.name = ?1") List findByName2(String name); } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/Simplistic.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; 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 static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import jakarta.inject.Qualifier; @Qualifier @Target({ TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented public @interface Simplistic { } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/SimplisticEntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import org.apache.deltaspike.data.api.EntityManagerResolver; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; public class SimplisticEntityManagerResolver implements EntityManagerResolver { @Inject @Simplistic private EntityManager entityManager; @Override public EntityManager resolveEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/Statistics.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; public class Statistics { private final Double average; private final Long count; public Statistics(Double average, Long count) { this.average = average; this.count = count; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Statistics [") .append("average=").append(average) .append(", count=").append(count) .append("]"); return builder.toString(); } public Double getAverage() { return average; } public Long getCount() { return count; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/service/WrappedMapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.service; import java.util.List; import org.apache.deltaspike.data.api.mapping.QueryInOutMapper; import org.apache.deltaspike.data.test.domain.Simple; import org.apache.deltaspike.data.test.domain.dto.BooleanWrapper; public class WrappedMapper implements QueryInOutMapper { private final SimpleMapper delegate = new SimpleMapper(); @Override public boolean mapsParameter(Object parameter) { if (parameter != null && parameter instanceof BooleanWrapper) { return true; } return delegate.mapsParameter(parameter); } @Override public Object mapParameter(Object parameter) { if (parameter instanceof BooleanWrapper) { return ((BooleanWrapper) parameter).getWrapped(); } return delegate.mapParameter(parameter); } @Override public Object mapResult(Simple result) { return delegate.mapResult(result); } @Override public Object mapResultList(List result) { return delegate.mapResultList(result); } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/EntityManagerProducer.java ================================================ /* * Copyright 2016 The Apache Software Foundation. * * 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 org.apache.deltaspike.data.test.util; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; public class EntityManagerProducer { @Produces @PersistenceContext private EntityManager entityManager; } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/Logging.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.util; import java.io.InputStream; import java.util.logging.LogManager; public class Logging { private Logging() { } public static void reconfigure() { try { InputStream loggingProperties = Logging.class.getClassLoader().getResourceAsStream("logging.properties"); LogManager.getLogManager().readConfiguration(loggingProperties); } catch (Exception e) { throw new RuntimeException("Failed to reconfigure Java Logging.", e); } } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.util; import jakarta.persistence.EntityManager; import org.apache.deltaspike.data.test.domain.Simple; public class TestData { private EntityManager entityManager; public TestData(EntityManager entityManager) { this.entityManager = entityManager; } public Simple createSimple(String name) { return createSimple(name, null); } public Simple createSimple(String name, Integer counter) { Simple result = new Simple(name); result.setCounter(counter); entityManager.persist(result); entityManager.flush(); return result; } } ================================================ FILE: deltaspike/modules/data/impl/src/test/java/org/apache/deltaspike/data/test/util/TestDeployments.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.data.test.util; import org.apache.deltaspike.data.test.BMTransactionStrategy; import org.apache.deltaspike.data.test.JpaTransactionStrategy; import org.apache.deltaspike.data.test.TransactionalTestCase; import org.apache.deltaspike.data.test.domain.AuditedEntity; import org.jboss.arquillian.container.test.spi.TestDeployment; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import java.io.File; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; public abstract class TestDeployments { /** * Create a basic deployment with dependencies, beans.xml and persistence descriptor. * * @return Basic web archive. */ public static WebArchive initDeployment() { return initDeployment(true, true); } public static WebArchive initDeployment(boolean addDefaultEntityManagerProducer) { return initDeployment(addDefaultEntityManagerProducer, BEANS_XML_ALL, true); } public static WebArchive initDeployment(boolean addDefaultEntityManagerProducer, boolean jpa) { return initDeployment(addDefaultEntityManagerProducer, BEANS_XML_ALL, jpa); } public static WebArchive initDeployment(boolean addDefaultEntityManagerProducer, Asset beansXmlAsset, boolean jpa) { Logging.reconfigure(); WebArchive archive = ShrinkWrap .create(WebArchive.class, "test.war") // used by many tests, shouldn't interfere with others .addClasses(TransactionalTestCase.class, TestData.class) .addPackages(true, AuditedEntity.class.getPackage()) .addAsLibraries(getDeltaSpikeDataWithDependencies()) .addAsWebInfResource("test-persistence.xml", "classes/META-INF/persistence.xml") .addAsWebInfResource(beansXmlAsset, "beans.xml"); if (addDefaultEntityManagerProducer) { archive.addClass(EntityManagerProducer.class); } if (jpa) { archive.addClass(JpaTransactionStrategy.class); } else { archive.addClass(BMTransactionStrategy.class); } return archive; } public static File[] getDeltaSpikeDataWithDependencies() { return Maven.resolver().loadPomFromFile("pom.xml").resolve( "org.apache.deltaspike.core:deltaspike-core-api", "org.apache.deltaspike.core:deltaspike-core-impl", "org.apache.deltaspike.modules:deltaspike-partial-bean-module-api", "org.apache.deltaspike.modules:deltaspike-partial-bean-module-impl", "org.apache.deltaspike.modules:deltaspike-jpa-module-api", "org.apache.deltaspike.modules:deltaspike-jpa-module-impl", "org.apache.deltaspike.modules:deltaspike-data-module-api", "org.apache.deltaspike.modules:deltaspike-data-module-impl") .withTransitivity() .asFile(); } public static void addToEarManifestIfExists(EnterpriseArchive archive, String resource) { URL url = TestDeployment.class.getClassLoader().getResource(resource); if (url != null) { archive.addAsManifestResource(resource); } } } ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/disabled/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.data.impl.RepositoryDeactivator ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/log4j.xml ================================================ ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/logging.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # handlers=java.util.logging.ConsoleHandler .level=SEVERE java.util.logging.FileHandler.pattern=%h/java%u.log java.util.logging.FileHandler.limit=50000 java.util.logging.FileHandler.count=1 java.util.logging.FileHandler.formatter=java.util.logging.XMLFormatter java.util.logging.ConsoleHandler.level=ALL java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter #org.glassfish.level=SEVERE #com.sun.enterprise.level=INFO ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/test-custom-orm.xml ================================================ org.apache.deltaspike.data.test.domain.mapped ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/test-default-orm.xml ================================================ org.apache.deltaspike.data.test.domain.mapped ================================================ FILE: deltaspike/modules/data/impl/src/test/resources/test-orm.xml ================================================ ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-openejb/test-mapped-persistence.xml ================================================ org.apache.openjpa.persistence.PersistenceProviderImpl testDatabase META-INF/orm.xml META-INF/custom-orm.xml ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-openejb/test-persistence.xml ================================================ org.apache.openjpa.persistence.PersistenceProviderImpl testDatabase ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-payara/test-mapped-persistence.xml ================================================ org.eclipse.persistence.jpa.PersistenceProvider jdbc/__default META-INF/orm.xml META-INF/custom-orm.xml ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-payara/test-persistence.xml ================================================ org.eclipse.persistence.jpa.PersistenceProvider jdbc/__default ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-weblogic/test-mapped-persistence.xml ================================================ org.eclipse.persistence.jpa.PersistenceProvider TestDS META-INF/orm.xml META-INF/custom-orm.xml ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-weblogic/test-persistence.xml ================================================ org.eclipse.persistence.jpa.PersistenceProvider TestDS ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-wildfly/test-mapped-persistence.xml ================================================ java:jboss/datasources/ExampleDS META-INF/orm.xml META-INF/custom-orm.xml ================================================ FILE: deltaspike/modules/data/impl/src/test/resources-wildfly/test-persistence.xml ================================================ java:jboss/datasources/ExampleDS ================================================ FILE: deltaspike/modules/data/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT data-module-project pom Apache DeltaSpike Data-Module api impl 3.2.1 org.jboss.shrinkwrap.resolver shrinkwrap-resolver-bom ${shrinkwrap.version} pom import org.jboss.shrinkwrap.resolver shrinkwrap-resolver-impl-maven ${shrinkwrap.version} test ================================================ FILE: deltaspike/modules/jpa/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules jpa-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-jpa-module-api jar Apache DeltaSpike JPA-Module API org.apache.deltaspike.jpa.* jakarta.persistence.*, jakarta.enterprise.inject, !org.apache.deltaspike.jpa.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.apache.deltaspike.core deltaspike-core-api ${project.version} ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/config/base/JpaBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.config.base; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; public interface JpaBaseConfig extends DeltaSpikeBaseConfig { interface UserTransaction { String JNDI_NAME = ConfigResolver.resolve("deltaspike.jpa.user-transaction.jndi-name") .withCurrentProjectStage(true) .withDefault("java:comp/UserTransaction") .getValue(); Integer TIMEOUT_IN_SECONDS = ConfigResolver.resolve("deltaspike.jpa.user-transaction.timeout_in_seconds") .as(Integer.class) .withCurrentProjectStage(true) .getValue(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.entitymanager; import jakarta.enterprise.inject.Any; import jakarta.persistence.FlushModeType; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Configure the EntityManager for a specific repository. */ @Target( { ElementType.TYPE, ElementType.METHOD } ) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface EntityManagerConfig { /** * References the type which provides the EntityManager for a specific repository. * Must be resolvable over the BeanManager. */ Class entityManagerResolver() default EntityManagerResolver.class; /** * If no entityManagerResolver is specified, then these qualifiers will be used to look up an entity manager * @return */ Class[] qualifier() default Any.class; /** * Set the flush mode for the repository EntityManager. */ FlushModeType flushMode() default FlushModeType.AUTO; } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/EntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.entitymanager; import jakarta.persistence.EntityManager; /** * Resolve the EntityManager used for a specific repository. * Only necessary if there is more than one persistence unit. * * The container will look in the following order: * - A configured {@link EntityManagerConfig} * - A bean of type EntityManagerResolver * - Otherwise we'll assume there's a single {@link EntityManager}. */ public interface EntityManagerResolver { EntityManager resolveEntityManager(); } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/entitymanager/PersistenceUnitName.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.entitymanager; import jakarta.enterprise.util.Nonbinding; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; 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; /** * The name of the PersistenceUnit to get picked up by the * EntityManagerFactoryProducer. * * The EntityManagerFactoryProducer will in turn use the * {@link org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider} * to pick up the properties to be used for creating the {@code }EntityManagerFactory}. */ @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(value = RetentionPolicy.RUNTIME) @Documented @Qualifier public @interface PersistenceUnitName { /** * @return the name of the persistence unit. */ @Nonbinding String value(); } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/transaction/TransactionConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.transaction; import org.apache.deltaspike.core.api.config.DeltaSpikeConfig; /** * Optional config for transactions */ public interface TransactionConfig extends DeltaSpikeConfig { /** * @return timeout in seconds or null */ Integer getUserTransactionTimeoutInSeconds(); } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/transaction/TransactionHelper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.transaction; import org.apache.deltaspike.core.api.provider.BeanProvider; import jakarta.enterprise.context.ApplicationScoped; import java.util.concurrent.Callable; /** *

This class allows to execute CDI-unmanaged code blocks in a * @Transactional manner. This is handy if you like e.g. to execute * database code in a unit test tearDown method.

* *

Attention: please be aware that this helper only works for * @Transactional with auto-detecting the EntityManager! * If you need to manually specify the EntityManager Qualifier * for another EntityManager, then you need to copy this code and adopt it.

*

Usage: *

 *  SomeEntity retVal = TransactionHelper.getInstance().executeTransactional( new Callable() {
 *    private @Inject EntityManager em;
 *    public SomeEntity call() throws Exception {
 *      return em.find(entityId, SomeEntity.class);
 *    }
 *  } );
 * 
*

*/ @ApplicationScoped public class TransactionHelper { public static TransactionHelper getInstance() { return BeanProvider.getContextualReference(TransactionHelper.class); } /** * Execute the given {@link Callable} in a Transitional manner. * * @param callable which will get executed in a @Transactional block * @param the return type of the executed {@link Callable} * @return the return value of the executed {@link Callable} * @throws Exception */ @Transactional public T executeTransactional(Callable callable) throws Exception { return callable.call(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/transaction/TransactionScoped.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.transaction; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import jakarta.enterprise.context.NormalScope; /** *

A @TransactionScoped contextual instance will be unique for a given * transaction controlled by {@link Transactional}. The context will get started when the outermost * {@link Transactional} method gets invoked and will get closed when * the call chain leaves the outermost {@link Transactional} method.

* *

The classic use-case is for producing JPA EntityManagers. *

 *  @Dependent
 *  public class EntityManagerProducer
 *  {
 *      private @PersistenceContext(unitName = "test") EntityManager entityManager;
 *
 *      public @Produces @TransactionScoped EntityManager createEntityManager()
 *      {
 *          return entityManager;
 *      }
 *
 *      public void closeEntityManager(@Disposes EntityManager em)
 *      {
 *          if (em.isOpen()) //this check is optional -not needed if #close doesn't get called by the transactional bean
 *          {
 *              em.close();
 *          }
 *      }
 *  }
 * 
*

* or *

*

 *  @Dependent
 *  public class EntityManagerProducer
 *  {
 *      private @PersistenceUnit(unitName = "test") EntityManagerFactory entityManagerFactory;
 *
 *      public @Produces @TransactionScoped EntityManager createEntityManager()
 *      {
 *          return entityManagerFactory.createEntityManager();
 *      }
 *
 *      public void closeEntityManager(@Disposes EntityManager em)
 *      {
 *          if (em.isOpen()) //this check is optional -not needed if #close doesn't get called by the transactional bean
 *          {
 *              em.close();
 *          }
 *      }
 *  }
 * 
*

* *

* Furthermore, it's possible to use different persistence-units with (simple) qualifiers * (for the producer- and dispose-methods and therefore also at the injection-points). *

* *

* It's also possible to use @Transactional and @TransactionScoped in an application-server. * Therefore it's only needed to configure one of the * {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy}s which support JTA. *

* * @see Transactional */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) @NormalScope(passivating = false) public @interface TransactionScoped { } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/api/transaction/Transactional.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.api.transaction; import jakarta.enterprise.inject.Any; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * If it isn't possible to use EJBs, this interceptor adds transaction support to methods or a class. * The optional qualifier can be used to specify different entity managers. *

* Further details can be found at {@link TransactionScoped} which is an optional scope which can be used together with * @Transactional. */ @InterceptorBinding @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) public @interface Transactional { /** * Optional qualifier/s which allow/s to start only specific transactions instead of one * for the injected {@link jakarta.persistence.EntityManager}s. * Default-value is {@link Any} which means any injected {@link jakarta.persistence.EntityManager}s * should be detected automatically and transactions for all injected {@link jakarta.persistence.EntityManager}s * will be started. Or the {@link jakarta.enterprise.inject.Default} {@link jakarta.persistence.EntityManager} * will be used, if no qualifier and no {@link jakarta.persistence.EntityManager} was found (in the annotated class) * (see DELTASPIKE-320). * * This qualifier can also be used for integrating other frameworks, * which follow a different style (see DELTASPIKE-319) as well as the usage of * {@link jakarta.persistence.EntityManager}s with qualifiers in a called method (of a different bean) * which isn't {@link Transactional} itself. * * @return target persistence-unit identifier */ @Nonbinding Class[] qualifier() default Any.class; /** * Only evaluated on the first/outermost transactional bean/method in the chain * @return true to trigger #rollback for the current transaction(s), false otherwise */ @Nonbinding boolean readOnly() default false; } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/AbstractEntityDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.Serializable; public abstract class AbstractEntityDescriptor { private String id[]; private String version; private String name; private Class entityClass; private Class idClass; private AbstractEntityDescriptor parent; public AbstractEntityDescriptor() { } public AbstractEntityDescriptor(String[] id, String version, String name, Class entityClass, Class idClass, AbstractEntityDescriptor parent) { this.id = id; this.version = version; this.name = name; this.entityClass = entityClass; this.idClass = idClass; this.parent = parent; } public String[] getId() { return id; } public void setId(String[] id) { this.id = id; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Class getEntityClass() { return entityClass; } public void setEntityClass(Class entityClass) { this.entityClass = entityClass; } public Class getIdClass() { return idClass; } public void setIdClass(Class idClass) { this.idClass = idClass; } public AbstractEntityDescriptor getParent() { return parent; } public void setParent(AbstractEntityDescriptor parent) { this.parent = parent; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/AbstractEntityHierarchyBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.util.List; public final class AbstractEntityHierarchyBuilder { private AbstractEntityHierarchyBuilder() { } public static void buildHierarchy(List entities, List superClasses) { for (EntityDescriptor descriptor : entities) { buildHierarchy(descriptor, entities, superClasses); } } protected static void buildHierarchy(AbstractEntityDescriptor descriptor, List entities, List superClasses) { Class superClass = descriptor.getEntityClass().getSuperclass(); while (superClass != null) { AbstractEntityDescriptor superDescriptor = findPersistentClassDescriptor(superClass, entities, superClasses); if (superDescriptor != null) { if (descriptor.getParent() == null) { buildHierarchy(superDescriptor, entities, superClasses); } descriptor.setParent(superDescriptor); return; } superClass = superClass.getSuperclass(); } } protected static AbstractEntityDescriptor findPersistentClassDescriptor(Class superClass, List entities, List superClasses) { for (MappedSuperclassDescriptor descriptor : superClasses) { if (descriptor.getEntityClass().equals(superClass)) { return descriptor; } } for (EntityDescriptor descriptor : entities) { if (descriptor.getEntityClass().equals(superClass)) { return descriptor; } } return null; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/Descriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.net.URL; import org.w3c.dom.Document; public class Descriptor { private final Document document; private final URL url; public Descriptor(Document document, URL url) { this.document = document; this.url = url; } public Document getDocument() { return document; } public URL getUrl() { return url; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/DescriptorReader.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Collections; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.deltaspike.core.util.AggregatedClassLoader; import org.xml.sax.InputSource; import org.xml.sax.SAXException; abstract class DescriptorReader { private static final Logger LOG = Logger.getLogger(DescriptorReader.class.getName()); private final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); protected List readAllFromClassPath(String resource) throws IOException { List result = new LinkedList(); Enumeration urls = classLoader().getResources(resource); while (urls.hasMoreElements()) { URL u = urls.nextElement(); try { result.add(readFromUrl(u)); } catch (Exception e) { LOG.log(Level.WARNING, "Could not load " + resource + " from " + u, e); } } return Collections.unmodifiableList(result); } protected Descriptor readFromClassPath(String resource) throws IOException { return readFromUrl(classLoader().getResource(resource)); } protected Descriptor readFromUrl(URL url) throws IOException { InputStream stream = url.openStream(); try { DocumentBuilder builder = factory.newDocumentBuilder(); return new Descriptor(builder.parse(new InputSource(stream)), url); } catch (SAXException e) { throw new RuntimeException("Failed reading XML document", e); } catch (ParserConfigurationException e) { throw new RuntimeException("Failed reading XML document", e); } finally { stream.close(); } } protected Descriptor read(String baseUrl, String resource) throws IOException { try { URL url = new URL(baseUrl + resource); return readFromUrl(url); } catch (Exception e) { return readFromClassPath(resource); } } protected String extractBaseUrl(URL fileUrl, String resource) { String file = fileUrl.toString(); return file.substring(0, file.length() - resource.length()); } protected ClassLoader classLoader() { return AggregatedClassLoader.newInstance(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/EntityDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.Serializable; public class EntityDescriptor extends AbstractEntityDescriptor { private String tableName; public EntityDescriptor() { } public EntityDescriptor(String[] id, String version, String name, Class entityClass, Class idClass, AbstractEntityDescriptor parent, String tableName) { super(id, version, name, entityClass, idClass, parent); this.tableName = tableName; } public String getTableName() { return tableName; } public void setTableName(String tableName) { this.tableName = tableName; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("EntityDescriptor ") .append("[entityClass=").append(getEntityClass().getName()) .append(", name=").append(getName()) .append(", idClass=").append(getIdClass().getName()) .append(", id=").append(getId()) .append(", superClass=").append(getParent()) .append(", tableName=").append(tableName) .append("]"); return builder.toString(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/EntityMappingsDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.util.List; public class EntityMappingsDescriptor { private List mappedSuperclassDescriptors; private List entityDescriptors; private String packageName; public EntityMappingsDescriptor(List mappedSuperclassDescriptors, List entityDescriptors, String packageName) { this.mappedSuperclassDescriptors = mappedSuperclassDescriptors; this.entityDescriptors = entityDescriptors; this.packageName = packageName; } public List getMappedSuperclassDescriptors() { return mappedSuperclassDescriptors; } public void setMappedSuperclassDescriptors(List mappedSuperclassDescriptors) { this.mappedSuperclassDescriptors = mappedSuperclassDescriptors; } public List getEntityDescriptors() { return entityDescriptors; } public void setEntityDescriptors(List entityDescriptors) { this.entityDescriptors = entityDescriptors; } public String getPackageName() { return packageName; } public void setPackageName(String packageName) { this.packageName = packageName; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/EntityMappingsDescriptorParser.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.IOException; import java.io.Serializable; import java.util.Collections; import java.util.LinkedList; import java.util.List; import jakarta.enterprise.inject.Vetoed; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @Vetoed public class EntityMappingsDescriptorParser extends DescriptorReader { public static final String DEFAULT_ORM_PATH = "META-INF/orm.xml"; public EntityMappingsDescriptor readAll(String baseUrl, String resource) throws IOException { Document document = read(baseUrl, resource).getDocument(); return readFromDocument(document); } public EntityMappingsDescriptor readDefaultOrm(String baseUrl) throws IOException { try { Descriptor desc = read(baseUrl, DEFAULT_ORM_PATH); return readFromDocument(desc.getDocument()); } catch (Exception e) { return new EntityMappingsDescriptor(Collections.emptyList(), Collections.emptyList(), null); } } protected EntityMappingsDescriptor readFromDocument(Document doc) { String packageName = parsePackageName(doc); List mappedSuperclassDescriptors = parseMappedSuperclassDescriptors(doc, packageName); List entityDescriptors = parseEntityDescriptors(doc, packageName); return new EntityMappingsDescriptor(mappedSuperclassDescriptors, entityDescriptors, packageName); } protected String extractNodeAttribute(Element element, String childName, String attribute) { NodeList list = element.getElementsByTagName(childName); if (list.getLength() == 0) { return null; } return extractAttribute(list.item(0), attribute); } protected String extractAttribute(Node item, String name) { Node node = item.getAttributes().getNamedItem(name); if (node != null) { return node.getTextContent(); } return null; } protected String[] extractNodeAttributes(Element element, String childName, String attribute) { NodeList list = element.getElementsByTagName(childName); if (list.getLength() == 0) { return null; } return extractAttributes(list, attribute); } protected String[] extractAttributes(NodeList list, String name) { String[] values = null; for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i).getAttributes().getNamedItem(name); if (node != null) { if (values == null) { values = new String[list.getLength()]; } values[i] = node.getTextContent(); } } return values; } protected String extractNodeContent(Element element, String name) { NodeList list = element.getElementsByTagName(name); if (list.getLength() == 0) { return null; } return list.item(0).getTextContent(); } protected String parsePackageName(Document doc) { return extractNodeContent(doc.getDocumentElement(), "package"); } protected List parseMappedSuperclassDescriptors(Document doc, String packageName) { List result = new LinkedList(); NodeList mappings = doc.getElementsByTagName("mapped-superclass"); for (int i = 0; i < mappings.getLength(); i++) { Node node = mappings.item(i); MappedSuperclassDescriptor entityDescriptor = new MappedSuperclassDescriptor(); parseCommonEntityDescriptorAttributes(packageName, entityDescriptor, node); result.add(entityDescriptor); } return result; } protected List parseEntityDescriptors(Document doc, String packageName) { List result = new LinkedList(); NodeList mappings = doc.getElementsByTagName("entity"); for (int i = 0; i < mappings.getLength(); i++) { Node node = mappings.item(i); EntityDescriptor entityDescriptor = new EntityDescriptor(); parseCommonEntityDescriptorAttributes(packageName, entityDescriptor, node); entityDescriptor.setTableName(extractNodeAttribute((Element) node, "table", "name")); result.add(entityDescriptor); } return result; } protected void parseCommonEntityDescriptorAttributes(String packageName, AbstractEntityDescriptor entityDescriptor, Node node) { entityDescriptor.setName(extractAttribute(node, "name")); entityDescriptor.setVersion(extractNodeAttribute((Element) node, "version", "name")); String[] id = extractNodeAttributes((Element) node, "id", "name"); if (id != null) { entityDescriptor.setId(id); } else { String embeddedId = extractNodeAttribute((Element) node, "embedded-id", "name"); if (embeddedId != null) { entityDescriptor.setId(new String[] { embeddedId }); } } String className = extractAttribute(node, "class"); if (className != null) { try { entityDescriptor.setEntityClass(Class.forName(buildClassName(className, packageName))); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Can't get class " + buildClassName(className, packageName), e); } } String idClass = extractNodeAttribute((Element) node, "id-class", "class"); if (idClass != null) { try { entityDescriptor.setIdClass( (Class) Class.forName(buildClassName(idClass, packageName))); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Can't get class " + buildClassName(className, packageName), e); } } } protected String buildClassName(String clazzName, String packageName) { if (clazzName == null && packageName == null) { return null; } return (packageName != null && !isClassNameQualified(clazzName)) ? packageName + "." + clazzName : clazzName; } protected boolean isClassNameQualified(String name) { return name.contains("."); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/MappedSuperclassDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.Serializable; public class MappedSuperclassDescriptor extends AbstractEntityDescriptor { public MappedSuperclassDescriptor() { } public MappedSuperclassDescriptor(String[] id, String version, String name, Class entityClass, Class idClass, AbstractEntityDescriptor parent) { super(id, version, name, entityClass, idClass, parent); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("EntityDescriptor ") .append("[entityClass=").append(getEntityClass().getName()) .append(", name=").append(getName()) .append(", idClass=").append(getIdClass().getName()) .append(", id=").append(getId()) .append(", superClass=").append(getParent()) .append("]"); return builder.toString(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/PersistenceUnitDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.util.List; import java.util.Map; public class PersistenceUnitDescriptor { private String name; /* private String transactionType; private boolean excludeUnlistedClasses; */ private List entityDescriptors; private Map properties; public PersistenceUnitDescriptor(String name, List entityDescriptors, Map properties) { this.name = name; this.entityDescriptors = entityDescriptors; this.properties = properties; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List getEntityDescriptors() { return entityDescriptors; } public void setEntityDescriptors(List entityDescriptors) { this.entityDescriptors = entityDescriptors; } public Map getProperties() { return properties; } public void setProperties(Map properties) { this.properties = properties; } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("PersistenceUnit [name=").append(name) .append(", entityDescriptors=").append(entityDescriptors).append("]"); return builder.toString(); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/PersistenceUnitDescriptorParser.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import jakarta.enterprise.inject.Vetoed; @Vetoed public class PersistenceUnitDescriptorParser extends DescriptorReader { public static final String RESOURCE_PATH = "META-INF/persistence.xml"; private final EntityMappingsDescriptorParser entityMappingsDescriptorParser = new EntityMappingsDescriptorParser(); public List readAll() throws IOException { List result = new LinkedList(); List persistenceXmls = readAllFromClassPath(RESOURCE_PATH); for (Descriptor desc : persistenceXmls) { result.addAll(lookupUnits(desc)); } return Collections.unmodifiableList(result); } protected List lookupUnits(Descriptor descriptor) { List result = new LinkedList(); NodeList list = descriptor.getDocument().getDocumentElement().getElementsByTagName("persistence-unit"); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); String unitName = extractUnitName(node); String baseUrl = extractBaseUrl(descriptor.getUrl(), RESOURCE_PATH); List entities = extractMappings((Element) node, baseUrl, unitName); Map properties = extractProperties((Element) node); result.add(new PersistenceUnitDescriptor(unitName, entities, properties)); } return result; } protected List extractMappings(Element element, String baseUrl, String unitName) { try { List entities = new LinkedList(); List superClasses = new LinkedList(); NodeList list = element.getElementsByTagName("mapping-file"); readMappingFiles(baseUrl, unitName, entities, superClasses, list); EntityMappingsDescriptor mappings = entityMappingsDescriptorParser.readDefaultOrm(baseUrl); entities.addAll(mappings.getEntityDescriptors()); superClasses.addAll(mappings.getMappedSuperclassDescriptors()); AbstractEntityHierarchyBuilder.buildHierarchy(entities, superClasses); return entities; } catch (Exception e) { throw new RuntimeException("Failed initializing mapping files", e); } } protected void readMappingFiles(String baseUrl, String unitName, List entities, List superClasses, NodeList list) { for (int i = 0; i < list.getLength(); i++) { String resource = list.item(i).getTextContent(); try { EntityMappingsDescriptor mappings = entityMappingsDescriptorParser.readAll(baseUrl, resource); entities.addAll(mappings.getEntityDescriptors()); superClasses.addAll(mappings.getMappedSuperclassDescriptors()); } catch (Exception e) { throw new RuntimeException("[PersistenceUnit: " + unitName + "] " + "Unable to resolve named mapping-file [" + resource + "]"); } } } protected String extractUnitName(Node node) { return node.getAttributes().getNamedItem("name").getTextContent(); } protected Map extractProperties(Element element) { Map propertiesMap = new HashMap(); Node propertiesNode = element.getElementsByTagName("properties").item(0); if (propertiesNode != null) { NodeList propertyNodes = propertiesNode.getChildNodes(); for (int i = 0; i < propertyNodes.getLength(); i++) { if ("property".equals(propertyNodes.item(i).getNodeName())) { Element propertyNode = (Element) propertyNodes.item(i); propertiesMap.put(propertyNode.getAttribute("name"), propertyNode.getAttribute("value")); } } } return Collections.unmodifiableMap(propertiesMap); } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/descriptor/xml/PersistenceUnitDescriptorProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.descriptor.xml; import java.io.IOException; import java.util.Collections; import java.util.List; import jakarta.enterprise.inject.Vetoed; import org.apache.deltaspike.core.util.StringUtils; @Vetoed public final class PersistenceUnitDescriptorProvider { private static final PersistenceUnitDescriptorProvider INSTANCE = new PersistenceUnitDescriptorProvider(); private final PersistenceUnitDescriptorParser persistenceUnitDescriptorParser = new PersistenceUnitDescriptorParser(); private List persistenceUnitDescriptors = Collections.emptyList(); private PersistenceUnitDescriptorProvider() { } public static PersistenceUnitDescriptorProvider getInstance() { return INSTANCE; } public void init() { try { persistenceUnitDescriptors = persistenceUnitDescriptorParser.readAll(); } catch (IOException e) { throw new RuntimeException("Failed to parse persitence.xml's", e); } } public PersistenceUnitDescriptor get(String name) { for (PersistenceUnitDescriptor unit : persistenceUnitDescriptors) { if (name.equalsIgnoreCase(unit.getName())) { return unit; } } return null; } public boolean isEntity(Class entityClass) { return find(entityClass) != null; } public String[] primaryKeyFields(Class entityClass) { EntityDescriptor entity = find(entityClass); if (entity != null) { if (entity.getId() != null) { return entity.getId(); } AbstractEntityDescriptor parent = entity.getParent(); while (parent != null) { if (parent.getId() != null) { return parent.getId(); } parent = parent.getParent(); } } return null; } public String versionField(Class entityClass) { EntityDescriptor entity = find(entityClass); if (entity != null) { if (!StringUtils.isEmpty(entity.getVersion())) { return entity.getVersion(); } AbstractEntityDescriptor parent = entity.getParent(); while (parent != null) { if (!StringUtils.isEmpty(parent.getVersion())) { return parent.getVersion(); } parent = parent.getParent(); } } return null; } public Class primaryKeyIdClass(Class entityClass) { EntityDescriptor entity = find(entityClass); if (entity != null) { if (entity.getIdClass() != null) { return entity.getIdClass(); } AbstractEntityDescriptor parent = entity.getParent(); while (parent != null) { if (parent.getIdClass() != null) { return parent.getIdClass(); } parent = parent.getParent(); } } return null; } public String entityName(Class entityClass) { EntityDescriptor entity = find(entityClass); if (entity != null) { return entity.getName(); } return null; } public String entityTableName(Class entityClass) { EntityDescriptor entity = find(entityClass); if (entity != null) { return entity.getTableName(); } return null; } public EntityDescriptor find(Class entityClass) { for (PersistenceUnitDescriptor unit : persistenceUnitDescriptors) { EntityDescriptor entity = find(entityClass, unit); if (entity != null) { return entity; } } return null; } protected EntityDescriptor find(Class entityClass, PersistenceUnitDescriptor descriptor) { for (EntityDescriptor entity : descriptor.getEntityDescriptors()) { if (entity.getEntityClass().equals(entityClass)) { return entity; } } return null; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/entitymanager/ActiveEntityManagerHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.entitymanager; import jakarta.persistence.EntityManager; import java.io.Serializable; /** * Optional holder which allows to customize the handling of the {@link EntityManager}. * Multiple Entity-Managers with different qualifiers aren't supported. * See the data-module for further details. */ public interface ActiveEntityManagerHolder extends Serializable { void set(EntityManager entityManager); boolean isSet(); EntityManager get(); void dispose(); } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/entitymanager/PersistenceConfigurationProvider.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.entitymanager; import java.util.Properties; /** * Provide the configuration for the EntityManagerFactory * which gets produced with a given {@link org.apache.deltaspike.jpa.api.entitymanager.PersistenceUnitName}. * * By default we provide a configuration which con be configured * differently depending on the -DdatabaseVendor and the * {@link org.apache.deltaspike.core.api.projectstage.ProjectStage} */ public interface PersistenceConfigurationProvider { /** * @param persistenceUnitName the name of the persistence unit in persistence.xml * @return the additional Properties from the configuration. */ Properties getEntityManagerFactoryConfiguration(String persistenceUnitName); } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/entitymanager/QualifierBackedEntityManagerResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.entitymanager; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.persistence.EntityManager; public class QualifierBackedEntityManagerResolver implements EntityManagerResolver { private static final Logger logger = Logger.getLogger(QualifierBackedEntityManagerResolver.class.getName()); private final Class[] qualifiers; private final BeanManager beanManager; public QualifierBackedEntityManagerResolver(BeanManager beanManager, Class... qualifiers) { this.beanManager = beanManager; this.qualifiers = qualifiers; } @Override public EntityManager resolveEntityManager() { Bean entityManagerBean = resolveEntityManagerBeans(); if (entityManagerBean == null) { StringBuilder qualifierNames = new StringBuilder(); for (Class c : qualifiers) { qualifierNames.append(c.getName()).append(" "); } throw new IllegalStateException("Cannot find an EntityManager qualified with [" + qualifierNames + "]. Did you add a corresponding producer?"); } return (EntityManager) beanManager.getReference(entityManagerBean, EntityManager.class, beanManager.createCreationalContext(entityManagerBean)); } private Bean resolveEntityManagerBeans() { Set> entityManagerBeans = beanManager.getBeans(EntityManager.class, Any.Literal.INSTANCE); if (entityManagerBeans == null) { entityManagerBeans = new HashSet<>(); } Set> detectedEntityManagerBeans = new HashSet<>(); for (Class qualifierClass : qualifiers) { for (Bean currentEntityManagerBean : entityManagerBeans) { Set foundQualifierAnnotations = currentEntityManagerBean.getQualifiers(); for (Annotation currentQualifierAnnotation : foundQualifierAnnotations) { if (currentQualifierAnnotation.annotationType().equals(qualifierClass)) { detectedEntityManagerBeans.add(currentEntityManagerBean); } } } } if (detectedEntityManagerBeans.size() > 1) { logger.warning("detected multiple entityManager provider: " + detectedEntityManagerBeans); } if (!detectedEntityManagerBeans.isEmpty()) { Bean entityManagerBean = detectedEntityManagerBeans.iterator().next(); logger.fine("detected entityManager provider: " + entityManagerBean); return (Bean) entityManagerBean; } return null; } } ================================================ FILE: deltaspike/modules/jpa/api/src/main/java/org/apache/deltaspike/jpa/spi/transaction/TransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.spi.transaction; import org.apache.deltaspike.core.spi.InterceptorStrategy; /** * Marker interface for a plugable strategy for {@link org.apache.deltaspike.jpa.api.transaction.Transactional}. */ public interface TransactionStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/modules/jpa/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jpa/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules jpa-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-jpa-module-impl jar Apache DeltaSpike JPA-Module Impl org.apache.deltaspike.jpa.impl.* jakarta.persistence.*, !org.apache.deltaspike.jpa.impl.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.ops4j.pax.cdi.extension; extension=deltaspike-jpa-module-impl org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} compile org.apache.deltaspike.modules deltaspike-jpa-module-api ${project.version} jakarta.transaction jakarta.transaction-api ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/descriptor/xml/PersistenceUnitDescriptorInitExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.descriptor.xml; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptorProvider; public class PersistenceUnitDescriptorInitExtension implements Extension, Deactivatable { private Boolean isActivated = true; void beforeBeanDiscovery(@Observes BeforeBeanDiscovery before) { isActivated = ClassDeactivationUtils.isActivated(getClass()); if (!isActivated) { return; } PersistenceUnitDescriptorProvider.getInstance().init(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/DefaultEntityManagerHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import jakarta.enterprise.context.Dependent; import jakarta.persistence.EntityManager; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; /** * Empty holder. Override and specialize in using module. * Currently only used by the data module. */ @Dependent public class DefaultEntityManagerHolder implements ActiveEntityManagerHolder { @Override public void set(EntityManager entityManager) { throw new UnsupportedOperationException( "Default implementation does not store an EntityManager"); } @Override public boolean isSet() { return false; } @Override public EntityManager get() { return null; } @Override public void dispose() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerFactoryProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.inject.Inject; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; import java.util.Properties; import java.util.logging.Logger; import org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider; import org.apache.deltaspike.jpa.api.entitymanager.PersistenceUnitName; /** *

Built in support for injecting EntityManagerFactories into own beans. * The injection point must use the Qualifier {@link PersistenceUnitName} * to express the desired persistence unit name.

* *

The EntityManagerFactory for the given persistence unit will be produced * as @Dependent scoped. It can be used to easily implement own * EntityManagerProviders as shown in the following example which provides * a producer according to the entitymanager-per-request design pattern:

*
 * @ApplicationScoped
 * public class SampleEntityManagerProducer {
 *   @Inject
 *   @PersistenceUnitName("testPersistenceUnit")
 *   private EntityManagerFactory emf;
 *
 *   @Produces
 *   @RequestScoped
 *   public EntityManager createEntityManager() {
 *     return emf.createEntityManager();
 *   }
 *
 *   public void closeEm(@Disposes EntityManager em) {
 *     em.close();
 *   }
 * }
 *  
*/ @ApplicationScoped public class EntityManagerFactoryProducer { private static final Logger LOG = Logger.getLogger(EntityManagerFactoryProducer.class.getName()); @Inject private PersistenceConfigurationProvider persistenceConfigurationProvider; @Produces @Dependent @PersistenceUnitName("any") // the value is nonbinding, thus 'any' is just a dummy parameter here public EntityManagerFactory createEntityManagerFactoryForUnit(InjectionPoint injectionPoint) { PersistenceUnitName unitNameAnnotation = injectionPoint.getAnnotated().getAnnotation(PersistenceUnitName.class); if (unitNameAnnotation == null) { LOG.warning("@PersistenceUnitName annotation could not be found at EntityManagerFactory injection point!"); return null; } String unitName = unitNameAnnotation.value(); Properties properties = persistenceConfigurationProvider.getEntityManagerFactoryConfiguration(unitName); EntityManagerFactory emf = Persistence.createEntityManagerFactory(unitName, properties); return emf; } public void disposeEntityManagerFactory(@Disposes @PersistenceUnitName("any") EntityManagerFactory emf) { if (emf.isOpen()) { emf.close(); } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerMetadata.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.persistence.FlushModeType; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.util.Set; public class EntityManagerMetadata { private Class entityManagerResolverClass; private EntityManagerResolver unmanagedResolver; private Class[] qualifiers; private boolean entityManagerResolverIsNormalScope; private FlushModeType entityManagerFlushMode; private boolean readOnly = false; public Class getEntityManagerResolverClass() { return entityManagerResolverClass; } public void setEntityManagerResolverClass(Class entityManagerResolverClass) { this.entityManagerResolverClass = entityManagerResolverClass; } public FlushModeType getEntityManagerFlushMode() { return entityManagerFlushMode; } public void setEntityManagerFlushMode(FlushModeType entityManagerFlushMode) { this.entityManagerFlushMode = entityManagerFlushMode; } public boolean isEntityManagerResolverIsNormalScope() { return entityManagerResolverIsNormalScope; } public void setEntityManagerResolverIsNormalScope(boolean entityManagerResolverIsNormalScope) { this.entityManagerResolverIsNormalScope = entityManagerResolverIsNormalScope; } public Class[] getQualifiers() { return qualifiers; } public void setQualifiers(Class[] qualifiers) { this.qualifiers = qualifiers; } public EntityManagerResolver getUnmanagedResolver() { return unmanagedResolver; } public void setUnmanagedResolver(EntityManagerResolver unmanagedResolver) { this.unmanagedResolver = unmanagedResolver; } public boolean readFrom(AnnotatedElement method, BeanManager beanManager) { EntityManagerConfig entityManagerConfig = method.getAnnotation(EntityManagerConfig.class); boolean processed = processEntityManagerConfig(beanManager, entityManagerConfig); Transactional transactional = method.getAnnotation(Transactional.class); processed = processTransactional(processed, transactional); return processed; } private boolean processTransactional(boolean processed, Transactional transactional) { if (transactional != null && this.qualifiers == null) { processed = true; this.setQualifiers(transactional.qualifier()); } if (transactional != null) { this.readOnly = transactional.readOnly(); } return processed; } private boolean processEntityManagerConfig(BeanManager beanManager, EntityManagerConfig entityManagerConfig) { boolean processed = false; if (entityManagerConfig != null) { processed = true; this.setEntityManagerFlushMode(entityManagerConfig.flushMode()); this.setQualifiers(entityManagerConfig.qualifier()); Class resolverClass = entityManagerConfig.entityManagerResolver(); if (!resolverClass.equals(EntityManagerResolver.class)) { this.setEntityManagerResolverClass(resolverClass); Set> beans = beanManager.getBeans(resolverClass); Class scope = beanManager.resolve(beans).getScope(); this.setEntityManagerResolverIsNormalScope(beanManager.isNormalScope(scope)); } else { this.setEntityManagerResolverIsNormalScope(false); } } return processed; } public boolean isReadOnly() { return readOnly; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerRef.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import jakarta.persistence.EntityManager; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; public class EntityManagerRef { private EntityManager entityManager; private DependentProvider entityManagerDependentProvider; private Class entityManagerResolverClass; private EntityManagerResolver entityManagerResolver; private DependentProvider entityManagerResolverDependentProvider; public void release() { if (entityManagerDependentProvider != null) { entityManagerDependentProvider.destroy(); } if (entityManagerResolverDependentProvider != null) { entityManagerResolverDependentProvider.destroy(); } } public Class getEntityManagerResolverClass() { return entityManagerResolverClass; } public void setEntityManagerResolverClass(Class entityManagerResolverClass) { this.entityManagerResolverClass = entityManagerResolverClass; } public DependentProvider getEntityManagerResolverDependentProvider() { return entityManagerResolverDependentProvider; } public void setEntityManagerResolverDependentProvider( DependentProvider entityManagerResolverDependentProvider) { this.entityManagerResolverDependentProvider = entityManagerResolverDependentProvider; } public EntityManager getEntityManager() { return entityManager; } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } public EntityManagerResolver getEntityManagerResolver() { return entityManagerResolver; } public void setEntityManagerResolver(EntityManagerResolver entityManagerResolver) { this.entityManagerResolver = entityManagerResolver; } public DependentProvider getEntityManagerDependentProvider() { return entityManagerDependentProvider; } public void setEntityManagerDependentProvider( DependentProvider entityManagerDependentProvider) { this.entityManagerDependentProvider = entityManagerDependentProvider; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/EntityManagerRefLookup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import java.util.Set; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerResolver; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; @ApplicationScoped public class EntityManagerRefLookup { @Inject private ActiveEntityManagerHolder activeEntityManagerHolder; private volatile Boolean globalEntityManagerInitialized; private boolean globalEntityManagerIsNormalScope; private EntityManager globalEntityManager; private void lazyInitGlobalEntityManager() { if (this.globalEntityManagerInitialized == null) { initGlobalEntityManager(); } } private synchronized void initGlobalEntityManager() { // switch into paranoia mode if (this.globalEntityManagerInitialized == null) { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Set> beans = beanManager.getBeans(EntityManager.class); Bean bean = beanManager.resolve(beans); if (bean == null) { throw new IllegalStateException("Could not find EntityManager with default qualifier."); } globalEntityManagerIsNormalScope = beanManager.isNormalScope(bean.getScope()); if (globalEntityManagerIsNormalScope) { globalEntityManager = (EntityManager) beanManager.getReference(bean, EntityManager.class, beanManager.createCreationalContext(bean)); } this.globalEntityManagerInitialized = true; } } public EntityManagerRef lookupReference(final EntityManagerMetadata entityManagerMetadata) { EntityManagerRef ref = new EntityManagerRef(); EntityManagerResolver unmanagedResolver = entityManagerMetadata.getUnmanagedResolver(); if (unmanagedResolver != null) { ref.setEntityManagerResolver(unmanagedResolver); ref.setEntityManager(unmanagedResolver.resolveEntityManager()); } else if (entityManagerMetadata.getEntityManagerResolverClass() != null) { ref.setEntityManagerResolverClass(entityManagerMetadata.getEntityManagerResolverClass()); if (entityManagerMetadata.isEntityManagerResolverIsNormalScope()) { ref.setEntityManagerResolver( BeanProvider.getContextualReference(ref.getEntityManagerResolverClass())); } else { ref.setEntityManagerResolverDependentProvider( BeanProvider.getDependent(ref.getEntityManagerResolverClass())); ref.setEntityManagerResolver( ref.getEntityManagerResolverDependentProvider().get()); } ref.setEntityManager( ref.getEntityManagerResolver().resolveEntityManager()); } else { if (activeEntityManagerHolder.isSet()) { ref.setEntityManager( activeEntityManagerHolder.get()); // TODO should we really not apply the FlushMode on the active EntityManager? return ref; } else { lazyInitGlobalEntityManager(); if (globalEntityManagerIsNormalScope) { ref.setEntityManager(globalEntityManager); } else { ref.setEntityManagerDependentProvider( BeanProvider.getDependent(EntityManager.class)); ref.setEntityManager( ref.getEntityManagerDependentProvider().get()); } } } if (entityManagerMetadata.getEntityManagerFlushMode() != null) { ref.getEntityManager().setFlushMode(entityManagerMetadata.getEntityManagerFlushMode()); } return ref; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/entitymanager/PersistenceConfigurationProviderImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.entitymanager; import jakarta.enterprise.context.ApplicationScoped; import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.PropertyLoader; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider; /** * Default implementation of the PersistenceConfigurationProvider. * */ @ApplicationScoped public class PersistenceConfigurationProviderImpl implements PersistenceConfigurationProvider { /** * A prefix which will be used for looking up more specific * information for a persistenceUnit. * * @see #addConfigProperties(Properties, String) */ private static final String CONFIG_PREFIX = "deltaspike.persistence.config."; @Override public Properties getEntityManagerFactoryConfiguration(String persistenceUnitName) { Properties unitProperties = PropertyLoader.getProperties("persistence-" + persistenceUnitName); if (unitProperties == null) { unitProperties = new Properties(); } // apply ConfigFilters to the configured values. for (Map.Entry entry : unitProperties.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); entry.setValue(ConfigResolver.filterConfigValue(key, value)); } unitProperties = addConfigProperties(unitProperties, persistenceUnitName); // add spec expected attributes unitProperties.put("jakarta.persistence.bean.manager", BeanManagerProvider.getInstance().getBeanManager()); return unitProperties; } /** * Load additional configuration from the Configuration system * and overload the basic settings with that info. * * The key is deltaspike.persistence.config.${persistenceUnitName}.${originalKey} * * @see #CONFIG_PREFIX * @since 1.8.0 */ protected Properties addConfigProperties(Properties unitProperties, String persistenceUnitName) { // we start with a copy of the original properties Properties mergedConfig = new Properties(); mergedConfig.putAll(unitProperties); Set allConfigKeys = ConfigResolver.getAllProperties().keySet(); String unitPrefix = CONFIG_PREFIX + persistenceUnitName + "."; for (String configKey : allConfigKeys) { if (configKey.startsWith(unitPrefix)) { mergedConfig.put(configKey.substring(unitPrefix.length()), ConfigResolver.getProjectStageAwarePropertyValue(configKey)); } } return mergedConfig; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.core.impl.util.JndiUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.jpa.api.config.base.JpaBaseConfig; import org.apache.deltaspike.jpa.api.transaction.TransactionConfig; import org.apache.deltaspike.jpa.impl.transaction.context.EntityManagerEntry; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityTransaction; import jakarta.transaction.Status; import jakarta.transaction.SystemException; import jakarta.transaction.TransactionSynchronizationRegistry; import jakarta.transaction.UserTransaction; import java.lang.annotation.Annotation; import java.util.logging.Level; import java.util.logging.Logger; /** *

{@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} for using JTA (bean-managed-)transactions * (including XA transactions with a XA DataSource). * The basic features are identical to the {@link ResourceLocalTransactionStrategy} (for * persistent-unit-transaction-type 'RESOURCE_LOCAL' only).

*/ @Dependent @Alternative @SuppressWarnings("UnusedDeclaration") //TODO move to a separated ds-jta module and use @Specializes -> no additional config is needed public class BeanManagedUserTransactionStrategy extends ResourceLocalTransactionStrategy { protected static final String TRANSACTION_SYNC_REGISTRY_JNDI_NAME = "java:comp/TransactionSynchronizationRegistry"; private static final long serialVersionUID = -2432802805095533499L; private static final Logger LOGGER = Logger.getLogger(BeanManagedUserTransactionStrategy.class.getName()); @Inject private BeanManager beanManager; private transient TransactionConfig transactionConfig; @Override protected EntityManagerEntry createEntityManagerEntry( EntityManager entityManager, Class qualifier) { applyTransactionTimeout(); //needs to be done before UserTransaction#begin - TODO move this call return super.createEntityManagerEntry(entityManager, qualifier); } protected void applyTransactionTimeout() { Integer transactionTimeout = getDefaultTransactionTimeoutInSeconds(); if (transactionTimeout == null) { //the default configured for the container will be used return; } try { UserTransaction userTransaction = resolveUserTransaction(); if (userTransaction != null && userTransaction.getStatus() != Status.STATUS_ACTIVE) { userTransaction.setTransactionTimeout(transactionTimeout); } } catch (SystemException e) { LOGGER.log(Level.WARNING, "UserTransaction#setTransactionTimeout failed", e); } } protected Integer getDefaultTransactionTimeoutInSeconds() { if (this.transactionConfig == null) { lazyInit(); } return transactionConfig.getUserTransactionTimeoutInSeconds(); } protected synchronized void lazyInit() { if (this.transactionConfig != null) { return; } this.transactionConfig = BeanProvider.getContextualReference(TransactionConfig.class, true); if (this.transactionConfig == null) { this.transactionConfig = createDefaultTransactionConfig(); } } protected TransactionConfig createDefaultTransactionConfig() { return new TransactionConfig() { private static final long serialVersionUID = -3915439087580270117L; @Override public Integer getUserTransactionTimeoutInSeconds() { return JpaBaseConfig.UserTransaction.TIMEOUT_IN_SECONDS; } }; } @Override protected EntityTransaction getTransaction(EntityManagerEntry entityManagerEntry) { return new UserTransactionAdapter(); } /** * Needed because the {@link EntityManager} might get created outside of the {@link UserTransaction} * (e.g. depending on the implementation of the producer). * Can't be in {@link BeanManagedUserTransactionStrategy.UserTransactionAdapter#begin()} * because {@link ResourceLocalTransactionStrategy} needs to do *
     * if (!transaction.isActive())
     * {
     *     transaction.begin();
     * }
     * 
* for the {@link EntityTransaction} of every {@link EntityManager} * and {@link BeanManagedUserTransactionStrategy.UserTransactionAdapter#isActive()} * can only use the status information of the {@link UserTransaction} and therefore * {@link BeanManagedUserTransactionStrategy.UserTransactionAdapter#begin()} * will only executed once, but {@link jakarta.persistence.EntityManager#joinTransaction()} * needs to be called for every {@link EntityManager}. * @param invocationContext current invocation-context * @param entityManagerEntry entry of the current entity-manager * @param transaction current JTA transaction wrapped in an EntityTransaction adapter */ @Override protected void beforeProceed(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { entityManagerEntry.getEntityManager().joinTransaction(); } protected UserTransaction resolveUserTransaction() { //manual lookup needed because injecting UserTransactionResolver can fail (see the comment there) try { DependentProvider provider = BeanProvider.getDependent(this.beanManager, UserTransactionResolver.class); UserTransaction userTransaction = provider.get().resolveUserTransaction(); provider.destroy(); return userTransaction; } catch (Exception e) { return null; } } protected TransactionSynchronizationRegistry resolveTransactionRegistry() { return JndiUtils.lookup(TRANSACTION_SYNC_REGISTRY_JNDI_NAME, TransactionSynchronizationRegistry.class); } private class UserTransactionAdapter implements EntityTransaction { private final UserTransaction userTransaction; //needed for calls through an EJB with CMT private final TransactionSynchronizationRegistry transactionSynchronizationRegistry; public UserTransactionAdapter() { this.userTransaction = resolveUserTransaction(); if (this.userTransaction == null) { this.transactionSynchronizationRegistry = resolveTransactionRegistry(); if (this.transactionSynchronizationRegistry.getTransactionStatus() != Status.STATUS_ACTIVE) { throw new IllegalStateException( "The CMT is not active. Please check the config of the Data-Source."); } } else { this.transactionSynchronizationRegistry = null; } } /** * Only delegate to the {@link UserTransaction} if the state of the * {@link UserTransaction} is {@link Status#STATUS_NO_TRANSACTION} * (= the status before and after a started transaction). */ @Override public void begin() { if (this.userTransaction == null) { throw new UnsupportedOperationException("A CMT is active. This operation is only supported with BMT."); } try { //2nd check (already done by #isActive triggered by ResourceLocalTransactionStrategy directly before) //currently to filter STATUS_UNKNOWN - see to-do -> TODO re-visit it if (this.userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) { this.userTransaction.begin(); } } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } /** * Only delegate to the {@link UserTransaction} if the state of the * {@link UserTransaction} is one of *
    *
  • {@link Status#STATUS_ACTIVE}
  • *
  • {@link Status#STATUS_PREPARING}
  • *
  • {@link Status#STATUS_PREPARED}
  • *
*/ @Override public void commit() { if (this.userTransaction == null) { throw new UnsupportedOperationException("A CMT is active. This operation is only supported with BMT."); } try { if (isTransactionReadyToCommit()) { this.userTransaction.commit(); } } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } /** * Only delegate to the {@link UserTransaction} if the state of the * {@link UserTransaction} is one of *
    *
  • {@link Status#STATUS_ACTIVE}
  • *
  • {@link Status#STATUS_PREPARING}
  • *
  • {@link Status#STATUS_PREPARED}
  • *
  • {@link Status#STATUS_MARKED_ROLLBACK}
  • *
  • {@link Status#STATUS_COMMITTING}
  • *
*/ @Override public void rollback() { if (this.userTransaction == null) { throw new UnsupportedOperationException("A CMT is active. This operation is only supported with BMT."); } try { if (isTransactionAllowedToRollback()) { this.userTransaction.rollback(); } } catch (SystemException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public void setRollbackOnly() { try { if (this.userTransaction != null) { this.userTransaction.setRollbackOnly(); } else { this.transactionSynchronizationRegistry.setRollbackOnly(); } } catch (SystemException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public boolean getRollbackOnly() { try { return getTransactionStatus() == Status.STATUS_MARKED_ROLLBACK; } catch (SystemException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } /** * @return true if the transaction has been started and not ended */ @Override public boolean isActive() { //we can't use the status of the overall try { return this.getTransactionStatus() != Status.STATUS_NO_TRANSACTION && this.getTransactionStatus() != Status.STATUS_UNKNOWN; //TODO re-visit it } catch (SystemException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } protected boolean isTransactionAllowedToRollback() throws SystemException { //if the following gets changed, it needs to be tested with different constellations //(normal exception, timeout,...) as well as servers return this.getTransactionStatus() != Status.STATUS_COMMITTED && this.getTransactionStatus() != Status.STATUS_NO_TRANSACTION && this.getTransactionStatus() != Status.STATUS_UNKNOWN; } protected boolean isTransactionReadyToCommit() throws SystemException { return getTransactionStatus() == Status.STATUS_ACTIVE || getTransactionStatus() == Status.STATUS_PREPARING || getTransactionStatus() == Status.STATUS_PREPARED; } protected int getTransactionStatus() throws SystemException { if (this.userTransaction != null) { return this.userTransaction.getStatus(); } else { return this.transactionSynchronizationRegistry.getTransactionStatus(); } } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ContainerManagedTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.interceptor.InvocationContext; /** *

{@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} for CMT for the data-module.

*/ @Dependent @Alternative @SuppressWarnings("UnusedDeclaration") public class ContainerManagedTransactionStrategy implements TransactionStrategy { private static final long serialVersionUID = 70354806762739497L; @Override public Object execute(InvocationContext invocationContext) throws Exception { return invocationContext.proceed(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/EnvironmentAwareTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.jpa.impl.transaction.context.EntityManagerEntry; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.interceptor.InvocationContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityTransaction; import java.lang.annotation.Annotation; /** *

This alternative {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} uses auto-detection and * can be used for different (parallel) persistence-units which use different transaction-types or * if different environments (dev., prod.,...) should use different transaction-types.

* *

This implementation can be used for environments which allow a mixed usage of JTA and RESOURCE_LOCAL. * (Within a transactional call it isn't possible to mix different transaction-types.) * * E.g.: in an application-server this class allows to use a persistence-unit with * transaction-type="RESOURCE_LOCAL" + non-jta-data-source * in parallel to a persistence-unit with * transaction-type="JTA" + jta-data-source

* *

Optional:
* E.g. in case of a project-stage based logic * {@link org.apache.deltaspike.core.api.exclude.Exclude} can be used to switch between different * producer-beans.

* *

It's a better alternative than extending * {@link BeanManagedUserTransactionStrategy} * (which would lead to an impl. dependency) only for using * {@link org.apache.deltaspike.core.api.exclude.Exclude} at the custom * {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} * (or doing a custom veto-extension).

*/ @Dependent @Alternative @SuppressWarnings("UnusedDeclaration") //TODO depending on further discussions about an own JTA module, BeanManagedUserTransactionStrategy //could be the default (via @Specializes) in the ds-jta module. //Depending on further discussions this class can be merged with BeanManagedUserTransactionStrategy or //we keep BeanManagedUserTransactionStrategy separated as a small tweak for applications which only use JTA transactions //or as a base implementation for a custom EnvironmentAwareTransactionStrategy. public class EnvironmentAwareTransactionStrategy extends BeanManagedUserTransactionStrategy { private static final long serialVersionUID = -4432802805095533499L; private static ThreadLocal isJtaModeDetected = new ThreadLocal(); @Override protected EntityManagerEntry createEntityManagerEntry( EntityManager entityManager, Class qualifier) { boolean isTransactionTypeJta = false; //Ensures that nested transactional beans with different entity-managers don't lead to a rollback //(in case of transaction-type JTA). if (isJtaModeDetected.get() == null) { try { //This check is only valid here, because the transaction isn't started. entityManager.getTransaction(); } catch (IllegalStateException e) { isTransactionTypeJta = true; } isJtaModeDetected.set(isTransactionTypeJta); } else { isTransactionTypeJta = isInJtaTransaction(); } if (isTransactionTypeJta) { applyTransactionTimeout(); //needs to be done before UserTransaction#begin - TODO move this call } return new EntityManagerEntry(entityManager, qualifier); } @Override protected void beforeProceed(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { if (isInJtaTransaction()) { super.beforeProceed(invocationContext, entityManagerEntry, transaction); } } @Override protected EntityTransaction getTransaction(EntityManagerEntry entityManagerEntry) { if (isInJtaTransaction()) { return super.getTransaction(entityManagerEntry); } return entityManagerEntry.getEntityManager().getTransaction(); } @Override protected void onCloseTransactionScope() { super.onCloseTransactionScope(); isJtaModeDetected.set(null); isJtaModeDetected.remove(); } private static boolean isInJtaTransaction() { return Boolean.TRUE.equals(isJtaModeDetected.get()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ManagedUserTransactionResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import jakarta.annotation.Resource; import jakarta.enterprise.context.Dependent; import jakarta.transaction.UserTransaction; //we need to keep it separated, //because the injection of UserTransaction might fail with an exception (see DELTASPIKE-986) @Dependent public class ManagedUserTransactionResolver { @Resource private UserTransaction userTransaction; public UserTransaction resolveUserTransaction() { return userTransaction; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/ResourceLocalTransactionStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityTransaction; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerMetadata; import org.apache.deltaspike.jpa.impl.transaction.context.EntityManagerEntry; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.spi.entitymanager.ActiveEntityManagerHolder; import org.apache.deltaspike.jpa.spi.entitymanager.QualifierBackedEntityManagerResolver; import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy; /** *

Default implementation of our plugable TransactionStrategy. * It supports nested Transactions with the MANDATORY behaviour.

* *

The outermost @Transactional interceptor for the given * {@link jakarta.inject.Qualifier} will open an {@link jakarta.persistence.EntityTransaction} * and the outermost @Transactional interceptor for all * EntityManagers will flush and subsequently close all open transactions.

* *

If an Exception occurs in flushing the EntityManagers or any other Exception * gets thrown inside the intercepted method chain and not gets catched * until the outermost @Transactional interceptor gets reached, then all * open transactions will get rollbacked.

* *

If you like to implement your own TransactionStrategy, then use the * standard CDI @Alternative mechanism.

*/ @Dependent public class ResourceLocalTransactionStrategy implements TransactionStrategy { private static final long serialVersionUID = -1432802805095533499L; private static final Logger LOGGER = Logger.getLogger(ResourceLocalTransactionStrategy.class.getName()); @Inject private BeanManager beanManager; @Inject private TransactionStrategyHelper transactionHelper; @Inject private ActiveEntityManagerHolder emHolder; @Override public Object execute(InvocationContext invocationContext) throws Exception { EntityManagerMetadata metadata = transactionHelper.createEntityManagerMetadata(invocationContext); Transactional transactionalAnnotation = transactionHelper.extractTransactionalAnnotation(invocationContext); Class targetClass = ProxyUtils.getUnproxiedClass(invocationContext.getTarget().getClass()); //see DELTASPIKE-517 // all the configured qualifier keys Set> emQualifiers = emHolder.isSet() ? new HashSet>(Arrays.asList(Default.class)) : transactionHelper.resolveEntityManagerQualifiers(metadata, targetClass); TransactionBeanStorage transactionBeanStorage = TransactionBeanStorage.getInstance(); boolean isOutermostInterceptor = transactionBeanStorage.isEmpty(); boolean startedTransaction = false; if (isOutermostInterceptor) { // a new Context needs to get started transactionBeanStorage.startTransactionScope(); } // the 'layer' of the transactional invocation, aka the refCounter @SuppressWarnings("UnusedDeclaration") int transactionLayer = transactionBeanStorage.incrementRefCounter(); Exception firstException = null; try { for (Class emQualifier : emQualifiers) { EntityManager entityManager = resolveEntityManagerForQualifier(emQualifier); EntityManagerEntry entityManagerEntry = createEntityManagerEntry(entityManager, emQualifier); transactionBeanStorage.storeUsedEntityManager(entityManagerEntry); EntityTransaction transaction = getTransaction(entityManagerEntry); if (!transaction.isActive()) { beforeBegin(invocationContext, entityManagerEntry, transaction); transaction.begin(); startedTransaction = true; } //don't move it before EntityTransaction#begin() and invoke it in any case beforeProceed(invocationContext, entityManagerEntry, transaction); } return invocationContext.proceed(); } catch (Exception e) { firstException = e; // we only cleanup and rollback all open transactions in the outermost interceptor! // this way, we allow inner functions to catch and handle exceptions properly. if (isOutermostInterceptor) { Set entityManagerEntryList = transactionBeanStorage.getUsedEntityManagerEntries(); if (startedTransaction) { // We only commit transactions we opened ourselfs. // If the transaction got opened outside of our interceptor chain // we must not handle it. // This e.g. happens if a Stateless EJB invokes a Transactional CDI bean // which uses the BeanManagedUserTransactionStrategy. rollbackAllTransactions(entityManagerEntryList); } // drop all EntityManagers from the request-context cache transactionBeanStorage.cleanUsedEntityManagers(); } // give any extensions a chance to supply a better error message e = prepareException(e); // rethrow the exception throw e; } finally { // will get set if we got an Exception while committing // in this case, we rollback all later transactions too. boolean commitFailed = false; // commit all open transactions in the outermost interceptor! // For Resource-local this is a 'JTA for poor men' only, and will not guaranty // commit stability over various databases! // In case of JTA we will just commit the UserTransaction. if (isOutermostInterceptor) { if (startedTransaction) { // We only commit transactions we opened ourselfs. // If the transaction got opened outside of our interceptor chain // we must not handle it. // This e.g. happens if a Stateless EJB invokes a Transactional CDI bean // which uses the BeanManagedUserTransactionStrategy. if (firstException == null) { // only commit all transactions if we didn't rollback // them already Set entityManagerEntryList = transactionBeanStorage.getUsedEntityManagerEntries(); boolean rollbackOnly = metadata.isReadOnly() || isRollbackOnly(transactionalAnnotation); if (!rollbackOnly && entityManagerEntryList.size() > 1) { // but first try to flush all the transactions and write the updates to the database for (EntityManagerEntry currentEntityManagerEntry : entityManagerEntryList) { EntityTransaction transaction = getTransaction(currentEntityManagerEntry); if (transaction != null && transaction.isActive()) { try { if (!commitFailed) { currentEntityManagerEntry.getEntityManager().flush(); if (!rollbackOnly && transaction.getRollbackOnly()) { // don't set commitFailed to true directly // (the order of the entity-managers isn't deterministic // -> tests would break) rollbackOnly = true; } } } catch (Exception e) { firstException = e; commitFailed = true; break; } } } } if (rollbackOnly) { commitFailed = true; } // and now either commit or rollback all transactions for (EntityManagerEntry currentEntityManagerEntry : entityManagerEntryList) { EntityTransaction transaction = getTransaction(currentEntityManagerEntry); if (transaction != null && transaction.isActive()) { try { // last chance to check it (again) if (commitFailed || transaction.getRollbackOnly()) { beforeRollback(invocationContext, currentEntityManagerEntry, transaction); transaction.rollback(); } else { beforeCommit(invocationContext, currentEntityManagerEntry, transaction); transaction.commit(); } } catch (Exception e) { firstException = e; commitFailed = true; } finally { afterProceed(invocationContext,currentEntityManagerEntry, firstException); } } } } } // and now we close the open transaction scope transactionBeanStorage.endTransactionScope(); onCloseTransactionScope(); } transactionBeanStorage.decrementRefCounter(); if (commitFailed && firstException != null /*null if just #getRollbackOnly is true*/) { throwException(firstException); } } } protected void beforeBegin(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { //override if needed } protected void beforeProceed(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { //override if needed } protected void beforeCommit(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { //override if needed } protected void beforeRollback(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, EntityTransaction transaction) { //override if needed } /** * @param invocationContext current invocation-context * @param entityManagerEntry current entity-manager entry * @param exception the exception which occurred or null if everything went fine */ protected void afterProceed(InvocationContext invocationContext, EntityManagerEntry entityManagerEntry, Exception exception) { //override if needed } protected void throwException(Exception exception) throws Exception { //override if needed throw exception; } //allows to use a custom tx-controller in a custom strategy @Deprecated // instead, configure read only on the method/class protected boolean isRollbackOnly(Transactional transactionalAnnotation) { return transactionalAnnotation != null && transactionalAnnotation.readOnly(); } private void rollbackAllTransactions(Set entityManagerEntryList) { for (EntityManagerEntry currentEntityManagerEntry : entityManagerEntryList) { EntityTransaction transaction = getTransaction(currentEntityManagerEntry); if (transaction != null && transaction.isActive()) { try { transaction.rollback(); } catch (Exception eRollback) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, "Got additional Exception while subsequently " + "rolling back other SQL transactions", eRollback); } } } } } protected EntityManagerEntry createEntityManagerEntry( EntityManager entityManager, Class qualifier) { return new EntityManagerEntry(entityManager, qualifier); } /** * * @param entityManagerEntry entry of the current entity-manager * @return per default the {@link EntityTransaction} of the given {@link EntityManager}. * A subclass can also return an adapter e.g. for an UserTransaction */ protected EntityTransaction getTransaction(EntityManagerEntry entityManagerEntry) { return entityManagerEntry.getEntityManager().getTransaction(); } private EntityManager resolveEntityManagerForQualifier(Class emQualifier) { if (emHolder.isSet()) { return emHolder.get(); } return new QualifierBackedEntityManagerResolver(beanManager, emQualifier).resolveEntityManager(); } /** * This method might get overridden in subclasses to supply better error messages. * This is useful if e.g. a JPA provider only provides a stubborn Exception for * their ConstraintValidationExceptions. * @return the wrapped or unwrapped Exception */ protected Exception prepareException(Exception e) { return e; } protected void onCloseTransactionScope() { TransactionBeanStorage.close(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionStrategyHelper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.core.util.AnnotationUtils; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.jpa.impl.entitymanager.EntityManagerMetadata; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Any; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import jakarta.persistence.EntityManager; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Helper which provides utility methods for any * {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy}. */ @Dependent public class TransactionStrategyHelper implements Serializable { private static final long serialVersionUID = -6272327391611428125L; @Inject private BeanManager beanManager; /** *

This method uses the InvocationContext to scan the @Transactional * interceptor for a manually specified Qualifier.

* *

If none is given (defaults to Any.class) then we scan the intercepted * instance and resolve the Qualifiers of all it's injected EntityManagers.

* *

Please note that we will only pickup the first Qualifier on the * injected EntityManager. We also do not parse for binding or * &h#064;NonBinding values. A @Qualifier should not have any parameter at all.

* @param entityManagerMetadata the metadata to locate the entity manager * @param interceptedTargetClass the Class of the intercepted target */ public Set> resolveEntityManagerQualifiers(EntityManagerMetadata entityManagerMetadata, Class interceptedTargetClass) { Set> emQualifiers = new HashSet<>(); Class[] qualifierClasses = entityManagerMetadata.getQualifiers(); if (qualifierClasses == null || qualifierClasses.length == 1 && Any.class.equals(qualifierClasses[0]) ) { // this means we have no special EntityManager configured in the interceptor // thus we should scan all the EntityManagers ourselfs from the intercepted class collectEntityManagerQualifiersOnClass(emQualifiers, interceptedTargetClass); } else { // take the qualifierKeys from the qualifierClasses Collections.addAll(emQualifiers, qualifierClasses); } //see DELTASPIKE-320 if (emQualifiers.isEmpty()) { emQualifiers.add(Default.class); } return emQualifiers; } /** * Scan the given class and return all the injected EntityManager fields. *

Attention: we do only pick up EntityManagers which use @Inject!

*/ private void collectEntityManagerQualifiersOnClass(Set> emQualifiers,Class target) { // first scan all declared fields Field[] fields = target.getDeclaredFields(); for (Field field : fields) { if (EntityManager.class.equals(field.getType())) { // also check if this is an injected EM if (field.getAnnotation(Inject.class) != null) { boolean qualifierFound = false; Class qualifier = getFirstQualifierAnnotation(field.getAnnotations()); if (qualifier != null) { emQualifiers.add(qualifier); qualifierFound = true; } if (!qualifierFound) { // according to the CDI injection rules @Default is assumed emQualifiers.add(Default.class); } } } } // finally recurse into the superclasses Class superClass = target.getSuperclass(); if (!Object.class.equals(superClass)) { collectEntityManagerQualifiersOnClass(emQualifiers, superClass); } } /** * Extract the first CDI-Qualifier Annotation from the given annotations array */ private Class getFirstQualifierAnnotation(Annotation[] annotations) { for (Annotation ann : annotations) { if (beanManager.isQualifier(ann.annotationType())) { return ann.annotationType(); } } return null; } EntityManagerMetadata createEntityManagerMetadata(InvocationContext context) { EntityManagerMetadata metadata = new EntityManagerMetadata(); metadata.readFrom(context.getMethod().getDeclaringClass(), beanManager); metadata.readFrom(context.getMethod(), beanManager); return metadata; } /** * @return the @Transactional annotation from either the method or class * or null if none present. */ protected Transactional extractTransactionalAnnotation(InvocationContext context) { Class targetClass = context.getTarget() != null ? context.getTarget().getClass() : context.getMethod().getDeclaringClass(); return AnnotationUtils .extractAnnotationFromMethodOrClass(beanManager, context.getMethod(), targetClass, Transactional.class); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/TransactionalInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import jakarta.annotation.Priority; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; /** * Interceptor for wrapping transactional database requests. * This interceptor itself doesn't contain any functionality. * Instead the 'real' work is done inside a pluggable * {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy}. */ @Interceptor @Transactional @Priority(1000) public class TransactionalInterceptor implements Serializable { private static final long serialVersionUID = 8787285444722371172L; @Inject private TransactionStrategy transactionStrategy; /** * Creates a transaction before the intercepted method gets called and commits or reverts it after the invocation. * A {@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} * is allowed to begin the transaction lazily but it has to support nested interceptor calls. * * @param invocationContext current invocation-context * @return result of the intercepted method * @throws Exception exception which might be thrown by the intercepted method */ @AroundInvoke public Object executeInTransaction(InvocationContext invocationContext) throws Exception { return transactionStrategy.execute(invocationContext); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/UserTransactionResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.core.impl.util.JndiUtils; import org.apache.deltaspike.jpa.api.config.base.JpaBaseConfig; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.transaction.UserTransaction; import java.io.Serializable; //the separated logic allows a lazy lookup of this bean and //avoids that the injection of UserTransaction fails in an unmanaged thread (see DELTASPIKE-917). @Dependent public class UserTransactionResolver implements Serializable { private static final long serialVersionUID = -1432802805095533499L; @Inject private BeanManager beanManager; public UserTransaction resolveUserTransaction() { UserTransaction userTransaction; try { DependentProvider provider = BeanProvider.getDependent(this.beanManager, ManagedUserTransactionResolver.class); userTransaction = provider.get().resolveUserTransaction(); provider.destroy(); } catch (Throwable t) { //it was just a try userTransaction = null; } if (userTransaction != null) { return userTransaction; } String jndiName = JpaBaseConfig.UserTransaction.JNDI_NAME; String[] jndiNames = jndiName.split(","); for (String currentJndiName : jndiNames) { try { userTransaction = JndiUtils.lookup(currentJndiName, UserTransaction.class); if (userTransaction != null) { break; } } catch (Exception e) { userTransaction = null; } } return userTransaction; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/context/EntityManagerEntry.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction.context; import jakarta.enterprise.inject.Vetoed; import jakarta.persistence.EntityManager; import java.lang.annotation.Annotation; /** * Stores a {@link EntityManager} and the qualifier */ @Vetoed public class EntityManagerEntry { private final EntityManager entityManager; //TODO DELTASPIKE-259 - use the annotation itself + calculate a key for #hashCode and #equals private Class qualifier; public EntityManagerEntry(EntityManager entityManager, Class qualifier) { this.entityManager = entityManager; this.qualifier = qualifier; } public EntityManager getEntityManager() { return entityManager; } //can be used e.g. by a custom strategy for logging,... @SuppressWarnings("UnusedDeclaration") public Class getQualifier() { return qualifier; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } EntityManagerEntry that = (EntityManagerEntry) o; if (!qualifier.equals(that.qualifier)) { return false; } return true; } @Override public int hashCode() { return qualifier.hashCode(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/context/TransactionBeanEntry.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction.context; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Vetoed; /** * Holds the information we need store to manage * the beans in the {@link TransactionContext}. */ @Vetoed public class TransactionBeanEntry { private Contextual bean; private T contextualInstance; private CreationalContext creationalContext; public TransactionBeanEntry(Contextual bean, T contextualInstance, CreationalContext creationalContext) { this.bean = bean; this.contextualInstance = contextualInstance; this.creationalContext = creationalContext; } public Contextual getBean() { return bean; } public T getContextualInstance() { return contextualInstance; } public CreationalContext getCreationalContext() { return creationalContext; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/context/TransactionBeanStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction.context; import jakarta.enterprise.context.spi.Contextual; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.Stack; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; /** *

This class stores information about * @{@link org.apache.deltaspike.jpa.api.transaction.TransactionScoped} * contextual instances, their {@link jakarta.enterprise.context.spi.CreationalContext} etc.

* *

We use a RequestScoped bean because this way we don't need to take * care about cleaning up any ThreadLocals ourselves. This also makes sure that * we subsequently destroy any left over TransactionScoped beans (which should not happen, * but who knows). We also don't need to do any fancy synchronization stuff since * we are sure that we are always in the same Thread.

*/ public class TransactionBeanStorage { private static final Logger LOGGER = Logger.getLogger(TransactionBeanStorage.class.getName()); private static ThreadLocal transactionBeanStorage = new ThreadLocal(); private static class TransactionContextInfo { /** * This is the actual bean storage. * The structure is: *
    *
  1. transactionKey identifies the 'database qualifier'
  2. *
  3. transactionKey -> Stack: we need the Stack because of REQUIRES_NEW, etc
  4. *
  5. top Element in the Stack -> Context beans for the transactionKey
  6. *
* */ private Map contextualInstances = new HashMap(); private Set ems = new HashSet(); /** * counts the 'depth' of the interceptor invocation. */ private AtomicInteger refCounter = new AtomicInteger(0); } /** * If we hit a layer with REQUIRES_NEW, then create a new TransactionContextInfo * and push the old one on top of this stack. */ private Stack oldTci = new Stack(); /** * The TransactionContextInfo which is on top of the stack. */ private TransactionContextInfo currentTci = null; private TransactionBeanStorage() { } public static TransactionBeanStorage getInstance() { TransactionBeanStorage result = transactionBeanStorage.get(); if (result == null) { result = new TransactionBeanStorage(); transactionBeanStorage.set(result); } return result; } public static void close() { TransactionBeanStorage currentStorage = transactionBeanStorage.get(); if (currentStorage != null) { currentStorage.endAllTransactionScopes(); transactionBeanStorage.set(null); transactionBeanStorage.remove(); } } public static boolean isOpen() { return transactionBeanStorage.get() != null; } /** * Increment the ref counter and return the old value. * Must only be called if the bean storage is not {@link #isEmpty()}. * * @return the the previous values of the refCounters. If 0 then we are 'outermost' */ public int incrementRefCounter() { return currentTci.refCounter.incrementAndGet() - 1; } /** * Decrement the reference counter and return the layer. * * @return the layer number. 0 represents the outermost interceptor for the qualifier */ public int decrementRefCounter() { if (currentTci == null) { return 0; } return currentTci.refCounter.decrementAndGet(); } /** * @return true if we are the outermost interceptor over all qualifiers * and the TransactionBeanStorage is yet empty. */ public boolean isEmpty() { return currentTci == null; } /** * Start a new TransactionScope */ public void startTransactionScope() { // first store away any previous TransactionContextInfo if (currentTci != null) { oldTci.push(currentTci); } currentTci = new TransactionContextInfo(); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer( "starting TransactionScope"); } } /** * End the TransactionScope with the given qualifier. * This will subsequently destroy all beans which are stored * in the context. * * This method only gets used if we leave a transaction with REQUIRES_NEW. */ public void endTransactionScope() { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("ending TransactionScope"); } destroyBeans(currentTci.contextualInstances); if (!oldTci.isEmpty()) { currentTci = oldTci.pop(); endTransactionScope(); } else { currentTci = null; } } public void storeUsedEntityManager(EntityManagerEntry entityManagerEntry) { currentTci.ems.add(entityManagerEntry); } public Set getUsedEntityManagerEntries() { return currentTci.ems; } public void cleanUsedEntityManagers() { currentTci.ems.clear(); } /** * @return the Map which represents the currently active Context content. */ public Map getActiveTransactionContext() { if (currentTci == null) { return null; } return currentTci.contextualInstances; } private void endAllTransactionScopes() { while (!isEmpty()) { endTransactionScope(); } } /** * Properly destroy all the given beans. * @param activeBeans to destroy */ private void destroyBeans(Map activeBeans) { for (TransactionBeanEntry beanEntry : activeBeans.values()) { beanEntry.getBean().destroy(beanEntry.getContextualInstance(), beanEntry.getCreationalContext()); } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/context/TransactionContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction.context; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.context.spi.Context; import jakarta.enterprise.context.spi.Contextual; import jakarta.enterprise.context.spi.CreationalContext; import java.lang.annotation.Annotation; import java.util.Map; /** * CDI Context for managing @{@link org.apache.deltaspike.jpa.api.transaction.TransactionScoped} * contextual instances. */ public class TransactionContext implements Context { public T get(Contextual component) { Map transactionBeanEntryMap = TransactionBeanStorage.getInstance().getActiveTransactionContext(); if (transactionBeanEntryMap == null) { TransactionBeanStorage.close(); throw new ContextNotActiveException("Not accessed within a transactional method - use @" + Transactional.class.getName()); } TransactionBeanEntry transactionBeanEntry = transactionBeanEntryMap.get(component); if (transactionBeanEntry != null) { return (T) transactionBeanEntry.getContextualInstance(); } return null; } public T get(Contextual component, CreationalContext creationalContext) { Map transactionBeanEntryMap = TransactionBeanStorage.getInstance().getActiveTransactionContext(); if (transactionBeanEntryMap == null) { TransactionBeanStorage.close(); throw new ContextNotActiveException("Not accessed within a transactional method - use @" + Transactional.class.getName()); } TransactionBeanEntry transactionBeanEntry = transactionBeanEntryMap.get(component); if (transactionBeanEntry != null) { return (T) transactionBeanEntry.getContextualInstance(); } // if it doesn't yet exist, we need to create it now! T instance = component.create(creationalContext); transactionBeanEntry = new TransactionBeanEntry(component, instance, creationalContext); transactionBeanEntryMap.put(component, transactionBeanEntry); return instance; } public Class getScope() { return TransactionScoped.class; } public boolean isActive() { try { return TransactionBeanStorage.isOpen() && TransactionBeanStorage.getInstance().getActiveTransactionContext() != null; } catch (ContextNotActiveException e) { return false; } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/context/TransactionContextExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jpa.impl.transaction.context; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; /** * CDI Extension which registers and manages the {@link TransactionContext}. */ public class TransactionContextExtension implements Extension, Deactivatable { private Boolean isActivated = true; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); } /** * Register the TransactionContext as a CDI Context * * @param afterBeanDiscovery after-bean-discovery event */ protected void registerTransactionContext(@Observes AfterBeanDiscovery afterBeanDiscovery) { if (!isActivated) { return; } TransactionContext transactionContext = new TransactionContext(); afterBeanDiscovery.addContext(transactionContext); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/main/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # deltaspike_ordinal=50 deltaspike.jpa.user-transaction.jndi-name=java:comp/UserTransaction,java:/jboss/UserTransaction ================================================ FILE: deltaspike/modules/jpa/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jpa/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension org.apache.deltaspike.jpa.impl.descriptor.xml.PersistenceUnitDescriptorInitExtension ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/entitymanager/EntityManagerFactoryProducerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.entitymanager; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import jakarta.persistence.spi.PersistenceProviderResolverHolder; import org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; 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.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(SeCategory.class) public class EntityManagerFactoryProducerTest { @Deployment public static WebArchive deploy() { // set the dummy PersistenceProviderResolver which creates our DummyEntityManagerFactory PersistenceProviderResolverHolder.setPersistenceProviderResolver(new TestPersistenceProviderResolver()); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "unitDefinitionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(EntityManagerFactoryProducerTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") .addAsResource(new StringAsset(TestPersistenceProviderResolver.class.getName()), "META-INF/services/jakarta.persistence.spi.PersistenceProviderResolver"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Inject @SampleDb private EntityManager entityManager; private @Inject PersistenceConfigurationProvider persistenceConfigurationProvider; @Test public void testUnitDefinitionQualifier() throws Exception { Assert.assertNotNull(entityManager); Assert.assertNotNull(entityManager.getDelegate()); Assert.assertTrue(entityManager.getDelegate() instanceof TestEntityManager); TestEntityManager tem = (TestEntityManager) entityManager.getDelegate(); Assert.assertEquals("testPersistenceUnit", tem.getUnitName()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/entitymanager/PersistenceConfigurationProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.entitymanager; import jakarta.inject.Inject; import jakarta.persistence.spi.PersistenceProviderResolverHolder; import java.util.Properties; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.jpa.spi.entitymanager.PersistenceConfigurationProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(SeCategory.class) public class PersistenceConfigurationProviderTest { @Deployment public static WebArchive deploy() { // set the dummy PersistenceProviderResolver which creates our DummyEntityManagerFactory PersistenceProviderResolverHolder.setPersistenceProviderResolver(new TestPersistenceProviderResolver()); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "unitDefinitionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addClass(PersistenceConfigurationProviderTest.class) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } private @Inject PersistenceConfigurationProvider persistenceConfigurationProvider; @Test public void testPersistenceConfigurationProvider() { Properties myUnitConfig = persistenceConfigurationProvider.getEntityManagerFactoryConfiguration("MyUnit"); Assert.assertEquals(4, myUnitConfig.size()); Assert.assertEquals(BeanManagerProvider.getInstance().getBeanManager(), myUnitConfig.get("jakarta.persistence.bean.manager")); Assert.assertEquals("blub", myUnitConfig.get("jakarta.persistence.jdbc.password")); Assert.assertEquals("sa", myUnitConfig.get("jakarta.persistence.jdbc.user")); Assert.assertEquals("some.jdbc.Driver", myUnitConfig.get("jakarta.persistence.jdbc.driver")); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/entitymanager/SampleDb.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.entitymanager; import jakarta.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; 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 static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Sample Database Qualifier */ @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(value= RUNTIME) @Qualifier public @interface SampleDb { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/entitymanager/SampleEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.entitymanager; import org.apache.deltaspike.jpa.api.entitymanager.PersistenceUnitName; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import jakarta.persistence.EntityManagerFactory; /** * Sample producer for a @SampleDb EntityManager. */ @ApplicationScoped @SuppressWarnings("unused") public class SampleEntityManagerProducer { @Inject @PersistenceUnitName("testPersistenceUnit") private EntityManagerFactory emf; @Produces @RequestScoped @SampleDb public TestEntityManager /*needed by weld - see DS-315*/ createEntityManager() { return (TestEntityManager)emf.createEntityManager(); } public void closeEm(@Disposes @SampleDb TestEntityManager em) { em.close(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/entitymanager/TestPersistenceProviderResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.entitymanager; import jakarta.enterprise.inject.Vetoed; import jakarta.persistence.Cache; import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.PersistenceUnitUtil; import jakarta.persistence.Query; import jakarta.persistence.SynchronizationType; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.metamodel.Metamodel; import jakarta.persistence.spi.PersistenceProvider; import jakarta.persistence.spi.PersistenceProviderResolver; import jakarta.persistence.spi.PersistenceUnitInfo; import jakarta.persistence.spi.ProviderUtil; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; /** * PersistenceProviderResolver for dummy PersistenceProviders. */ @Vetoed public class TestPersistenceProviderResolver implements PersistenceProviderResolver { private List persistenceProviders; public TestPersistenceProviderResolver() { this.persistenceProviders = new ArrayList(); this.persistenceProviders.add(new DummyPersistenceProvider()); } @Override public void clearCachedProviders() { } @Override public List getPersistenceProviders() { return persistenceProviders; } @Vetoed public static class DummyPersistenceProvider implements PersistenceProvider { @Override public EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map) { return new DummyEntityManagerFactory(); } @Override public EntityManagerFactory createEntityManagerFactory(String emName, Map map) { return new DummyEntityManagerFactory(emName, map); } @Override public ProviderUtil getProviderUtil() { return null; } @Override public void generateSchema(PersistenceUnitInfo arg0, Map arg1) { } @Override public boolean generateSchema(String arg0, Map arg1) { return true; } } @Vetoed public static class DummyEntityManagerFactory implements EntityManagerFactory { private final String emName; private final Map map; public DummyEntityManagerFactory() { this.emName = null; this.map = null; } public DummyEntityManagerFactory(String emName, Map map) { this.emName = emName; this.map = map; } @Override public void close() { } @Override public EntityManager createEntityManager() { return new TestEntityManager(emName); } @Override public EntityManager createEntityManager(Map map) { return new TestEntityManager(emName); } @Override public CriteriaBuilder getCriteriaBuilder() { return null; } @Override public Metamodel getMetamodel() { return null; } @Override public boolean isOpen() { return false; } @Override public Map getProperties() { return map; } @Override public Cache getCache() { return null; } @Override public PersistenceUnitUtil getPersistenceUnitUtil() { return null; } @Override public EntityManager createEntityManager(SynchronizationType arg0) { return null; } @Override public EntityManager createEntityManager(SynchronizationType arg0, Map arg1) { return null; } @Override public void addNamedQuery(String arg0, Query arg1) { } @Override public T unwrap(Class arg0) { return null; } @Override public void addNamedEntityGraph(String arg0, EntityGraph arg1) { } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/shared/First.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.shared; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; 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.RetentionPolicy.RUNTIME; @Target({ FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Documented //cdi annotations @Qualifier public @interface First { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/shared/Second.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.shared; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; 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.RetentionPolicy.RUNTIME; @Target({ FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Documented //cdi annotations @Qualifier public @interface Second { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/shared/TestEntityManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.shared; import jakarta.enterprise.inject.Vetoed; import jakarta.persistence.EntityGraph; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.FlushModeType; import jakarta.persistence.LockModeType; import jakarta.persistence.Query; import jakarta.persistence.StoredProcedureQuery; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaDelete; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.CriteriaUpdate; import jakarta.persistence.metamodel.Metamodel; import java.util.List; import java.util.Map; @Vetoed public class TestEntityManager implements EntityManager { private EntityTransaction entityTransaction = new TestEntityTransaction(this); private boolean open = true; private boolean flushed = false; private String unitName = null; public TestEntityManager() { } public TestEntityManager(String name) { this.unitName = name; } public String getUnitName() { return unitName; } @Override public void persist(Object entity) { throw new IllegalStateException("not implemented"); } @Override public T merge(T entity) { throw new IllegalStateException("not implemented"); } @Override public void remove(Object entity) { throw new IllegalStateException("not implemented"); } @Override public T find(Class entityClass, Object primaryKey) { throw new IllegalStateException("not implemented"); } @Override public T find(Class entityClass, Object primaryKey, Map properties) { throw new IllegalStateException("not implemented"); } @Override public T find(Class entityClass, Object primaryKey, LockModeType lockMode) { throw new IllegalStateException("not implemented"); } @Override public T find(Class entityClass, Object primaryKey, LockModeType lockMode, Map properties) { throw new IllegalStateException("not implemented"); } @Override public T getReference(Class entityClass, Object primaryKey) { throw new IllegalStateException("not implemented"); } @Override public void flush() { flushed = true; } @Override public void setFlushMode(FlushModeType flushMode) { throw new IllegalStateException("not implemented"); } @Override public FlushModeType getFlushMode() { throw new IllegalStateException("not implemented"); } @Override public void lock(Object entity, LockModeType lockMode) { throw new IllegalStateException("not implemented"); } @Override public void lock(Object entity, LockModeType lockMode, Map properties) { throw new IllegalStateException("not implemented"); } @Override public void refresh(Object entity) { throw new IllegalStateException("not implemented"); } @Override public void refresh(Object entity, Map properties) { throw new IllegalStateException("not implemented"); } @Override public void refresh(Object entity, LockModeType lockMode) { throw new IllegalStateException("not implemented"); } @Override public void refresh(Object entity, LockModeType lockMode, Map properties) { throw new IllegalStateException("not implemented"); } @Override public void clear() { throw new IllegalStateException("not implemented"); } @Override public void detach(Object entity) { throw new IllegalStateException("not implemented"); } @Override public boolean contains(Object entity) { throw new IllegalStateException("not implemented"); } @Override public LockModeType getLockMode(Object entity) { throw new IllegalStateException("not implemented"); } @Override public void setProperty(String propertyName, Object value) { throw new IllegalStateException("not implemented"); } @Override public Map getProperties() { throw new IllegalStateException("not implemented"); } @Override public Query createQuery(String qlString) { throw new IllegalStateException("not implemented"); } @Override public TypedQuery createQuery(CriteriaQuery criteriaQuery) { throw new IllegalStateException("not implemented"); } @Override public TypedQuery createQuery(String qlString, Class resultClass) { throw new IllegalStateException("not implemented"); } @Override public Query createNamedQuery(String name) { throw new IllegalStateException("not implemented"); } @Override public TypedQuery createNamedQuery(String name, Class resultClass) { throw new IllegalStateException("not implemented"); } @Override public Query createNativeQuery(String sqlString) { throw new IllegalStateException("not implemented"); } @Override public Query createNativeQuery(String sqlString, Class resultClass) { throw new IllegalStateException("not implemented"); } @Override public Query createNativeQuery(String sqlString, String resultSetMapping) { throw new IllegalStateException("not implemented"); } @Override public void joinTransaction() { // all fine, nothing to do } @Override public T unwrap(Class cls) { throw new IllegalStateException("not implemented"); } @Override public Object getDelegate() { return this; } @Override public void close() { if (!open) { throw new IllegalStateException("entity manager is closed already"); } open = false; } @Override public boolean isOpen() { return open; } @Override public EntityTransaction getTransaction() { return entityTransaction; } @Override public EntityManagerFactory getEntityManagerFactory() { throw new IllegalStateException("not implemented"); } @Override public CriteriaBuilder getCriteriaBuilder() { throw new IllegalStateException("not implemented"); } @Override public Metamodel getMetamodel() { throw new IllegalStateException("not implemented"); } public boolean isFlushed() { return flushed; } public void setFlushed(boolean flushed) { this.flushed = flushed; } @Override public Query createQuery(CriteriaUpdate arg0) { throw new IllegalStateException("not implemented"); } @Override public Query createQuery(CriteriaDelete arg0) { throw new IllegalStateException("not implemented"); } @Override public StoredProcedureQuery createNamedStoredProcedureQuery(String arg0) { throw new IllegalStateException("not implemented"); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0) { throw new IllegalStateException("not implemented"); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0, Class... arg1) { throw new IllegalStateException("not implemented"); } @Override public StoredProcedureQuery createStoredProcedureQuery(String arg0, String... arg1) { throw new IllegalStateException("not implemented"); } @Override public boolean isJoinedToTransaction() { throw new IllegalStateException("not implemented"); } @Override public EntityGraph createEntityGraph(Class arg0) { throw new IllegalStateException("not implemented"); } @Override public EntityGraph createEntityGraph(String arg0) { throw new IllegalStateException("not implemented"); } @Override public EntityGraph getEntityGraph(String arg0) { throw new IllegalStateException("not implemented"); } @Override public List> getEntityGraphs(Class arg0) { throw new IllegalStateException("not implemented"); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/shared/TestEntityTransaction.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.shared; import jakarta.persistence.EntityTransaction; public class TestEntityTransaction implements EntityTransaction { private boolean started = false; private boolean committed = false; private boolean rolledBack = false; private boolean markRolledBack = false; private TestEntityManager testEntityManager; public TestEntityTransaction(TestEntityManager testEntityManager) { this.testEntityManager = testEntityManager; } @Override public void begin() { if (started) { throw new IllegalStateException("transaction started already"); } started = true; } @Override public void commit() { committed = true; testEntityManager.setFlushed(true); } @Override public void rollback() { rolledBack = true; } @Override public void setRollbackOnly() { this.markRolledBack = true; } @Override public boolean getRollbackOnly() { return this.markRolledBack; } @Override public boolean isActive() { return started && !(committed || rolledBack); } public boolean isStarted() { return started; } public boolean isCommitted() { return committed; } public boolean isRolledBack() { return rolledBack; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/shared/TestException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.shared; public class TestException extends RuntimeException { private static final long serialVersionUID = -3719932856173828526L; } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/aggregation/AggregatedDefaultEntityManagerInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.aggregation; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class AggregatedDefaultEntityManagerInjectionTest { @Inject private TransactionalBean transactionalBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "aggregatedDefaultInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(AggregatedDefaultEntityManagerInjectionTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void defaultEntityManagerInjection() { EntityManager injectedEntityManager = entityManagerProducer.getDefaultEntityManager(); Assert.assertNotNull(injectedEntityManager); Assert.assertTrue(injectedEntityManager instanceof TestEntityManager); TestEntityTransaction testTransaction = (TestEntityTransaction) (injectedEntityManager).getTransaction(); Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(false, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); transactionalBean.executeInTransaction(); Assert.assertEquals(true, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/aggregation/BeanA.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.aggregation; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class BeanA { @Inject private EntityManager entityManager; public void doA() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/aggregation/BeanB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.aggregation; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class BeanB { @Inject private EntityManager entityManager; public void doB() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/aggregation/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.aggregation; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/aggregation/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.aggregation; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class TransactionalBean { @Inject private BeanA beanA; @Inject private BeanB beanB; @Transactional public void executeInTransaction() { beanA.doA(); beanB.doB(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/DefaultEntityManagerInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class DefaultEntityManagerInjectionTest { @Inject private TransactionalBean transactionalBean; @Inject @Failed private TransactionalBean failedTransactionalBean; @Inject private FailedFlushTransactionalBean failedFlushTransactionalBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(DefaultEntityManagerInjectionTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void defaultEntityManagerInjection() { EntityManager injectedEntityManager = entityManagerProducer.getDefaultEntityManager(); Assert.assertNotNull(injectedEntityManager); Assert.assertTrue(injectedEntityManager instanceof TestEntityManager); TestEntityTransaction testTransaction = (TestEntityTransaction) (injectedEntityManager).getTransaction(); Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(false, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); transactionalBean.executeInTransaction(); Assert.assertEquals(true, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } @Test public void defaultEntityManagerInjectionFailedTransaction() { EntityManager injectedEntityManager = entityManagerProducer.getDefaultEntityManager(); Assert.assertNotNull(injectedEntityManager); Assert.assertTrue(injectedEntityManager instanceof TestEntityManager); TestEntityTransaction testTransaction = (TestEntityTransaction) (injectedEntityManager).getTransaction(); Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(false, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); try { failedTransactionalBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected } Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(true, testTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } @Test public void defaultEntityManagerInjectionFailedFlush() { EntityManager injectedEntityManager = entityManagerProducer.getFailedFlushEntityManager(); Assert.assertNotNull(injectedEntityManager); Assert.assertTrue(injectedEntityManager instanceof TestEntityManager); TestEntityTransaction testTransaction = (TestEntityTransaction) (injectedEntityManager).getTransaction(); Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(false, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); try { failedFlushTransactionalBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected } Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(true, testTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/Failed.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ FIELD, METHOD, TYPE }) @Retention(RUNTIME) @Documented //cdi annotations @Qualifier public @interface Failed { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/FailedFlushTransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FailedFlushTransactionalBean { @Inject @Failed private EntityManager entityManager; @Inject private EntityManager validEntityManager; //just needed, because we only flush in case of multiple entity-managers @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/FailedTransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; @Failed @ApplicationScoped public class FailedTransactionalBean extends TransactionalBean { @Override @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager failedFlushEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @Failed protected EntityManager failedFlushEntityManager() { return failedFlushEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFailedFlushEntityManager() { return failedFlushEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultinjection/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultinjection; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped @Transactional(readOnly = true) public class TransactionalBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultnested/DefaultNestedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultnested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(SeCategory.class) public class DefaultNestedTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultNestedTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(DefaultNestedTransactionTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void defaultNestedTransaction() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultnested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultnested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private EntityManager entityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultnested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultnested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/defaultnested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.defaultnested; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); @Produces protected EntityManager firstEntityManager() { return firstEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/multipleinjection/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { try { nestedTransactionBean.executeInTransaction(); } catch (TestException e) { //expected -> do nothing } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/multipleinjection/nested/NestedMultiTransactionCatchedExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.multipleinjection.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionCatchedExceptionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionCatchedExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionCatchedExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionCatchedExceptionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/multipleinjection/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/multipleinjection/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.multipleinjection.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { try { nestedTransactionBean.executeInTransaction(); } catch (TestException e) { //catch to test that the transaction doesn't get rolled back //do nothing } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @First EntityManager firstEntityManager; @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/nested/NestedTransactionCatchedExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedTransactionCatchedExceptionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedTransactionCatchedExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedTransactionCatchedExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedTransactionCatchedExceptionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/catched/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.catched.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.auto; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/auto/UncatchedExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class UncatchedExceptionTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionUncatchedExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(UncatchedExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionUncatchedExceptionTest() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); try { multiTransactionBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected -> do nothing } Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.auto; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; private TestEntityManager firstEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; private TestEntityManager secondEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/auto/UncatchedFlushExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class UncatchedFlushExceptionTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionUncatchedFlushExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(UncatchedFlushExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionUncatchedFlushExceptionTest() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); try { multiTransactionBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected -> do nothing } Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; private TestEntityManager secondEntityManager = new TestEntityManager() { @Override public void flush() { throw new TestException(); } }; @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/flush/nested/UncatchedFlushExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.flush.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class UncatchedFlushExceptionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionUncatchedFlushExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(UncatchedFlushExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionUncatchedFlushExceptionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); try { firstLevelTransactionBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected -> do nothing } Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/multipleinjection/nested/UncatchedExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.multipleinjection.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class UncatchedExceptionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionUncatchedExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(UncatchedExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionUncatchedExceptionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); try { firstLevelTransactionBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected -> do nothing } Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @First EntityManager firstEntityManager; @Transactional public void executeInTransaction() { throw new TestException(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/nested/NestedTransactionWithExceptionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.jpa.api.shared.TestException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedTransactionWithExceptionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedTransactionWithExceptionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedTransactionWithExceptionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedTransactionWithExceptionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); try { firstLevelTransactionBean.executeInTransaction(); Assert.fail(TestException.class.getName() + " expected!"); } catch (TestException e) { //expected } Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/exception/uncatched/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.exception.uncatched.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransactionRollbackDefault() { this.defaultEntityManager.getTransaction().setRollbackOnly(); } @Transactional public void executeInTransactionRollback1() { this.firstEntityManager.getTransaction().setRollbackOnly(); } @Transactional public void executeInTransactionRollback2() { this.secondEntityManager.getTransaction().setRollbackOnly(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/auto/RollbackOnly1Test.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; //different classes needed due to arquillian restriction @RunWith(Arquillian.class) @Category(SeCategory.class) public class RollbackOnly1Test { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionRollbackOnly1Test.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(RollbackOnly1Test.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionRollbackOnly1Test() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); multiTransactionBean.executeInTransactionRollback1(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/auto/RollbackOnly2Test.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; //different classes needed due to arquillian restriction @RunWith(Arquillian.class) @Category(SeCategory.class) public class RollbackOnly2Test { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionRollbackOnly2Test.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(RollbackOnly2Test.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionRollbackOnly2Test() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); multiTransactionBean.executeInTransactionRollback2(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/auto/RollbackOnlyTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; //different classes needed due to arquillian restriction @RunWith(Arquillian.class) @Category(SeCategory.class) public class RollbackOnlyTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionRollbackOnlyTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(RollbackOnlyTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionRollbackOnlyDefaultTest() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); multiTransactionBean.executeInTransactionRollbackDefault(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.auto; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/nested/NestedMultiTransactionRollbackOnlyTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionRollbackOnlyTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionRollbackOnlyTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionRollbackOnlyTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionRollbackOnlyTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { secondEntityManager.getTransaction().setRollbackOnly(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/getRollbackOnly/multipleinjection/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.getRollbackOnly.multipleinjection.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/auto/MultipleEntityManagerInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class MultipleEntityManagerInjectionTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(MultipleEntityManagerInjectionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoEntityManagerInjection() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); multiTransactionBean.executeInTransaction(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(true, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.auto; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/manual/BeanManagedlTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.manual; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; /** * Same test as {@link ManualTransactionTest} but now with a UserTransaction instead * of manual EM Tx. */ @RunWith(Arquillian.class) @Category(SeCategory.class) public class BeanManagedlTransactionTest { private static Asset beansXml = new StringAsset( "" + "" + "org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy" + "" + "" ); @Inject private ManualTransactionBean manualTransactionBean; @Inject private MockUserTransactionResolver mockTxResolver; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "manualTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(BeanManagedlTransactionTest.class.getPackage().getName()) .addAsManifestResource(beansXml, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void manualTransactionTest() { mockTxResolver.resetTx(); MockUserTransactionResolver.MockUserTransaction mockTx = mockTxResolver.resolveUserTransaction(); manualTransactionBean.executeInTransaction(); Assert.assertEquals(false, mockTx.isActive()); Assert.assertEquals(true, mockTx.isBegin()); Assert.assertEquals(true, mockTx.isCommit()); Assert.assertEquals(false, mockTx.isRollback()); Assert.assertEquals(false, mockTx.isRollBackOnly()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/manual/ManualTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.manual; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class ManualTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional(qualifier = Default.class) public void executeInDefaultTransaction() { } @Transactional(qualifier = First.class) public void executeInFirstTransaction() { } @Transactional(qualifier = Second.class) public void executeInSecondTransaction() { } @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/manual/ManualTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.manual; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ManualTransactionTest { @Inject private ManualTransactionBean manualTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "manualTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(ManualTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void manualTransactionTest() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); manualTransactionBean.executeInDefaultTransaction(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(true, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); manualTransactionBean.executeInFirstTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); manualTransactionBean.executeInSecondTransaction(); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/manual/MockUserTransactionResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.manual; import org.apache.deltaspike.jpa.impl.transaction.ManagedUserTransactionResolver; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; import jakarta.transaction.HeuristicMixedException; import jakarta.transaction.HeuristicRollbackException; import jakarta.transaction.NotSupportedException; import jakarta.transaction.RollbackException; import jakarta.transaction.Status; import jakarta.transaction.SystemException; import jakarta.transaction.UserTransaction; @Specializes @ApplicationScoped public class MockUserTransactionResolver extends ManagedUserTransactionResolver { private MockUserTransaction mockTx; @PostConstruct public void resetTx() { mockTx = new MockUserTransaction(); } @Override public MockUserTransaction resolveUserTransaction() { return mockTx; } public static class MockUserTransaction implements UserTransaction { private boolean begin = false; private boolean commit = false; private boolean rollback = false; private boolean rollBackOnly =false; private int status = Status.STATUS_NO_TRANSACTION; @Override public void begin() throws NotSupportedException, SystemException { this.begin = true; this.status = Status.STATUS_ACTIVE; } @Override public void commit() throws HeuristicMixedException, HeuristicRollbackException, IllegalStateException, RollbackException, SecurityException, SystemException { this.commit = true; this.status = Status.STATUS_COMMITTED; } @Override public int getStatus() throws SystemException { return status; } @Override public void rollback() throws IllegalStateException, SecurityException, SystemException { this.rollback = true; this.status = Status.STATUS_ROLLEDBACK; } @Override public void setRollbackOnly() throws IllegalStateException, SystemException { this.rollBackOnly = true; this.status = Status.STATUS_MARKED_ROLLBACK; } @Override public void setTransactionTimeout(int i) throws SystemException { // do nothing } public boolean isActive() { return begin && !(commit || rollback); } public boolean isBegin() { return begin; } public boolean isCommit() { return commit; } public boolean isRollback() { return rollback; } public boolean isRollBackOnly() { return rollBackOnly; } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/manual/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.manual; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @ApplicationScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @RequestScoped protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @RequestScoped @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @RequestScoped @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/nested/NestedMultiTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/multipleinjection/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.multipleinjection.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @First EntityManager firstEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/nested/NestedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedTransaction.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedTransaction() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.nested; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/NoEntityManagerProducerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.noentitymanager; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import jakarta.inject.Inject; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NoEntityManagerProducerTest { @Inject private TransactionalBean transactionalBean; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "noEntityManagerProducer.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NoEntityManagerProducerTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void shouldFailIfNoEntityManager() { try { transactionalBean.executeInTransaction(); fail("This should fail as there is no EntityManager"); } catch (Exception e) { /* * The exception should tell the user that there is no EntityManager with the requested qualifier. The * following asserts just check for the important keywords in the message of the exception. Not a very nice * way to test this behavior but it will be sufficient to ensure the user gets all the information required * to fix the problem. */ assertTrue("Expected "+e.getMessage()+" to contain EntityManager",e.getMessage().contains("EntityManager")); assertTrue("Expected "+e.getMessage()+" to contain Second",e.getMessage().contains(Second.class.getName())); } } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.noentitymanager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager entityManager = new TestEntityManager(); /** * Producer method for an {@link EntityManager} qualified with {@link First}. */ @Produces @First protected EntityManager entityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/noentitymanager/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.noentitymanager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.EntityManager; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; @ApplicationScoped public class TransactionalBean { /** * This methods requests a transaction for the EntityManager qualified with {@link Second} although there is no * producer for such an {@link EntityManager}. */ @Transactional @EntityManagerConfig(qualifier = Second.class) public void executeInTransaction() { // no need to do anything } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional(readOnly = true) public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/auto/MultipleEntityManagerInjectionReadOnlyTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; //different classes needed due to arquillian restriction @RunWith(Arquillian.class) @Category(SeCategory.class) public class MultipleEntityManagerInjectionReadOnlyTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "multipleEntityManagerInjectionReadOnlyTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(MultipleEntityManagerInjectionReadOnlyTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoInjectionReadOnlyTest() { TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(defaultEntityManager); TestEntityTransaction defaultTransaction = (TestEntityTransaction) (defaultEntityManager).getTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(false, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); multiTransactionBean.executeInTransaction(); Assert.assertEquals(false, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(false, defaultTransaction.isCommitted()); Assert.assertEquals(true, defaultTransaction.isRolledBack()); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.auto; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager = new TestEntityManager(); private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces protected EntityManager defaultEntityManager() { return defaultEntityManager; } @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/norollback/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.norollback; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/norollback/NestedMultiTransactionReadOnlyNoRollbackTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.norollback; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionReadOnlyNoRollbackTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionReadOnlyNoRollbackTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionReadOnlyNoRollbackTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionReadOnlyNoRollbackTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/norollback/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.norollback; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional(readOnly = true) public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/norollback/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.norollback; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/rollback/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.rollback; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional(readOnly = true) public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/rollback/NestedMultiTransactionReadOnlyRollbackTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.rollback; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionReadOnlyRollbackTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionReadOnlyRollbackTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionReadOnlyRollbackTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionReadOnlyRollbackTest() { TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(false, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(false, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); firstLevelTransactionBean.executeInTransaction(); Assert.assertEquals(false, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(false, firstTransaction.isCommitted()); Assert.assertEquals(true, firstTransaction.isRolledBack()); Assert.assertEquals(false, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(false, secondTransaction.isCommitted()); Assert.assertEquals(true, secondTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/rollback/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.rollback; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/readonly/nested/rollback/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.readonly.nested.rollback; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager = new TestEntityManager(); private TestEntityManager secondEntityManager = new TestEntityManager(); @Produces @First protected EntityManager firstEntityManager() { return firstEntityManager; } @Produces @Second protected EntityManager secondEntityManager() { return secondEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/stereotype/Repository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.stereotype; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ TYPE }) @Retention(RUNTIME) @Documented //cdi annotations @Stereotype @Transactional @ApplicationScoped public @interface Repository { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/stereotype/StereotypeTransactionalTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.stereotype; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @RunWith(Arquillian.class) @Category(SeCategory.class) public class StereotypeTransactionalTest { @Inject private TransactionalBean transactionalBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "stereotypeTransactionalTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(StereotypeTransactionalTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void transactionalBeanViaStereotype() { EntityManager injectedEntityManager = entityManagerProducer.getEntityManager(); Assert.assertNotNull(injectedEntityManager); Assert.assertTrue(injectedEntityManager instanceof TestEntityManager); TestEntityTransaction testTransaction = (TestEntityTransaction) (injectedEntityManager).getTransaction(); Assert.assertEquals(false, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(false, testTransaction.isStarted()); Assert.assertEquals(false, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); transactionalBean.executeInTransaction(); Assert.assertEquals(true, ((TestEntityManager) injectedEntityManager).isFlushed()); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/stereotype/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.stereotype; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private EntityManager entityManager = new TestEntityManager(); @Produces protected EntityManager getEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/stereotype/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.stereotype; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @Repository public class TransactionalBean { @Inject private EntityManager entityManager; public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/transactionhelper/TransactionHelperTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.transactionhelper; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jpa.api.transaction.TransactionHelper; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.inject.spi.Extension; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityTransaction; import java.util.concurrent.Callable; @RunWith(Arquillian.class) @Category(SeCategory.class) public class TransactionHelperTest { @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(TransactionHelperTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Test public void testTransactionHelper() throws Exception { try { resolveEntityManager(); Assert.fail("ContextNotActiveException expected!"); } catch(ContextNotActiveException cnae) { // this was expected, all is fine! } Integer retVal = TransactionHelper.getInstance().executeTransactional( new Callable() { public Integer call() throws Exception { resolveEntityManager(); return Integer.valueOf(3); } }); Assert.assertEquals(retVal, Integer.valueOf(3)); try { resolveEntityManager(); Assert.fail("ContextNotActiveException expected!"); } catch(ContextNotActiveException cnae) { // this was expected, all is fine! } Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } private void resolveEntityManager() { EntityManager em = BeanProvider.getContextualReference(EntityManager.class); Assert.assertNotNull(em); EntityTransaction et = em.getTransaction(); Assert.assertNotNull(et); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactional/transactionhelper/TransactionScopedEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactional.transactionhelper; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; /** * This class produces and closes the EntityManager * for our {@link TransactionHelperTest} */ @Dependent public class TransactionScopedEntityManagerProducer { @Produces @TransactionScoped public EntityManager createEntityManager() { return new TestEntityManager(); } public void closeEntityManager(@Disposes EntityManager em) { em.close(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultinjection/DefaultTransactionScopedEntityManagerInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultinjection; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @RunWith(Arquillian.class) @Category(SeCategory.class) public class DefaultTransactionScopedEntityManagerInjectionTest { @Inject private TransactionalBean transactionalBean; @Inject private EntityManager entityManager; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultTransactionScopedInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(DefaultTransactionScopedEntityManagerInjectionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void defaultTransactionScopedEntityManagerInjection() { transactionalBean.executeInTransaction(); TestEntityTransaction testTransaction = (TestEntityTransaction) entityManagerProducer.getEntityManager().getTransaction(); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCount()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } @Test public void entityManagerUsageWithoutTransaction() { try { //not available because there is no transactional method entityManager.getTransaction(); Assert.fail(ContextNotActiveException.class.getName() + " expected!"); } catch (ContextNotActiveException e) { //expected } Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } @Test public void invalidEntityManagerUsageAfterTransaction() { transactionalBean.executeInTransaction(); try { //not available because there is no transactional method entityManager.getTransaction(); Assert.fail(ContextNotActiveException.class.getName() + " expected!"); } catch (ContextNotActiveException e) { //expected } Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultinjection/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultinjection; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager entityManager; private int closeEntityManagerCount = 0; @Produces @TransactionScoped protected EntityManager entityManager() { if (entityManager == null) { entityManager = new TestEntityManager(); return entityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCount++; } public int getCloseEntityManagerCount() { return closeEntityManagerCount; } public TestEntityManager getEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultinjection/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultinjection; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class TransactionalBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { //just access the transaction-scoped bean entityManager.getTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultnested/DefaultTransactionScopedNestedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultnested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class DefaultTransactionScopedNestedTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "defaultTransactionScopedNestedTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(DefaultTransactionScopedNestedTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void defaultTransactionScopedNestedTransaction() { firstLevelTransactionBean.executeInTransaction(); TestEntityTransaction testTransaction = (TestEntityTransaction) entityManagerProducer.getEntityManager().getTransaction(); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCount()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultnested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultnested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private EntityManager entityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultnested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultnested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/defaultnested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.defaultnested; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager entityManager; private int closeEntityManagerCount = 0; @Produces @TransactionScoped protected EntityManager entityManager() { if (entityManager == null) { entityManager = new TestEntityManager(); return entityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCount++; } public int getCloseEntityManagerCount() { return closeEntityManagerCount; } public TestEntityManager getEntityManager() { return entityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/auto/MultiTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.auto; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/auto/MultipleTransactionScopedEntityManagerInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.auto; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class MultipleTransactionScopedEntityManagerInjectionTest { @Inject private MultiTransactionBean multiTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "autoTransactionScopedInjectionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(MultipleTransactionScopedEntityManagerInjectionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void autoTransactionScopedEntityManagerInjection() { multiTransactionBean.executeInTransaction(); TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityTransaction defaultTransaction = (TestEntityTransaction)defaultEntityManager.getTransaction(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityTransaction firstTransaction = (TestEntityTransaction)firstEntityManager.getTransaction(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); TestEntityTransaction secondTransaction = (TestEntityTransaction)secondEntityManager.getTransaction(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(true, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountDefaultEntityManager()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountFirstEntityManager()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountSecondEntityManager()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/auto/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.auto; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager; private TestEntityManager firstEntityManager; private TestEntityManager secondEntityManager; private int closeEntityManagerCountDefaultEntityManager = 0; private int closeEntityManagerCountFirstEntityManager = 0; private int closeEntityManagerCountSecondEntityManager = 0; @Produces @TransactionScoped protected EntityManager defaultEntityManager() { if (defaultEntityManager == null) { defaultEntityManager = new TestEntityManager(); return defaultEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } @Produces @First @TransactionScoped protected EntityManager firstEntityManager() { if (firstEntityManager == null) { firstEntityManager = new TestEntityManager(); return firstEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } @Produces @Second @TransactionScoped protected EntityManager secondEntityManager() { if (secondEntityManager == null) { secondEntityManager = new TestEntityManager(); return secondEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeDefaultEntityManager(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountDefaultEntityManager++; } protected void closeFirstEntityManager(@Disposes @First EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountFirstEntityManager++; } protected void closeSecondEntityManager(@Disposes @Second EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountSecondEntityManager++; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } public int getCloseEntityManagerCountDefaultEntityManager() { return closeEntityManagerCountDefaultEntityManager; } public int getCloseEntityManagerCountFirstEntityManager() { return closeEntityManagerCountFirstEntityManager; } public int getCloseEntityManagerCountSecondEntityManager() { return closeEntityManagerCountSecondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.manual; import org.apache.deltaspike.jpa.api.entitymanager.EntityManagerConfig; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class ManualTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional(qualifier = Default.class) public void executeInDefaultTransaction() { } @Transactional @EntityManagerConfig(qualifier = First.class) public void executeInFirstTransaction() { } @Transactional(qualifier = Second.class) public void executeInSecondTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/ManualTransactionScopedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.manual; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class ManualTransactionScopedTransactionTest { @Inject private ManualTransactionBean manualTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "manualTransactionScopedTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(ManualTransactionScopedTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void manualTransactionScopedTransactionTest() { manualTransactionBean.executeInDefaultTransaction(); manualTransactionBean.executeInFirstTransaction(); manualTransactionBean.executeInSecondTransaction(); TestEntityManager defaultEntityManager = entityManagerProducer.getDefaultEntityManager(); TestEntityTransaction defaultTransaction = (TestEntityTransaction)defaultEntityManager.getTransaction(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityTransaction firstTransaction = (TestEntityTransaction)firstEntityManager.getTransaction(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); TestEntityTransaction secondTransaction = (TestEntityTransaction)secondEntityManager.getTransaction(); Assert.assertEquals(true, defaultEntityManager.isFlushed()); Assert.assertEquals(false, defaultTransaction.isActive()); Assert.assertEquals(true, defaultTransaction.isStarted()); Assert.assertEquals(true, defaultTransaction.isCommitted()); Assert.assertEquals(false, defaultTransaction.isRolledBack()); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountDefaultEntityManager()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountFirstEntityManager()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountSecondEntityManager()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/manual/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.manual; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @ApplicationScoped public class TestEntityManagerProducer { private TestEntityManager defaultEntityManager; private TestEntityManager firstEntityManager; private TestEntityManager secondEntityManager; private int closeEntityManagerCountDefaultEntityManager = 0; private int closeEntityManagerCountFirstEntityManager = 0; private int closeEntityManagerCountSecondEntityManager = 0; @Produces @TransactionScoped protected EntityManager defaultEntityManager() { if (defaultEntityManager == null) { defaultEntityManager = new TestEntityManager(); return defaultEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } @Produces @First @TransactionScoped protected EntityManager firstEntityManager() { if (firstEntityManager == null) { firstEntityManager = new TestEntityManager(); return firstEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } @Produces @Second @TransactionScoped protected EntityManager secondEntityManager() { if (secondEntityManager == null) { secondEntityManager = new TestEntityManager(); return secondEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeDefaultEntityManager(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountDefaultEntityManager++; } protected void closeFirstEntityManager(@Disposes @First EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountFirstEntityManager++; } protected void closeSecondEntityManager(@Disposes @Second EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountSecondEntityManager++; } public TestEntityManager getDefaultEntityManager() { return defaultEntityManager; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } public int getCloseEntityManagerCountDefaultEntityManager() { return closeEntityManagerCountDefaultEntityManager; } public int getCloseEntityManagerCountFirstEntityManager() { return closeEntityManagerCountFirstEntityManager; } public int getCloseEntityManagerCountSecondEntityManager() { return closeEntityManagerCountSecondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/nested/NestedMultiTransactionScopedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedMultiTransactionScopedTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedMultiTransactionScopedTransactionTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedMultiTransactionScopedTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedMultiTransactionScopedTransactionTest() { firstLevelTransactionBean.executeInTransaction(); TestEntityManager firstEntityManager = entityManagerProducer.getFirstEntityManager(); TestEntityManager secondEntityManager = entityManagerProducer.getSecondEntityManager(); Assert.assertNotNull(firstEntityManager); TestEntityTransaction firstTransaction = (TestEntityTransaction) (firstEntityManager).getTransaction(); Assert.assertNotNull(secondEntityManager); TestEntityTransaction secondTransaction = (TestEntityTransaction) (secondEntityManager).getTransaction(); Assert.assertEquals(true, firstEntityManager.isFlushed()); Assert.assertEquals(false, firstTransaction.isActive()); Assert.assertEquals(true, firstTransaction.isStarted()); Assert.assertEquals(true, firstTransaction.isCommitted()); Assert.assertEquals(false, firstTransaction.isRolledBack()); Assert.assertEquals(true, secondEntityManager.isFlushed()); Assert.assertEquals(false, secondTransaction.isActive()); Assert.assertEquals(true, secondTransaction.isStarted()); Assert.assertEquals(true, secondTransaction.isCommitted()); Assert.assertEquals(false, secondTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountFirstEntityManager()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCountSecondEntityManager()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.Second; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/multipleinjection/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.multipleinjection.nested; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.Second; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager; private TestEntityManager secondEntityManager; private int closeEntityManagerCountFirstEntityManager = 0; private int closeEntityManagerCountSecondEntityManager = 0; @Produces @First @TransactionScoped protected EntityManager firstEntityManager() { if (firstEntityManager == null) { firstEntityManager = new TestEntityManager(); return firstEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } @Produces @Second @TransactionScoped protected EntityManager secondEntityManager() { if (secondEntityManager == null) { secondEntityManager = new TestEntityManager(); return secondEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeFirstEntityManager(@Disposes @First EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountFirstEntityManager++; } protected void closeSecondEntityManager(@Disposes @Second EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCountSecondEntityManager++; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } public TestEntityManager getSecondEntityManager() { return secondEntityManager; } public int getCloseEntityManagerCountFirstEntityManager() { return closeEntityManagerCountFirstEntityManager; } public int getCloseEntityManagerCountSecondEntityManager() { return closeEntityManagerCountSecondEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/nested/FirstLevelTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { nestedTransactionBean.executeInTransaction(); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/nested/NestedTransactionBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.nested; import org.apache.deltaspike.jpa.api.transaction.Transactional; import org.apache.deltaspike.test.jpa.api.shared.First; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @ApplicationScoped public class NestedTransactionBean { @Inject private @First EntityManager firstEntityManager; @Transactional public void executeInTransaction() { } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/nested/NestedTransactionScopedTransactionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.nested; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class NestedTransactionScopedTransactionTest { @Inject private FirstLevelTransactionBean firstLevelTransactionBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "nestedTransactionScopedTransaction.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(NestedTransactionScopedTransactionTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void nestedTransactionScopedTransaction() { firstLevelTransactionBean.executeInTransaction(); TestEntityTransaction testTransaction = (TestEntityTransaction) entityManagerProducer.getFirstEntityManager().getTransaction(); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCount()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/nested/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.nested; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.First; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager firstEntityManager; private int closeEntityManagerCount = 0; @Produces @First @TransactionScoped protected EntityManager firstEntityManager() { if (firstEntityManager == null) { firstEntityManager = new TestEntityManager(); return firstEntityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeEntityManager(@Disposes @First EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCount++; } public int getCloseEntityManagerCount() { return closeEntityManagerCount; } public TestEntityManager getFirstEntityManager() { return firstEntityManager; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/stereotype/Repository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.stereotype; import org.apache.deltaspike.jpa.api.transaction.Transactional; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ TYPE }) @Retention(RUNTIME) @Documented //cdi annotations @Stereotype @Transactional @ApplicationScoped public @interface Repository { } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/stereotype/StereotypeTransactionScopedTransactionalTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.stereotype; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionBeanStorage; import org.apache.deltaspike.jpa.impl.transaction.context.TransactionContextExtension; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.spi.Extension; import jakarta.inject.Inject; @RunWith(Arquillian.class) @Category(SeCategory.class) public class StereotypeTransactionScopedTransactionalTest { @Inject private TransactionalBean transactionalBean; @Inject private TestEntityManagerProducer entityManagerProducer; @Inject private TestEntityTransactionHolder testEntityTransactionHolder; @Deployment public static WebArchive deploy() { JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "stereotypeTransactionScopedTransactionalTest.jar") .addPackage(ArchiveUtils.SHARED_PACKAGE) .addPackage(StereotypeTransactionScopedTransactionalTest.class.getPackage().getName()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJpaArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, TransactionContextExtension.class) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Before public void init() { ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); } @Test public void transactionalBeanViaStereotypeInTransactionScoped() { transactionalBean.executeInTransaction(); TestEntityTransaction testTransaction = testEntityTransactionHolder.getTestEntityTransaction(); Assert.assertEquals(false, testTransaction.isActive()); Assert.assertEquals(true, testTransaction.isStarted()); Assert.assertEquals(true, testTransaction.isCommitted()); Assert.assertEquals(false, testTransaction.isRolledBack()); Assert.assertEquals(1, entityManagerProducer.getCloseEntityManagerCount()); Assert.assertEquals(false, TransactionBeanStorage.isOpen()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/stereotype/TestEntityManagerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.stereotype; import org.apache.deltaspike.jpa.api.transaction.TransactionScoped; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Disposes; import jakarta.enterprise.inject.Produces; import jakarta.persistence.EntityManager; @RequestScoped public class TestEntityManagerProducer { private TestEntityManager entityManager; private int closeEntityManagerCount = 0; @Produces @TransactionScoped protected EntityManager entityManager() { if (entityManager == null) { entityManager = new TestEntityManager(); return entityManager; } throw new IllegalStateException("a second producer call isn't allowed"); } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } closeEntityManagerCount++; } public int getCloseEntityManagerCount() { return closeEntityManagerCount; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/stereotype/TestEntityTransactionHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.stereotype; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class TestEntityTransactionHolder { private TestEntityTransaction testEntityTransaction; public TestEntityTransaction getTestEntityTransaction() { return testEntityTransaction; } public void setTestEntityTransaction(TestEntityTransaction testEntityTransaction) { this.testEntityTransaction = testEntityTransaction; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/api/transactionscoped/stereotype/TransactionalBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.api.transactionscoped.stereotype; import org.apache.deltaspike.test.jpa.api.shared.TestEntityTransaction; import jakarta.inject.Inject; import jakarta.persistence.EntityManager; @Repository public class TransactionalBean { @Inject private EntityManager entityManager; //we can't provide a simple getter because it would be intercepted as well and //would break the check we have to perform in the test @Inject private TestEntityTransactionHolder testEntityTransactionHolder; public void executeInTransaction() { testEntityTransactionHolder.setTestEntityTransaction( (TestEntityTransaction) entityManager.getTransaction()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/datasource/DummyConnection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.datasource; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.NClob; import java.sql.PreparedStatement; import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; /** * Dummy JDBC Connection for use in a unit test */ public class DummyConnection implements Connection { @Override public void clearWarnings() throws SQLException { // not implemented } @Override public Statement createStatement() throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql) throws SQLException { return null; } @Override public CallableStatement prepareCall(String sql) throws SQLException { return null; } @Override public String nativeSQL(String sql) throws SQLException { return null; } @Override public void setAutoCommit(boolean autoCommit) throws SQLException { // not implemented } @Override public boolean getAutoCommit() throws SQLException { return false; } @Override public void commit() throws SQLException { // not implemented } @Override public void rollback() throws SQLException { // not implemented } @Override public void close() throws SQLException { // not implemented } @Override public boolean isClosed() throws SQLException { return false; } @Override public DatabaseMetaData getMetaData() throws SQLException { return null; } @Override public void setReadOnly(boolean readOnly) throws SQLException { // not implemented } @Override public boolean isReadOnly() throws SQLException { return false; } @Override public void setCatalog(String catalog) throws SQLException { // not implemented } @Override public String getCatalog() throws SQLException { return null; } @Override public void setTransactionIsolation(int level) throws SQLException { // not implemented } @Override public int getTransactionIsolation() throws SQLException { return 0; } @Override public SQLWarning getWarnings() throws SQLException { return null; } @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return null; } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return null; } @Override public Map> getTypeMap() throws SQLException { return null; } @Override public void setTypeMap(Map> map) throws SQLException { // not implemented } @Override public void setHoldability(int holdability) throws SQLException { // not implemented } @Override public int getHoldability() throws SQLException { return 0; } @Override public Savepoint setSavepoint() throws SQLException { return null; } @Override public Savepoint setSavepoint(String name) throws SQLException { return null; } @Override public void rollback(Savepoint savepoint) throws SQLException { // not implemented } @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { // not implemented } @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; } @Override public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return null; } @Override public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return null; } @Override public Clob createClob() throws SQLException { return null; } @Override public Blob createBlob() throws SQLException { return null; } @Override public NClob createNClob() throws SQLException { return null; } @Override public SQLXML createSQLXML() throws SQLException { return null; } @Override public boolean isValid(int timeout) throws SQLException { return false; } @Override public void setClientInfo(String name, String value) throws SQLClientInfoException { // not implemented } @Override public void setClientInfo(Properties properties) throws SQLClientInfoException { // not implemented } @Override public String getClientInfo(String name) throws SQLException { return null; } @Override public Properties getClientInfo() throws SQLException { return null; } @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { return null; } @Override public Struct createStruct(String typeName, Object[] attributes) throws SQLException { return null; } @Override public T unwrap(Class iface) throws SQLException { return null; } @Override public boolean isWrapperFor(Class iface) throws SQLException { return false; } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public int getNetworkTimeout() throws SQLException { return 0; } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { // not implemented } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public void abort(Executor executor) throws SQLException { // not implemented } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public String getSchema() throws SQLException { return null; } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public void setSchema(String schema) throws SQLException { // not implemented } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/datasource/DummyJdbcDriver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.datasource; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import java.util.logging.Logger; /** * A dummy JDBC driver for use in our unit tests */ public class DummyJdbcDriver implements Driver { @Override public boolean acceptsURL(String url) throws SQLException { return true; } @Override public Connection connect(String url, Properties info) throws SQLException { return new DummyConnection(); } @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return new DriverPropertyInfo[0]; //To change body of implemented methods use File | Settings | File Templates. } @Override public int getMajorVersion() { return 1; } @Override public int getMinorVersion() { return 0; } @Override public boolean jdbcCompliant() { return true; } /* * This method was introduced by Java7's java.sql.Driver and breaks backwards compatibility. */ public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/EntityMappingsDescriptorParserTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; import java.io.IOException; import org.apache.deltaspike.jpa.spi.descriptor.xml.EntityMappingsDescriptor; import org.apache.deltaspike.jpa.spi.descriptor.xml.EntityMappingsDescriptorParser; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class EntityMappingsDescriptorParserTest { private EntityMappingsDescriptorParser entityMappingsDescriptorParser; private EntityMappingsDescriptor descriptor; @Before public void before() throws IOException { entityMappingsDescriptorParser = new EntityMappingsDescriptorParser(); descriptor = entityMappingsDescriptorParser.readAll(getClass().getResource("/").getPath(), "META-INF/test-orm.xml"); } @Test public void testPackageName() throws IOException { Assert.assertEquals("org.apache.deltaspike.test.jpa.spi.descriptor.xml", descriptor.getPackageName()); } @Test public void testEntityDescriptors() throws IOException { Assert.assertNotNull(descriptor.getEntityDescriptors()); Assert.assertEquals(3, descriptor.getEntityDescriptors().size()); } @Test public void testMappedSuperclassDescriptors() throws IOException { Assert.assertNotNull(descriptor.getMappedSuperclassDescriptors()); Assert.assertEquals(2, descriptor.getMappedSuperclassDescriptors().size()); } @Test public void testEntityClass() throws IOException { Assert.assertEquals(MappedOne.class, descriptor.getEntityDescriptors().get(0).getEntityClass()); Assert.assertEquals(MappedTwo.class, descriptor.getEntityDescriptors().get(1).getEntityClass()); Assert.assertEquals(MappedThree.class, descriptor.getEntityDescriptors().get(2).getEntityClass()); } @Test public void testId() throws IOException { Assert.assertEquals("id", descriptor.getEntityDescriptors().get(0).getId()[0]); Assert.assertEquals("teeSetId", descriptor.getEntityDescriptors().get(1).getId()[0]); Assert.assertEquals("holeId", descriptor.getEntityDescriptors().get(1).getId()[1]); Assert.assertEquals(null, descriptor.getEntityDescriptors().get(2).getId()); } @Test public void testVersion() throws IOException { Assert.assertEquals("version", descriptor.getEntityDescriptors().get(0).getVersion()); Assert.assertEquals(null, descriptor.getEntityDescriptors().get(1).getVersion()); Assert.assertEquals(null, descriptor.getEntityDescriptors().get(2).getVersion()); Assert.assertEquals(null, descriptor.getMappedSuperclassDescriptors().get(0).getVersion()); Assert.assertEquals("version", descriptor.getMappedSuperclassDescriptors().get(1).getVersion()); } @Test public void testName() throws IOException { Assert.assertEquals("Mapped_One", descriptor.getEntityDescriptors().get(0).getName()); } @Test public void testTableName() throws IOException { Assert.assertEquals("mapped_three_table", descriptor.getEntityDescriptors().get(2).getTableName()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/MappedId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; public class MappedId { private Long id; public Long getId() { return id; } public void setId(Long id) { this.id = id; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/MappedOne.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; public class MappedOne { private Long id; private String name; public MappedOne() { } public MappedOne(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/MappedSuperclass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; public class MappedSuperclass extends MappedId { private Long counter; public Long getCounter() { return counter; } public void setCounter(Long id) { this.counter = id; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/MappedThree.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; public class MappedThree extends MappedSuperclass { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/MappedTwo.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; public class MappedTwo { private Long teeSetId; private Long holeId; private String name; public Long getTeeSetId() { return teeSetId; } public void setTeeSetId(Long teeSetId) { this.teeSetId = teeSetId; } public Long getHoleId() { return holeId; } public void setHoleId(Long holeId) { this.holeId = holeId; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/PersistenceUnitDescriptorParserTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; import java.io.IOException; import java.util.List; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptor; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptorParser; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class PersistenceUnitDescriptorParserTest { private PersistenceUnitDescriptorParser persistenceUnitDescriptorParser; private List descriptors; @Before public void before() throws IOException { persistenceUnitDescriptorParser = new PersistenceUnitDescriptorParser(); descriptors = persistenceUnitDescriptorParser.readAll(); } @Test public void testPackageName() throws IOException { Assert.assertEquals("test", descriptors.get(0).getName()); Assert.assertEquals("test2", descriptors.get(1).getName()); } @Test public void testProperties() throws IOException { Assert.assertNotNull(descriptors.get(0).getProperties()); Assert.assertEquals(1, descriptors.get(0).getProperties().size()); Assert.assertNotNull(descriptors.get(1).getProperties()); Assert.assertEquals(3, descriptors.get(1).getProperties().size()); Assert.assertNotNull(descriptors.get(2).getProperties()); Assert.assertEquals(0, descriptors.get(2).getProperties().size()); } @Test public void testEntityDescriptors() throws IOException { Assert.assertNotNull(descriptors.get(0).getEntityDescriptors()); Assert.assertEquals(3, descriptors.get(0).getEntityDescriptors().size()); Assert.assertEquals(MappedOne.class, descriptors.get(0).getEntityDescriptors().get(0).getEntityClass()); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/PersistenceUnitDescriptorProviderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; import java.io.IOException; import junit.framework.Assert; import org.apache.deltaspike.jpa.spi.descriptor.xml.PersistenceUnitDescriptorProvider; import org.junit.Before; import org.junit.Test; public class PersistenceUnitDescriptorProviderTest { @Before public void before() throws IOException { PersistenceUnitDescriptorProvider.getInstance().init(); } @Test public void testParentIdLookup() { String[] ids = PersistenceUnitDescriptorProvider.getInstance().primaryKeyFields(MappedThree.class); Assert.assertNotNull(ids); Assert.assertEquals(1, ids.length); } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/jpa/spi/descriptor/xml/TeeId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jpa.spi.descriptor.xml; import java.io.Serializable; import jakarta.persistence.Column; import jakarta.persistence.Embeddable; @Embeddable @SuppressWarnings("serial") public class TeeId implements Serializable { @Column(nullable = false) private Long teeSetId; @Column(nullable = false) private Long holeId; public TeeId() { } public TeeId(long teeSetId, long holeId) { this.teeSetId = teeSetId; this.holeId = holeId; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (holeId ^ (holeId >>> 32)); result = prime * result + (int) (teeSetId ^ (teeSetId >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } TeeId other = (TeeId) obj; if (holeId != other.holeId) { return false; } if (teeSetId != other.teeSetId) { return false; } return true; } public long getTeeSetId() { return teeSetId; } public void setTeeSetId(long teeSetId) { this.teeSetId = teeSetId; } public long getHoleId() { return holeId; } public void setHoleId(long holeId) { this.holeId = holeId; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/java/org/apache/deltaspike/test/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util; import org.apache.deltaspike.test.jpa.api.shared.TestEntityManager; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * This class contains helpers for building frequently used archives */ public class ArchiveUtils { public static final String SHARED_PACKAGE = TestEntityManager.class.getPackage().getName(); private ArchiveUtils() { // private ct } public static JavaArchive[] getDeltaSpikeCoreAndJpaArchive() { return ShrinkWrapArchiveUtil.getArchives( null, "META-INF/beans.xml", new String[]{"org.apache.deltaspike.core", "org.apache.deltaspike.jpa"}, null, "ds-core_and_jpa"); } public static Asset getBeansXml() { @SuppressWarnings("UnnecessaryLocalVariable") Asset beansXml = new StringAsset( "" + "" + "org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor" + "" + "" ); return beansXml; } } ================================================ FILE: deltaspike/modules/jpa/impl/src/test/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # overwriting the original value from bla to blub deltaspike.persistence.config.MyUnit.jakarta.persistence.jdbc.password=blub # and a new config entry deltaspike.persistence.config.MyUnit.jakarta.persistence.jdbc.driver=some.jdbc.Driver ================================================ FILE: deltaspike/modules/jpa/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jpa/impl/src/test/resources/META-INF/persistence.xml ================================================ java:test/test META-INF/test-orm.xml ================================================ FILE: deltaspike/modules/jpa/impl/src/test/resources/META-INF/test-orm.xml ================================================ org.apache.deltaspike.test.jpa.spi.descriptor.xml
================================================ FILE: deltaspike/modules/jpa/impl/src/test/resources/persistence-MyUnit.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # jakarta.persistence.jdbc.user=sa jakarta.persistence.jdbc.password=bla ================================================ FILE: deltaspike/modules/jpa/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules jpa-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike JPA-Module api impl jakarta.persistence jakarta.persistence-api ================================================ FILE: deltaspike/modules/jsf/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules jsf-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-jsf-module-api Apache DeltaSpike JSF-Module API 5.9.2 org.apache.deltaspike.core deltaspike-core-api ${project.version} compile org.apache.myfaces.core myfaces-api ${myfaces.version} provided org.apache.myfaces.core myfaces-test ${myfaces.version} test org.junit.jupiter junit-jupiter-api ${junit.jupiter.version} test ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/JsfModuleConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.config; import java.lang.annotation.Annotation; import org.apache.deltaspike.core.api.config.DeltaSpikeConfig; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Default; import jakarta.faces.context.FacesContext; import jakarta.faces.lifecycle.ClientWindow; /** * Config for all JSF specific configurations. */ @ApplicationScoped public class JsfModuleConfig implements DeltaSpikeConfig { private static final long serialVersionUID = -487295181899986237L; private volatile Boolean initialized; private boolean delegatedWindowHandlingEnabled; protected JsfModuleConfig() { } /** * If the initial redirect is enabled, a redirect will be performed for adding the current window-id to the url. * * @return true for activating it, false otherwise */ public boolean isInitialRedirectEnabled() { return true; } /** * Per default all faces-messages are preserved for the next rendering process * @return true if the messages should be preserved automatically, false otherwise */ public boolean isAlwaysKeepMessages() { return true; } /** * Per default the current view gets replaced with the error-view (in case of a security-violation). * For using a redirect it's needed to return true and using Page.NavigationMode.REDIRECT for @View of the * error-view-config. * @return true if the navigation-handler should be used in case of a security-violation, false otherwise */ public boolean isAlwaysUseNavigationHandlerOnSecurityViolation() { return false; } /** * If the window-handling of Faces is enabled, * {@link org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig.ClientWindowRenderMode#DELEGATED} * will be returned. In all other cases null gets returned as application wide default value. * That leads to a default-handling per session (which includes logic for handling bots,...) * @return application-default for the window-mode */ public ClientWindowConfig.ClientWindowRenderMode getDefaultWindowMode() { lazyInit(); if (this.delegatedWindowHandlingEnabled) { return ClientWindowConfig.ClientWindowRenderMode.DELEGATED; } return null; } /** * Defines the {@link jakarta.inject.Qualifier} which will be used for the * FacesContextWrapper ExceptionHandler * for unhandled JSF exceptions. * * @return the {@link jakarta.inject.Qualifier}. */ public Class getExceptionQualifier() { return Default.class; } public boolean isAllowPostRequestWithoutDoubleSubmitPrevention() { return true; } private void lazyInit() { if (this.initialized == null) { init(); } } protected synchronized void init() { if (this.initialized == null) { FacesContext facesContext = FacesContext.getCurrentInstance(); // can happen in case of a very simple test-setup without a mocked jsf container if (facesContext == null) { this.delegatedWindowHandlingEnabled = false; } else { String initParam = facesContext.getExternalContext() .getInitParameter(ClientWindow.CLIENT_WINDOW_MODE_PARAM_NAME); this.delegatedWindowHandlingEnabled = !(initParam == null || "none".equalsIgnoreCase(initParam.trim())); } this.initialized = true; } } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/base/JsfBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.config.base; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; import org.apache.deltaspike.core.api.config.base.CoreBaseConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; public interface JsfBaseConfig extends DeltaSpikeBaseConfig { interface ViewConfigCustomization { String CUSTOM_DEFAULT_BASE_PATH_BUILDER = ConfigResolver.resolve(View.DefaultBasePathBuilder.class.getName()) .withCurrentProjectStage(true) .getValue(); String CUSTOM_DEFAULT_FILE_NAME_BUILDER = ConfigResolver.resolve(View.DefaultFileNameBuilder.class.getName()) .withCurrentProjectStage(true) .getValue(); String CUSTOM_DEFAULT_EXTENSION_BUILDER = ConfigResolver.resolve(View.DefaultExtensionBuilder.class.getName()) .withCurrentProjectStage(true) .getValue(); String CUSTOM_DEFAULT_FOLDER_NAME_BUILDER = ConfigResolver .resolve(Folder.DefaultFolderNameBuilder.class.getName()) .withCurrentProjectStage(true) .getValue(); } interface ScopeCustomization { interface WindowRestriction { int ID_MAX_LENGTH_DEFAULT = 10; Integer MAX_COUNT = ConfigResolver.resolve(CoreBaseConfig.ScopeCustomization.WindowRestriction.MAX_COUNT_KEY) .as(Integer.class) .withCurrentProjectStage(true) .withDefault(64) .getValue(); //10 is enough for the integer generated by DefaultClientWindow#generateNewWindowId - see DELTASPIKE-752 Integer ID_MAX_LENGTH = ConfigResolver.resolve("deltaspike.window-id.max_length") .as(Integer.class) .withCurrentProjectStage(true) .withDefault(ID_MAX_LENGTH_DEFAULT) .getValue(); } } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/view/Folder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.config.view; import org.apache.deltaspike.core.api.config.view.metadata.SkipMetaDataMerge; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import org.apache.deltaspike.jsf.api.literal.FolderLiteral; import org.apache.deltaspike.jsf.util.NamingConventionUtils; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.Iterator; import java.util.Set; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Optional annotation to specify folder specific meta-data */ //don't use @Inherited @Target(TYPE) @Retention(RUNTIME) @Documented @ViewMetaData(preProcessor = Folder.FolderConfigPreProcessor.class) public @interface Folder { /** * Allows to specify a custom (folder-)name * * @return name of the folder */ @SkipMetaDataMerge String name() default "."; /** * Allows to add a custom inline path-builder * (a custom default implementation can be configured globally via the config mechanism provided by DeltaSpike) * @return path builder which allows to customize the naming conventions for the folder-name */ Class folderNameBuilder() default DefaultFolderNameBuilder.class; static class FolderConfigPreProcessor implements ConfigPreProcessor { @Override public Folder beforeAddToConfig(Folder folder, ViewConfigNode viewConfigNode) { boolean defaultValueReplaced = false; /* * file name */ NameBuilder folderNameBuilder = getFolderNameBuilder(folder); String name = folderNameBuilder.build(folder, viewConfigNode); if (folderNameBuilder.isDefaultValueReplaced()) { defaultValueReplaced = true; } if (defaultValueReplaced) { Folder result = new FolderLiteral(name, folder.folderNameBuilder()); updateNodeMetaData(viewConfigNode, result); return result; } return folder; } private void updateNodeMetaData(ViewConfigNode viewConfigNode, Folder folder) { Set metaData = viewConfigNode.getMetaData(); Iterator metaDataIterator = metaData.iterator(); while (metaDataIterator.hasNext()) { if (Folder.class.equals(metaDataIterator.next().annotationType())) { metaDataIterator.remove(); break; } } metaData.add(folder); } private NameBuilder getFolderNameBuilder(Folder folder) { NameBuilder folderNameBuilder; if (DefaultFolderNameBuilder.class.equals(folder.folderNameBuilder())) { String customDefaultFolderNameBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_FOLDER_NAME_BUILDER; if (customDefaultFolderNameBuilderClassName != null) { folderNameBuilder = (NameBuilder) ClassUtils.tryToInstantiateClassForName(customDefaultFolderNameBuilderClassName); } else { folderNameBuilder = new DefaultFolderNameBuilder(); } } else { folderNameBuilder = ClassUtils.tryToInstantiateClass(folder.folderNameBuilder()); } return folderNameBuilder; } } //TODO discuss if we use a central interface in the spi package //advantage: can be reused //disadvantage: a wrong builder can get assigned more easily, show usages will list more interface NameBuilder { String build(Folder folder, ViewConfigNode viewConfigNode); boolean isDefaultValueReplaced(); } class DefaultFolderNameBuilder implements NameBuilder { private boolean defaultValueReplaced = false; @Override public String build(Folder folder, ViewConfigNode viewConfigNode) { String name = folder.name(); if (name == null /*null used as marker value for dyn. added instances*/ || ".".equals(name) /*default*/) { name = NamingConventionUtils.toPath(viewConfigNode); this.defaultValueReplaced = true; } if (name != null && name.startsWith(".")) { name = NamingConventionUtils.toPath(viewConfigNode.getParent()) + name.substring(1); this.defaultValueReplaced = true; } if (name != null && !name.startsWith(".") && !name.startsWith("/")) { name = NamingConventionUtils.toPath(viewConfigNode.getParent()) + name; this.defaultValueReplaced = true; } if (name != null && !name.endsWith("/")) { name = name + "/"; this.defaultValueReplaced = true; } if (name != null && name.contains("//")) { name = name.replace("//", "/"); this.defaultValueReplaced = true; } return name; } public boolean isDefaultValueReplaced() { return defaultValueReplaced; } } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/config/view/View.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.config.view; import org.apache.deltaspike.core.api.config.view.metadata.SkipMetaDataMerge; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import org.apache.deltaspike.jsf.api.literal.ViewLiteral; import org.apache.deltaspike.jsf.util.NamingConventionUtils; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.Set; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.apache.deltaspike.jsf.api.config.view.View.Extension.XHTML; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.EXCLUDE; /** * Optional annotation to specify page specific meta-data */ //don't use @Inherited @Target(TYPE) @Retention(RUNTIME) @Documented @ViewMetaData(preProcessor = View.ViewConfigPreProcessor.class) public @interface View { /** * Allows to specify a custom base-path for the page represented by the view-config * @return base-path */ @SkipMetaDataMerge String basePath() default ""; /** * Allows to specify a custom (file-)name for the page represented by the view-config * * @return name of the page */ @SkipMetaDataMerge String name() default ""; /** * Allows to specify the (file-)extension for the page represented by the view-config * * @return extension of the page */ String extension() default Extension.DEFAULT; /** * Allows to specify navigation-mode which should be used to navigate to the page represented by the view-config * * @return navigation-mode which should be used to navigate to the page represented by the view-config */ NavigationMode navigation() default NavigationMode.DEFAULT; /** * for including view params in jsf2 * * @return the strategy which should be used by jsf2 for handling view-parameters (for the navigation) */ ViewParameterMode viewParams() default ViewParameterMode.DEFAULT; /** * Allows to add a custom inline path-builder * (a custom default implementation can be configured globally via the config mechanism provided by DeltaSpike) * @return path builder which allows to customize the naming conventions for the base-path */ Class basePathBuilder() default DefaultBasePathBuilder.class; /** * Allows to add a custom inline path-builder * (a custom default implementation can be configured globally via the config mechanism provided by DeltaSpike) * @return path builder which allows to customize the naming conventions for the file-name */ Class fileNameBuilder() default DefaultFileNameBuilder.class; /** * Allows to add a custom inline path-builder * (a custom default implementation can be configured globally via the config mechanism provided by DeltaSpike) * @return path builder which allows to customize the naming conventions for the file-extension */ Class extensionBuilder() default DefaultExtensionBuilder.class; /** * Extension of the markup file */ interface Extension { String DEFAULT = ""; String XHTML = "xhtml"; String JSF = "jsf"; String FACES = "faces"; String JSP = "jsp"; } /** * Type of the navigation which should be used by the {@link jakarta.faces.application.NavigationHandler} */ enum NavigationMode { DEFAULT, FORWARD, REDIRECT } /** * Mode specifies if JSF2 should include view-params */ enum ViewParameterMode { DEFAULT, INCLUDE, EXCLUDE } static class ViewConfigPreProcessor implements ConfigPreProcessor { @Override public View beforeAddToConfig(View view, ViewConfigNode viewConfigNode) { validateViewMetaData(view, viewConfigNode); boolean defaultValueReplaced = false; View.NavigationMode navigation = view.navigation(); View.ViewParameterMode viewParams = view.viewParams(); /* * base path */ NameBuilder basePathBuilder = getBasePathBuilder(view); String basePath = basePathBuilder.build(view, viewConfigNode); if (basePathBuilder.isDefaultValueReplaced()) { defaultValueReplaced = true; } /* * file name */ NameBuilder fileNameBuilder = getFileNameBuilder(view); String name = fileNameBuilder.build(view, viewConfigNode); if (fileNameBuilder.isDefaultValueReplaced()) { defaultValueReplaced = true; } /* * extension */ NameBuilder extensionBuilder = getExtensionBuilder(view); String extension = extensionBuilder.build(view, viewConfigNode); if (extensionBuilder.isDefaultValueReplaced()) { defaultValueReplaced = true; } /* * navigation */ if (View.NavigationMode.DEFAULT.equals(navigation) || navigation == null) { defaultValueReplaced = true; navigation = FORWARD; } if (View.ViewParameterMode.DEFAULT.equals(viewParams) || viewParams == null) { defaultValueReplaced = true; viewParams = EXCLUDE; } if (defaultValueReplaced) { View result = new ViewLiteral(basePath, name, extension, navigation, viewParams, view.basePathBuilder(), view.fileNameBuilder(), view.extensionBuilder()); updateNodeMetaData(viewConfigNode, result); return result; } return view; } protected void validateViewMetaData(View view, ViewConfigNode viewConfigNode) { String basePath = view.basePath(); if (viewConfigNode.getSource().isInterface() && !"".equals(basePath) && basePath != null) { throw new IllegalStateException("Using @" + View.class.getName() + "#basePath isn't allowed on" + " folder-nodes (= interfaces). Use @" + Folder.class.getName() + " for intended folder-nodes" + " or a class instead of the interface for page-nodes."); } } private void updateNodeMetaData(ViewConfigNode viewConfigNode, View view) { Set metaData = viewConfigNode.getMetaData(); Iterator metaDataIterator = metaData.iterator(); while (metaDataIterator.hasNext()) { if (View.class.equals(metaDataIterator.next().annotationType())) { metaDataIterator.remove(); break; } } metaData.add(view); } private NameBuilder getBasePathBuilder(View view) { NameBuilder basePathBuilder; if (DefaultBasePathBuilder.class.equals(view.basePathBuilder())) { String customDefaultBasePathBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_BASE_PATH_BUILDER; if (customDefaultBasePathBuilderClassName != null) { basePathBuilder = (NameBuilder)ClassUtils.tryToInstantiateClassForName(customDefaultBasePathBuilderClassName); } else { basePathBuilder = new DefaultBasePathBuilder(); } } else { basePathBuilder = ClassUtils.tryToInstantiateClass(view.basePathBuilder()); } return basePathBuilder; } private NameBuilder getFileNameBuilder(View view) { NameBuilder fileNameBuilder; if (DefaultFileNameBuilder.class.equals(view.fileNameBuilder())) { String customDefaultFileNameBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_FILE_NAME_BUILDER; if (customDefaultFileNameBuilderClassName != null) { fileNameBuilder = (NameBuilder)ClassUtils.tryToInstantiateClassForName(customDefaultFileNameBuilderClassName); } else { fileNameBuilder = new DefaultFileNameBuilder(); } } else { fileNameBuilder = ClassUtils.tryToInstantiateClass(view.fileNameBuilder()); } return fileNameBuilder; } private NameBuilder getExtensionBuilder(View view) { NameBuilder extensionBuilder; if (DefaultExtensionBuilder.class.equals(view.extensionBuilder())) { String customDefaultExtensionBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_EXTENSION_BUILDER; if (customDefaultExtensionBuilderClassName != null) { extensionBuilder = (NameBuilder)ClassUtils.tryToInstantiateClassForName(customDefaultExtensionBuilderClassName); } else { extensionBuilder = new DefaultExtensionBuilder(); } } else { extensionBuilder = ClassUtils.tryToInstantiateClass(view.extensionBuilder()); } return extensionBuilder; } //it's possible that the given source is a folder-node //e.g. @View(navigation = REDIRECT) specified for a whole folder private static boolean isView(Class source) { return !Modifier.isAbstract(source.getModifiers()) && !Modifier.isInterface(source.getModifiers()); } } //TODO discuss if we use a central interface in the spi package //advantage: can be reused //disadvantage: a wrong builder can get assigned more easily, show usages will list more interface NameBuilder { String build(View view, ViewConfigNode viewConfigNode); boolean isDefaultValueReplaced(); } abstract class AbstractNameBuilder implements NameBuilder { protected boolean defaultValueReplaced = false; public boolean isDefaultValueReplaced() { return defaultValueReplaced; } } class DefaultBasePathBuilder extends AbstractNameBuilder { @Override public String build(View view, ViewConfigNode viewConfigNode) { String basePath = view.basePath(); Class source = viewConfigNode.getSource(); if (("".equals(basePath) || basePath == null) && ViewConfigPreProcessor.isView(source) /*only calc the path for real pages*/) { this.defaultValueReplaced = true; basePath = NamingConventionUtils.toPath(viewConfigNode.getParent()); } if (basePath != null && basePath.startsWith(".")) { basePath = NamingConventionUtils.toPath(viewConfigNode.getParent()) + basePath.substring(1); this.defaultValueReplaced = true; } if (basePath != null && !basePath.startsWith(".") && !basePath.startsWith("/")) { basePath = NamingConventionUtils.toPath(viewConfigNode.getParent()) + basePath; this.defaultValueReplaced = true; } if (basePath != null && !basePath.endsWith("/")) { basePath = basePath + "/"; this.defaultValueReplaced = true; } if (basePath != null && basePath.contains("//")) { basePath = basePath.replace("//", "/"); this.defaultValueReplaced = true; } return basePath; } } class DefaultFileNameBuilder extends AbstractNameBuilder { @Override public String build(View view, ViewConfigNode viewConfigNode) { String name = view.name(); Class source = viewConfigNode.getSource(); if (("".equals(name) || name == null) && ViewConfigPreProcessor.isView(source) /*only calc the path for real pages*/) { this.defaultValueReplaced = true; String className = viewConfigNode.getSource().getSimpleName(); name = className.substring(0, 1).toLowerCase() + className.substring(1); } return name; } } class DefaultExtensionBuilder extends AbstractNameBuilder { @Override public String build(View view, ViewConfigNode viewConfigNode) { String extension = view.extension(); if (View.Extension.DEFAULT.equals(extension) || extension == null) { defaultValueReplaced = true; extension = XHTML; } return extension; } } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/listener/phase/AfterPhase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.listener.phase; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; 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.RetentionPolicy.RUNTIME; /** * Qualifier for after-request observers */ @Target({ PARAMETER, FIELD, METHOD }) @Retention(RUNTIME) @Documented @Qualifier /** * - for request-observer-methods * //TODO - for lifecycle callbacks in view-definitions * * Parameter-type of the observer: {@link jakarta.faces.event.PhaseEvent} */ public @interface AfterPhase { /** * {@link JsfPhaseId} which is the equivalent for the {@link jakarta.faces.event.PhaseId} value. * For more details see {@link JsfPhaseId} * * @return request-id which defines the jsf-lifecycle-request to completely define this qualifier */ JsfPhaseId value(); } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/listener/phase/BeforePhase.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.listener.phase; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; 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.RetentionPolicy.RUNTIME; @Target({ PARAMETER, FIELD, METHOD }) @Retention(RUNTIME) @Documented @Qualifier /** * - for request-observer-methods * //TODO - for lifecycle callbacks in view-definitions * * Parameter-type of the observer: {@link jakarta.faces.event.PhaseEvent} */ public @interface BeforePhase { /** * {@link JsfPhaseId} which is the equivalent for the {@link jakarta.faces.event.PhaseId} value. * For more details see {@link JsfPhaseId} * * @return request-id which defines the jsf-lifecycle-request to completely define this qualifier */ JsfPhaseId value(); } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/listener/phase/JsfPhaseId.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.listener.phase; /** * It isn't possible to use the original implementation of JSF in combination with annotations */ public enum JsfPhaseId { RESTORE_VIEW(jakarta.faces.event.PhaseId.RESTORE_VIEW), APPLY_REQUEST_VALUES(jakarta.faces.event.PhaseId.APPLY_REQUEST_VALUES), PROCESS_VALIDATIONS(jakarta.faces.event.PhaseId.PROCESS_VALIDATIONS), UPDATE_MODEL_VALUES(jakarta.faces.event.PhaseId.UPDATE_MODEL_VALUES), INVOKE_APPLICATION(jakarta.faces.event.PhaseId.INVOKE_APPLICATION), RENDER_RESPONSE(jakarta.faces.event.PhaseId.RENDER_RESPONSE), ANY_PHASE(jakarta.faces.event.PhaseId.ANY_PHASE); private jakarta.faces.event.PhaseId phaseId; JsfPhaseId(jakarta.faces.event.PhaseId phaseId) { this.phaseId = phaseId; } /** * Converts the jsf implementation to the ds implementation * * @param phaseId current request-id which has to be converted * @return ds implementation for the given request-id */ public static JsfPhaseId convertFromFacesClass(jakarta.faces.event.PhaseId phaseId) { if (RESTORE_VIEW.getPhaseId().equals(phaseId)) { return RESTORE_VIEW; } if (RENDER_RESPONSE.getPhaseId().equals(phaseId)) { return RENDER_RESPONSE; } if (APPLY_REQUEST_VALUES.getPhaseId().equals(phaseId)) { return APPLY_REQUEST_VALUES; } if (PROCESS_VALIDATIONS.getPhaseId().equals(phaseId)) { return PROCESS_VALIDATIONS; } if (UPDATE_MODEL_VALUES.getPhaseId().equals(phaseId)) { return UPDATE_MODEL_VALUES; } if (INVOKE_APPLICATION.getPhaseId().equals(phaseId)) { return INVOKE_APPLICATION; } return null; } jakarta.faces.event.PhaseId getPhaseId() { return phaseId; } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/listener/phase/JsfPhaseListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.listener.phase; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Annotation for implementations of {@link jakarta.faces.event.PhaseListener}. */ @Target(TYPE) @Retention(RUNTIME) @Inherited @Documented @Stereotype public @interface JsfPhaseListener { /** * @return ordinal for invocation-order - higher ordinals first */ int ordinal() default 1000; //aligned with value in BaseConfigSource } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/literal/FolderLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.literal; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link Folder} */ //TODO remove null trick once we can merge with default values and the tests pass public class FolderLiteral extends AnnotationLiteral implements Folder { private static final long serialVersionUID = 2582580975876369665L; private final String name; private final Class folderNameBuilder; public FolderLiteral(boolean virtual) { if (virtual) { this.name = null; } else { this.name = ""; } final String customDefaultFolderNameBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_FOLDER_NAME_BUILDER; if (customDefaultFolderNameBuilderClassName != null) { this.folderNameBuilder = ClassUtils.tryToLoadClassForName(customDefaultFolderNameBuilderClassName); } else { this.folderNameBuilder = DefaultFolderNameBuilder.class; } } public FolderLiteral(String name, Class folderNameBuilder) { this.name = name; this.folderNameBuilder = folderNameBuilder; } @Override public String name() { return this.name; } @Override public Class folderNameBuilder() { return this.folderNameBuilder; } /* * generated */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!(o instanceof FolderLiteral)) { return false; } if (!super.equals(o)) { return false; } FolderLiteral that = (FolderLiteral) o; if (!folderNameBuilder.equals(that.folderNameBuilder)) { return false; } if (name != null ? !name.equals(that.name) : that.name != null) { return false; } return true; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + folderNameBuilder.hashCode(); return result; } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/literal/ViewLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.literal; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.enterprise.util.AnnotationLiteral; /** * Literal for {@link org.apache.deltaspike.jsf.api.config.view.View} */ //TODO remove null trick once we can merge with default values and the tests pass public class ViewLiteral extends AnnotationLiteral implements View { private static final long serialVersionUID = 1582580975876369665L; private final String basePath; private final String name; private final String extension; private final NavigationMode navigation; private final ViewParameterMode viewParams; private final Class basePathBuilder; private final Class fileNameBuilder; private final Class extensionBuilder; public ViewLiteral(boolean virtual) { if (virtual) { this.basePath = null; this.name = null; this.extension = null; this.navigation = null; this.viewParams = null; } else { this.basePath = ""; this.name = ""; this.extension = Extension.DEFAULT; this.navigation = NavigationMode.FORWARD; this.viewParams = ViewParameterMode.DEFAULT; } final String customDefaultBasePathBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_BASE_PATH_BUILDER; if (customDefaultBasePathBuilderClassName != null) { this.basePathBuilder = ClassUtils.tryToLoadClassForName(customDefaultBasePathBuilderClassName); } else { this.basePathBuilder = DefaultBasePathBuilder.class; } final String customDefaultFileNameBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_FILE_NAME_BUILDER; if (customDefaultFileNameBuilderClassName != null) { this.fileNameBuilder = ClassUtils.tryToLoadClassForName(customDefaultFileNameBuilderClassName); } else { this.fileNameBuilder = DefaultFileNameBuilder.class; } final String customDefaultExtensionBuilderClassName = JsfBaseConfig.ViewConfigCustomization.CUSTOM_DEFAULT_EXTENSION_BUILDER; if (customDefaultExtensionBuilderClassName != null) { this.extensionBuilder = ClassUtils.tryToLoadClassForName(customDefaultExtensionBuilderClassName); } else { this.extensionBuilder = DefaultExtensionBuilder.class; } } public ViewLiteral(String basePath, String name, String extension, NavigationMode navigation, ViewParameterMode viewParams, Class basePathBuilder, Class fileNameBuilder, Class extensionBuilder) { this.basePath = basePath; this.name = name; this.extension = extension; this.navigation = navigation; this.viewParams = viewParams; this.basePathBuilder = basePathBuilder; this.fileNameBuilder = fileNameBuilder; this.extensionBuilder = extensionBuilder; } @Override public String basePath() { return this.basePath; } @Override public String name() { return this.name; } @Override public String extension() { return this.extension; } @Override public NavigationMode navigation() { return this.navigation; } @Override public ViewParameterMode viewParams() { return this.viewParams; } @Override public Class basePathBuilder() { return this.basePathBuilder; } @Override public Class fileNameBuilder() { return this.fileNameBuilder; } @Override public Class extensionBuilder() { return this.extensionBuilder; } /* * generated */ @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } if (!(o instanceof ViewLiteral)) { return false; } if (!super.equals(o)) { return false; } ViewLiteral that = (ViewLiteral) o; if (basePath != null ? !basePath.equals(that.basePath) : that.basePath != null) { return false; } if (!basePathBuilder.equals(that.basePathBuilder)) { return false; } if (extension != null ? !extension.equals(that.extension) : that.extension != null) { return false; } if (!extensionBuilder.equals(that.extensionBuilder)) { return false; } if (!fileNameBuilder.equals(that.fileNameBuilder)) { return false; } if (name != null ? !name.equals(that.name) : that.name != null) { return false; } if (navigation != that.navigation) { return false; } if (viewParams != that.viewParams) { return false; } return true; } @Override public int hashCode() { int result = (basePath != null ? basePath.hashCode() : 0); result = 31 * result + (name != null ? name.hashCode() : 0); result = 31 * result + (extension != null ? extension.hashCode() : 0); result = 31 * result + (navigation != null ? navigation.hashCode() : 0); result = 31 * result + (viewParams != null ? viewParams.hashCode() : 0); result = 31 * result + basePathBuilder.hashCode(); result = 31 * result + fileNameBuilder.hashCode(); result = 31 * result + extensionBuilder.hashCode(); return result; } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/api/message/JsfMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.api.message; import jakarta.faces.component.UIComponent; import java.io.Serializable; /** *

An injectable component for typesafe FacesMessages. * T must be a class which is annotated with * {@link org.apache.deltaspike.core.api.message.MessageBundle}

* *

Usage: *

 * @Inject
 * JsfMessage<MyMessages> msg;
 * ...
 * msg.addError().userNotLoggedIn(user);
 * 
*

MessageBundle methods which are used as JsfMessage can return a * {@link org.apache.deltaspike.core.api.message.Message} or a String. * In case of a String we use it for both the summary and detail * information on the FacesMessage.

*

If a Message is returned, we lookup the 'detail' and 'summary' * categories (see {@link org.apache.deltaspike.core.api.message.Message#toString(String)} * for creating the FacesMessage.

* */ public interface JsfMessage extends Serializable { String CATEGORY_DETAIL = "detail"; String CATEGORY_SUMMARY = "summary"; /** * If the JsfMessage is used in a UIComponent we allow to set the clientId * @param clientId */ JsfMessage forClientId(String clientId); /** * @param uiComponent */ JsfMessage forComponent(UIComponent uiComponent); /** * @return the underlying Message which will automatically add a FacesMessage with SEVERITY_ERROR */ T addError(); /** * @return the underlying Message which will automatically add a FacesMessage with SEVERITY_FATAL */ T addFatal(); /** * @return the underlying Message which will automatically add a FacesMessage with SEVERITY_INFO */ T addInfo(); /** * @return the underlying Message which will automatically add a FacesMessage with SEVERITY_WARN */ T addWarn(); /** * @return the underlying Message implementation without adding any FacesMessage */ T get(); } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/config/view/navigation/NavigationParameterStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.spi.config.view.navigation; import org.apache.deltaspike.core.spi.InterceptorStrategy; /** * Allows to provide a custom {@link InterceptorStrategy} */ public interface NavigationParameterStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/ClientWindowConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.spi.scope.window; import jakarta.faces.context.FacesContext; import java.io.Serializable; /** * Configuration for ClientWindow handler which is used * to determine the correct windowId for ?WindowScoped beans. */ public interface ClientWindowConfig extends Serializable { public enum ClientWindowRenderMode { /** * Any window or browser tab detection is disabled for this request */ NONE, /** *

The GET request results in an intermediate small html page which * checks if the browser tab fits the selected windowId

*

The ClientWindow html extracts the windowId from the window.name and * enforces a 2nd GET which will contain the windowId and will get routed * through to the target JSF page.

*/ CLIENTWINDOW, /** * Render each GET request with the windowId you get during the request * and perform a lazy check on the client side via JavaScript or similar. */ LAZY, /** * Delegates to the default window-handling */ DELEGATED, } /** * @return whether JavaScript is enabled */ boolean isJavaScriptEnabled(); /** * @param javaScriptEnabled whether JavaScript is enabled */ void setJavaScriptEnabled(boolean javaScriptEnabled); /** * Determine whether this request should take care of clientWindow detection. * This can e.g. get disabled for download pages or if a useragent doesn't * support html5 or any other required technique. * This only gets checked for GET requests! * * @param facesContext * @return the selected ClientWindowRenderMode */ ClientWindowRenderMode getClientWindowRenderMode(FacesContext facesContext); /** * @return the prepared html which gets sent out to the client as intermediate client window. */ String getClientWindowHtml(); /** * @return Whether the DOM tree should store in the localStorage for the windowhandler.html * when clicking on a link. * Currently, it's only used by {@link ClientWindowRenderMode#CLIENTWINDOW}. * See windowhandler.html */ boolean isClientWindowStoreWindowTreeEnabledOnLinkClick(); /** * @return Whether the DOM tree should store in the localStorage for the windowhandler.html * when clicking on a button. * Currently, it's only used by {@link ClientWindowRenderMode#CLIENTWINDOW}. * See windowhandler.html */ boolean isClientWindowStoreWindowTreeEnabledOnButtonClick(); boolean isClientWindowTokenizedRedirectEnabled(); /** * Restricts the number of active windows. * * @return limit for active windows */ int getMaxWindowContextCount(); } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/spi/scope/window/DefaultClientWindowConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.spi.scope.window; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.SessionScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import org.apache.deltaspike.jsf.util.ValueExpressionEvaluationInputStream; /** *

Default implementation of {@link ClientWindowConfig}. * By default it will use the internal windowhandler.html

* *

You can @Specializes this class to tweak the configuration or * provide a completely new implementation as @Alternative.

*/ @SessionScoped public class DefaultClientWindowConfig implements ClientWindowConfig { private static final long serialVersionUID = -708423418378550210L; /** * The location of the default windowhandler resource */ private static final String DEFAULT_WINDOW_HANDLER_HTML_FILE = "static/windowhandler.html"; private volatile Boolean javaScriptEnabled = null; /** * lazily initiated via {@link #getUserAgent(jakarta.faces.context.FacesContext)} */ private volatile String userAgent = null; /** * Contains the cached ClientWindow handler html for this session. */ private String clientWindowtml; @Inject private JsfModuleConfig jsfModuleConfig; @Inject private ProjectStage projectStage; private ClientWindowRenderMode defaultClientWindowRenderMode; private int maxWindowContextCount; @PostConstruct protected void init() { this.defaultClientWindowRenderMode = this.jsfModuleConfig.getDefaultWindowMode(); this.maxWindowContextCount = JsfBaseConfig.ScopeCustomization.WindowRestriction.MAX_COUNT; } @Override public boolean isJavaScriptEnabled() { if (javaScriptEnabled == null) { synchronized (this) { // double lock checking idiom on volatile variable works since java5 if (javaScriptEnabled == null) { // no info means that it is default -> true javaScriptEnabled = Boolean.TRUE; } } } return javaScriptEnabled; } @Override public void setJavaScriptEnabled(boolean javaScriptEnabled) { this.javaScriptEnabled = Boolean.valueOf(javaScriptEnabled); } /** * By default we use {@link ClientWindowRenderMode#LAZY} unless * we detect a bot. Use {@link org.apache.deltaspike.jsf.api.config.JsfModuleConfig#getDefaultWindowMode()} * to change this default behavior. Alternative: * Override this method to exclude other requests from getting accessed. */ @Override public ClientWindowRenderMode getClientWindowRenderMode(FacesContext facesContext) { if (!isJavaScriptEnabled()) { if (this.defaultClientWindowRenderMode != null) { return this.defaultClientWindowRenderMode; //currently mainly needed for 'DELEGATED' } return ClientWindowRenderMode.NONE; } String userAgent = getUserAgent(facesContext); if (userAgent != null && ( userAgent.indexOf("bot") >= 0 || // Googlebot, etc userAgent.indexOf("Bot") >= 0 || // BingBot, etc userAgent.indexOf("Slurp") >= 0 || // Yahoo Slurp userAgent.indexOf("Crawler") >= 0 // various other Crawlers ) ) { return ClientWindowRenderMode.NONE; } if (this.defaultClientWindowRenderMode != null) { return this.defaultClientWindowRenderMode; } return ClientWindowRenderMode.LAZY; } @Override public String getClientWindowHtml() { if (projectStage != ProjectStage.Development && clientWindowtml != null) { // use cached windowHandlerHtml except in Development return clientWindowtml; } InputStream is = ClassUtils.getClassLoader(null).getResourceAsStream(getClientWindowResourceLocation()); // wrap InputStream to evaluate EL expressions like resource includes is = new ValueExpressionEvaluationInputStream(FacesContext.getCurrentInstance(), is); StringBuffer sb = new StringBuffer(); try { byte[] buf = new byte[16 * 1024]; int bytesRead; while ((bytesRead = is.read(buf)) != -1) { String sbuf = new String(buf, 0, bytesRead); sb.append(sbuf); } } catch (IOException e) { ExceptionUtils.throwAsRuntimeException(e); } finally { try { is.close(); } catch (IOException e) { // do nothing, all fine so far } } clientWindowtml = sb.toString(); return clientWindowtml; } /** * This information will get stored as it cannot * change during the session anyway. * @return the UserAgent of the request. */ public String getUserAgent(FacesContext facesContext) { if (userAgent == null) { synchronized (this) { if (userAgent == null) { Map requestHeaders = facesContext.getExternalContext().getRequestHeaderValuesMap(); if (requestHeaders != null && requestHeaders.containsKey("User-Agent")) { String[] userAgents = requestHeaders.get("User-Agent"); userAgent = userAgents.length > 0 ? userAgents[0] : null; } } } } return userAgent; } /** * Overwrite this to define your own ClientWindow handler html location. * This will get picked up as resource from the classpath. */ public String getClientWindowResourceLocation() { return DEFAULT_WINDOW_HANDLER_HTML_FILE; } @Override public int getMaxWindowContextCount() { return this.maxWindowContextCount; } @Override public boolean isClientWindowStoreWindowTreeEnabledOnLinkClick() { return true; } @Override public boolean isClientWindowStoreWindowTreeEnabledOnButtonClick() { return false; } @Override public boolean isClientWindowTokenizedRedirectEnabled() { return false; } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/util/NamingConventionUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.util; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import java.lang.annotation.Annotation; public abstract class NamingConventionUtils { public static String toPath(ViewConfigNode node) { if (node == null || node.getParent() == null) //root-node { return "/"; } Folder folderMetaData = null; for (Annotation nodeMetaData : node.getMetaData()) { if (Folder.class.isAssignableFrom(nodeMetaData.annotationType())) { folderMetaData = (Folder)nodeMetaData; break; } } String folderName = null; if (folderMetaData != null) { folderName = folderMetaData.name(); } if (".".equals(folderName)) { folderName = null; //default value -> fallback to the default naming } if (folderName == null) { folderName = node.getSource().getSimpleName(); folderName = "./" + folderName.substring(0, 1).toLowerCase() + folderName.substring(1) + "/"; } //@Folder found and no relative path if (folderMetaData != null && !folderName.startsWith(".")) { return folderName; } return toPath(node.getParent()) + folderName.substring(1); } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/java/org/apache/deltaspike/jsf/util/ValueExpressionEvaluationInputStream.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.util; import jakarta.faces.context.FacesContext; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import java.util.logging.Level; import java.util.logging.Logger; /** * A filtered stream that evaluates value expressions in the original stream while reading from it. */ public class ValueExpressionEvaluationInputStream extends InputStream { /** * Logger for this class. */ private static final Logger log = Logger.getLogger(ValueExpressionEvaluationInputStream.class.getName()); private FacesContext facesContext; private PushbackInputStream wrapped; private String currentValue; private int currentValueIndex = -1; public ValueExpressionEvaluationInputStream(FacesContext facesContext, InputStream inputStream) { this.facesContext = facesContext; this.wrapped = new PushbackInputStream(inputStream, 512); } /** * Reads a byte from the original stream and checks for value expression occurrences. * A value expression has the following format: #{xxx} * If a value expression is found, its occurrence in the stream will replaced with * the evaluated value of the expression. * * @return * @throws java.io.IOException */ @Override public int read() throws IOException { // check for a current value if (currentValueIndex != -1) { if (currentValueIndex < currentValue.length()) { return currentValue.charAt(currentValueIndex++); } else { // current value exhausted, reset index currentValueIndex = -1; } } // read byte and check for value expression begin int c1 = wrapped.read(); if (c1 != '#') { return c1; // can't be a value expression, just return the character } else { // could be a value expression, next character must be '{' int c2 = wrapped.read(); if (c2 != '{') { wrapped.unread(c2); // we did not find a value expression, unread byte that we read too much return c1; // return original character } else { // read until '}', '\n' or eof occurs (end of value expression or data) List possibleValueExpression = new LinkedList(); int c = wrapped.read(); boolean insideString = (c == '\''); // a '}' inside a string must not terminate the expression string while (c != -1 && c != '\n' && (insideString || c != '}')) { possibleValueExpression.add(c); c = wrapped.read(); if (c == '\'') { insideString = !insideString; } } if (c != '}') { // we did not find a value expression, unread bytes that we read too much (in reverse order) if (c != -1) // we can't unread eof { wrapped.unread(c); } ListIterator it = possibleValueExpression.listIterator(possibleValueExpression.size()); while (it.hasPrevious()) { wrapped.unread(it.previous()); } wrapped.unread(c2); return c1; // return original character } else { // we found a value expression #{xxx} (xxx is stored in possibleValueExpression) // create the expression string String expressionString = createExpressionString(possibleValueExpression); // evaluate it String expressionValue = facesContext.getApplication() .evaluateExpressionGet(facesContext, expressionString, String.class); if (expressionValue == null) { if (log.isLoggable(Level.WARNING)) { log.warning("ValueExpression " + expressionString + " evaluated to null."); } expressionValue = "null"; // fallback value for null } // do NOT unread the evaluated value, but rather store it in an internal buffer, // because otherwise we could recursively evaluate value expressions (a value expression // that resolves to a string containing "#{...}" would be re-evaluated). this.currentValue = expressionValue; // return first character of currentValue, if exists (not an empty string) if (currentValue.length() != 0) { this.currentValueIndex = 0; return currentValue.charAt(currentValueIndex++); } else // currentValue is an empty string { // in this case we must recursively start a new read (incl. checks for a new value expression) this.currentValueIndex = -1; return read(); } } } } } private String createExpressionString(List expressionList) { char[] expressionChars = new char[expressionList.size() + 3]; // #{expressionList} int i = 0; expressionChars[i++] = '#'; expressionChars[i++] = '{'; for (Integer c : expressionList) { expressionChars[i++] = (char) c.intValue(); } expressionChars[i] = '}'; return String.valueOf(expressionChars); } } ================================================ FILE: deltaspike/modules/jsf/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jsf/api/src/test/java/org/apache/deltaspike/jsf/util/ValueExpressionEvaluationInputStreamTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.util; import org.junit.jupiter.api.Test; import jakarta.faces.context.FacesContext; import java.io.ByteArrayInputStream; import org.apache.myfaces.test.base.junit.AbstractJsfTestCase; import org.junit.jupiter.api.Assertions; /** * Tests for {@link ValueExpressionEvaluationInputStream}. */ public class ValueExpressionEvaluationInputStreamTest extends AbstractJsfTestCase { @Test public void testStreamWithoutExpression_mustBeUnmodified() throws Exception { final String data = "aa\nbbbb\ncccc\ndddd\n\n"; byte[] dataArray = data.getBytes(); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[dataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(dataArray, inputStreamDataArray); // data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamWithSimpleExpression_mustBeEvaluated() throws Exception { final String data = "aa\nbbbb\ncc#{requestScope.test}cc\ndddd\n\n"; final String evaluatedData = "aa\nbbbb\ncctest-valuecc\ndddd\n\n"; byte[] dataArray = data.getBytes(); byte[] evaluatedDataArray = evaluatedData.getBytes(); // put test value into scope, so that expression can evaluate to this value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "test-value"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[evaluatedDataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(evaluatedDataArray, inputStreamDataArray); // evaluated data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamWithHalfExpressionAtEnd_mustBeUnmodified() throws Exception { final String data = "aa\nbbbb\ncccc\ndddd\n\n#{requestScope.test"; // } is missing at the end byte[] dataArray = data.getBytes(); // put test value into scope, so that expression could evaluate to this value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "test-value"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[dataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(dataArray, inputStreamDataArray); // data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamWithHalfExpressionAtLineEnd_mustBeUnmodified() throws Exception { final String data = "aa\nbb#{requestScope.test\n}bb\ncccc\ndddd\n\n"; // } is missing at the end byte[] dataArray = data.getBytes(); // put test value into scope, so that expression could evaluate to this value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "test-value"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[dataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(dataArray, inputStreamDataArray); // data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamWithExpressionEvaluatingToExpressionString_mustOnlyEvaluateFirstExpression() throws Exception { final String data = "aa\nbbbb\ncc#{requestScope.test}cc\ndddd\n\n"; final String evaluatedData = "aa\nbbbb\ncc#{requestScope.test2}cc\ndddd\n\n"; byte[] dataArray = data.getBytes(); byte[] evaluatedDataArray = evaluatedData.getBytes(); // put test value into scope, so that expression can evaluate to this value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "#{requestScope.test2}"); FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test2", "test-value"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[evaluatedDataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(evaluatedDataArray, inputStreamDataArray); // evaluated data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamThatOnlyConsistsOfExpression_mustEvaluateExpression() throws Exception { final String data = "#{requestScope.test}"; final String evaluatedData = "test-value"; byte[] dataArray = data.getBytes(); byte[] evaluatedDataArray = evaluatedData.getBytes(); // put test value into scope, so that expression can evaluate to this value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "test-value"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[evaluatedDataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(evaluatedDataArray, inputStreamDataArray); // evaluated data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } @Test public void testStreamWithNullExpression_mustEvaluateToEmptyString() throws Exception { final String data = "aa\nbbbb\ncc#{requestScope.test}cc\ndddd\n\n"; final String evaluatedData = "aa\nbbbb\ncccc\ndddd\n\n"; byte[] dataArray = data.getBytes(); byte[] evaluatedDataArray = evaluatedData.getBytes(); // make sure there is no value FacesContext.getCurrentInstance().getExternalContext().getRequestMap().remove("test"); ValueExpressionEvaluationInputStream inputStream = new ValueExpressionEvaluationInputStream( FacesContext.getCurrentInstance(), new ByteArrayInputStream(dataArray)); byte[] inputStreamDataArray = new byte[evaluatedDataArray.length]; inputStream.read(inputStreamDataArray); // checks Assertions.assertArrayEquals(evaluatedDataArray, inputStreamDataArray); // evaluated data arrays must match Assertions.assertEquals(-1, inputStream.read()); // stream must be at eof } } ================================================ FILE: deltaspike/modules/jsf/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules jsf-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-jsf-module-impl Apache DeltaSpike JSF-Module Impl 4.34.0 org.apache.maven.plugins maven-resources-plugin 2.6 process-resources copy-resources true ${project.build.directory}/classes/META-INF/resources/deltaspike-uncompressed ${project.build.directory}/classes/META-INF/resources/deltaspike org.primefaces.extensions resources-optimizer-maven-plugin 1.0.0 compile optimize ${project.build.directory}/classes/META-INF/resources/deltaspike/ **/*.js **/*.css org.apache.deltaspike.core deltaspike-core-api ${project.version} compile org.apache.deltaspike.core deltaspike-core-impl ${project.version} compile org.apache.deltaspike.modules deltaspike-security-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-security-module-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-jsf-module-api ${project.version} compile org.apache.deltaspike.modules deltaspike-proxy-module-impl-asm ${project.version} true runtime org.owasp.encoder encoder compile jakarta.el jakarta.el-api provided org.apache.tomcat tomcat-servlet-api provided org.jboss.arquillian.container arquillian-container-test-api test org.jboss.arquillian.junit arquillian-junit-core test org.jboss.arquillian.test arquillian-test-api test org.jboss.shrinkwrap shrinkwrap-api test org.seleniumhq.selenium htmlunit3-driver ${selenium.version} test org.seleniumhq.selenium selenium-api ${selenium.version} test org.seleniumhq.selenium selenium-support ${selenium.version} test tomee-build-managed org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} org/apache/deltaspike/test/jsf/impl/injection/**/* org.apache.myfaces.core myfaces-impl ${myfaces.version} test ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/clientwindow/ClientSideClientWindow.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.clientwindow; import jakarta.faces.FacesException; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import org.apache.deltaspike.jsf.impl.util.ClientWindowHelper; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import java.io.IOException; import java.io.OutputStream; import java.util.Collections; import java.util.Map; public class ClientSideClientWindow extends DeltaSpikeClientWindow { /** * Value which can be used as "window-id" by external clients which aren't aware of windows. * It deactivates e.g. the redirect for the initial request. */ private static final String AUTOMATED_ENTRY_POINT_PARAMETER_KEY = "automatedEntryPoint"; private static final String UNINITIALIZED_WINDOW_ID_VALUE = "uninitializedWindowId"; private static final String WINDOW_ID_REPLACE_PATTERN = "$$windowIdValue$$"; private static final String REQUEST_URL_REPLACE_PATTERN = "$$requestUrl$$"; private static final String NOSCRIPT_URL_REPLACE_PATTERN = "$$noscriptUrl$$"; /** * Use this parameter to force a 'direct' request from the clients without any windowId detection * We keep this name for backward compat with CODI. */ private static final String NOSCRIPT_PARAMETER = "mfDirect"; @Override public void decode(FacesContext facesContext) { boolean post = isPost(facesContext); if (post) { id = getWindowIdPostParameter(facesContext); } else if (isNoscriptRequest(facesContext.getExternalContext())) { // the client has JavaScript disabled getClientWindowConfig().setJavaScriptEnabled(false); id = DEFAULT_WINDOW_ID; } else { id = getVerifiedWindowIdFromCookie(facesContext.getExternalContext()); boolean newWindowIdRequested = false; if (AUTOMATED_ENTRY_POINT_PARAMETER_KEY.equals(id)) { // this is a marker for generating a new windowId id = generateNewWindowId(); newWindowIdRequested = true; } if (id == null || newWindowIdRequested) { // GET request without windowId - send windowhandlerfilter.html to get the windowId sendWindowHandlerHtml(facesContext, facesContext.getExternalContext(), id); facesContext.responseComplete(); } } id = sanitiseWindowId(id); } protected boolean isNoscriptRequest(ExternalContext externalContext) { String noscript = externalContext.getRequestParameterMap().get(NOSCRIPT_PARAMETER); return (noscript != null && "true".equals(noscript)); } protected void sendWindowHandlerHtml(FacesContext facesContext, ExternalContext externalContext, String windowId) { HttpServletResponse httpResponse = (HttpServletResponse) externalContext.getResponse(); try { httpResponse.setStatus(HttpServletResponse.SC_OK); httpResponse.setContentType("text/html"); String windowHandlerHtml = getClientWindowConfig().getClientWindowHtml(); if (windowId == null) { windowId = UNINITIALIZED_WINDOW_ID_VALUE; } // set the windowId value in the javascript code windowHandlerHtml = windowHandlerHtml.replace(WINDOW_ID_REPLACE_PATTERN, org.owasp.encoder.Encode.forJavaScriptBlock(windowId)); // set the current request url // on the client we can't use window.location as the location // could be a different when using forwards windowHandlerHtml = windowHandlerHtml.replace(REQUEST_URL_REPLACE_PATTERN, org.owasp.encoder.Encode.forJavaScriptBlock( ClientWindowHelper.constructRequestUrl(facesContext, externalContext))); // set the noscript-URL for users with no JavaScript windowHandlerHtml = windowHandlerHtml.replace(NOSCRIPT_URL_REPLACE_PATTERN, org.owasp.encoder.Encode.forHtmlAttribute(getNoscriptUrl(externalContext))); OutputStream os = httpResponse.getOutputStream(); try { os.write(windowHandlerHtml.getBytes()); } finally { os.close(); } } catch (IOException ioe) { throw new FacesException(ioe); } } protected String getNoscriptUrl(ExternalContext externalContext) { String url = externalContext.getRequestPathInfo(); if (url == null) { url = ""; } // only use the very last part of the url int lastSlash = url.lastIndexOf('/'); if (lastSlash != -1) { url = url.substring(lastSlash + 1); } // add request parameter url = JsfUtils.addPageParameters(externalContext, url, true); url = JsfUtils.addParameter(externalContext, url, false, NOSCRIPT_PARAMETER, "true"); // NOTE that the url could contain data for an XSS attack // like e.g. ?"> getQueryURLParameters(FacesContext facesContext) { return Collections.emptyMap(); } @Override public boolean isClientWindowRenderModeEnabled(FacesContext facesContext) { return false; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/clientwindow/DeltaSpikeClientWindow.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.clientwindow; import jakarta.faces.context.FacesContext; import jakarta.faces.lifecycle.ClientWindow; import jakarta.faces.render.ResponseStateManager; import jakarta.servlet.http.HttpServletRequest; import java.util.Map; import java.util.Random; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.StringUtils; import org.apache.deltaspike.jsf.impl.util.ClientWindowHelper; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; public abstract class DeltaSpikeClientWindow extends ClientWindow { /** * This windowId will be used for all requests with disabled windowId feature */ public static final String DEFAULT_WINDOW_ID = "default"; protected String id; protected int maxWindowIdCount = 10; public DeltaSpikeClientWindow() { this.maxWindowIdCount = ClientWindowHelper.getMaxWindowIdLength(); } @Override public String getId() { return id; } /** * We have to escape some characters to make sure we do not open * any XSS vectors. E.g. replace (,<, & etc to * prevent attackers from injecting JavaScript function calls or html. */ protected String sanitiseWindowId(String windowId) { if (windowId == null) { return null; } windowId = StringUtils.removeSpecialChars(windowId); if (windowId.length() > this.maxWindowIdCount) { windowId = windowId.substring(0, this.maxWindowIdCount); } return windowId; } protected String generateNewWindowId() { //X TODO proper mechanism return Integer.toString((new Random()).nextInt() % 10000); } protected String generateNewRequestToken() { return Integer.toString((int) Math.floor(Math.random() * 999)); } protected boolean isPost(FacesContext facesContext) { if (facesContext.isPostback()) { return true; } Object request = facesContext.getExternalContext().getRequest(); if (request instanceof HttpServletRequest) { if ("POST".equals(((HttpServletRequest) request).getMethod())) { return true; } } return false; } protected String getWindowIdPostParameter(FacesContext facesContext) { Map requestParams = facesContext.getExternalContext().getRequestParameterMap(); return requestParams.get(ResponseStateManager.CLIENT_WINDOW_PARAM); } protected String getWindowIdParameter(FacesContext facesContext) { Map requestParameters = facesContext.getExternalContext().getRequestParameterMap(); return requestParameters.get(ResponseStateManager.CLIENT_WINDOW_URL_PARAM); } protected ClientWindowConfig getClientWindowConfig() { return BeanProvider.getContextualReference(ClientWindowConfig.class); } /** * @return true if the implementation possible sends an initial redirect. */ public abstract boolean isInitialRedirectSupported(FacesContext facesContext); /** * @return The new redirect url. */ public abstract String interceptRedirect(FacesContext facesContext, String url); } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/clientwindow/LazyClientWindow.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.clientwindow; import org.apache.deltaspike.jsf.impl.util.ClientWindowHelper; import jakarta.faces.context.FacesContext; import java.util.Collections; import java.util.Map; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.StringUtils; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; public class LazyClientWindow extends DeltaSpikeClientWindow { @Override public void decode(FacesContext facesContext) { id = ClientWindowHelper.getInitialRedirectWindowId(facesContext); if (StringUtils.isEmpty(id)) { id = getWindowIdParameter(facesContext); } boolean post = isPost(facesContext); if (StringUtils.isEmpty(id) && post) { id = getWindowIdPostParameter(facesContext); } if (StringUtils.isEmpty(id)) { id = generateNewWindowId(); JsfModuleConfig jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); if (jsfModuleConfig.isInitialRedirectEnabled() && !post) { id = sanitiseWindowId(id); // handleInitialRedirect already takes the id, just be sure and sanitise now ClientWindowHelper.handleInitialRedirect(facesContext, id); facesContext.responseComplete(); } } id = sanitiseWindowId(id); } @Override public Map getQueryURLParameters(FacesContext facesContext) { return Collections.emptyMap(); } @Override public boolean isInitialRedirectSupported(FacesContext facesContext) { return true; } @Override public String interceptRedirect(FacesContext facesContext, String url) { return url; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/component/token/PostRequestTokenComponent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.component.token; import org.apache.deltaspike.jsf.impl.token.PostRequestTokenMarker; import jakarta.faces.component.FacesComponent; import jakarta.faces.component.UIInput; /** * Component for rendering the post-request-token */ @FacesComponent(PostRequestTokenComponent.COMPONENT_TYPE) public class PostRequestTokenComponent extends UIInput { public static final String COMPONENT_TYPE = "org.apache.deltaspike.PostRequestTokenHolder"; private transient String markedId; @Override public String getId() { if (this.markedId == null) { String originalId = super.getId(); if (originalId.contains(PostRequestTokenMarker.POST_REQUEST_TOKEN_KEY)) { this.markedId = originalId; } else { this.markedId = originalId + "_" + PostRequestTokenMarker.POST_REQUEST_TOKEN_KEY; } } return this.markedId; } //don't use #restoreState - we couldn't support stateless views,... } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/component/token/RequestTokenHtmlRenderer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.component.token; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jsf.impl.token.PostRequestTokenManager; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.context.ResponseWriter; import jakarta.faces.render.FacesRenderer; import jakarta.faces.render.Renderer; import java.io.IOException; @FacesRenderer( componentFamily = PostRequestTokenComponent.COMPONENT_FAMILY, rendererType = PostRequestTokenComponent.COMPONENT_TYPE) public class RequestTokenHtmlRenderer extends Renderer { private static final String INPUT_ELEMENT = "input"; private static final String TYPE_ATTRIBUTE = "type"; private static final String INPUT_TYPE_HIDDEN = "hidden"; private static final String ID_ATTRIBUTE = "id"; private static final String NAME_ATTRIBUTE = "name"; private static final String VALUE_ATTRIBUTE = "value"; private volatile PostRequestTokenManager postRequestTokenManager; @Override public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException { ResponseWriter writer = facesContext.getResponseWriter(); writer.startElement(INPUT_ELEMENT, component); writer.writeAttribute(TYPE_ATTRIBUTE, INPUT_TYPE_HIDDEN, null); String clientId = component.getClientId(facesContext); writer.writeAttribute(ID_ATTRIBUTE, clientId, null); writer.writeAttribute(NAME_ATTRIBUTE, clientId, null); String currentPostRequestToken = getPostRequestTokenManager().getCurrentToken(); if (currentPostRequestToken != null) { writer.writeAttribute(VALUE_ATTRIBUTE, currentPostRequestToken, VALUE_ATTRIBUTE); } writer.endElement(INPUT_ELEMENT); } //don't use #decode - we couldn't support DSP for immediate actions private PostRequestTokenManager getPostRequestTokenManager() { if (this.postRequestTokenManager == null) { synchronized (this) { if (this.postRequestTokenManager == null) { this.postRequestTokenManager = BeanProvider.getContextualReference(PostRequestTokenManager.class); } } } return this.postRequestTokenManager; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/component/window/WindowIdComponent.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.component.window; import jakarta.faces.component.FacesComponent; import jakarta.faces.component.UIOutput; /** * {@link WindowIdHtmlRenderer} will render a small script needed for ajax-requests */ @FacesComponent(WindowIdComponent.COMPONENT_TYPE) public class WindowIdComponent extends UIOutput { public static final String COMPONENT_TYPE = "org.apache.deltaspike.WindowIdHolder"; } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/component/window/WindowIdHtmlRenderer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.component.window; import jakarta.faces.application.ResourceDependencies; import jakarta.faces.application.ResourceDependency; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.context.ResponseWriter; import jakarta.faces.lifecycle.ClientWindow; import jakarta.faces.render.FacesRenderer; import jakarta.faces.render.Renderer; import java.io.IOException; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jsf.impl.clientwindow.DeltaSpikeClientWindow; import org.apache.deltaspike.jsf.impl.util.ClientWindowHelper; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; @FacesRenderer(componentFamily = WindowIdComponent.COMPONENT_FAMILY, rendererType = WindowIdComponent.COMPONENT_TYPE) @ResourceDependencies( { @ResourceDependency(library = "deltaspike", name = "windowhandler.js", target = "head"), @ResourceDependency(library = "jakarta.faces", name = "faces.js", target = "head") } ) public class WindowIdHtmlRenderer extends Renderer { private volatile ClientWindowConfig clientWindowConfig; private int maxWindowIdLength = 10; /** * 'deltaspikeJsWindowId' will be used to: * Write a simple hidden field into the form. * This might change in the future... * @param context * @param component * @throws IOException */ @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { super.encodeBegin(context, component); lazyInit(); ClientWindowConfig.ClientWindowRenderMode clientWindowRenderMode = clientWindowConfig.getClientWindowRenderMode(context); // see DELTASPIKE-1113 boolean delegatedWindowMode = ClientWindowConfig.ClientWindowRenderMode.DELEGATED.equals(clientWindowRenderMode); if (delegatedWindowMode) { return; } ClientWindow clientWindow = context.getExternalContext().getClientWindow(); if (clientWindow == null && !(clientWindow instanceof DeltaSpikeClientWindow)) { return; } String windowId = clientWindow.getId(); // just to get sure if a user provides a own client window windowId = secureWindowId(windowId); ResponseWriter writer = context.getResponseWriter(); writer.write(""); } protected String secureWindowId(String windowId) { //restrict the length to prevent script-injection if (windowId != null && windowId.length() > this.maxWindowIdLength) { windowId = windowId.substring(0, this.maxWindowIdLength); } return windowId; } private void lazyInit() { if (clientWindowConfig == null) { synchronized (this) { if (clientWindowConfig == null) { clientWindowConfig = BeanProvider.getContextualReference(ClientWindowConfig.class); maxWindowIdLength = ClientWindowHelper.getMaxWindowIdLength(); } } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/AbstractConfigNode.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; public abstract class AbstractConfigNode implements ViewConfigNode { private final ViewConfigNode parent; private List children = new ArrayList(); private Set metaData; private List inheritedMetaData = new ArrayList(); private Map, List> callbackDescriptors = new HashMap, List>(); protected AbstractConfigNode(ViewConfigNode parent, Set metaData) { this.parent = parent; this.metaData = new HashSet(metaData); //might be read-only (from Annotated#getAnnotations) } @Override public ViewConfigNode getParent() { return this.parent; } @Override public List getChildren() { return this.children; } @Override public Set getMetaData() { return this.metaData; } @Override public List getInheritedMetaData() { return this.inheritedMetaData; } @Override public Map, List> getCallbackDescriptors() { return this.callbackDescriptors; } @Override public List getCallbackDescriptors(Class metaDataType) { List result = this.callbackDescriptors.get(metaDataType); if (result == null) { result = new ArrayList(); this.callbackDescriptors.put(metaDataType, result); } return result; } @Override public void registerCallbackDescriptors(Class metaDataType, CallbackDescriptor callbackDescriptor) { if (!callbackDescriptor.getCallbackMethods().isEmpty()) { getCallbackDescriptors(metaDataType).add(callbackDescriptor); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/AbstractPathConfigDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.metadata.ExecutableCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; abstract class AbstractPathConfigDescriptor implements ConfigDescriptor { private final Class source; private List metaData; private Map, List> callbackDescriptors; AbstractPathConfigDescriptor(Class configClass, List mergedMetaData, Map, List> callbackDescriptors) { this.source = configClass; this.metaData = Collections.unmodifiableList(mergedMetaData); this.callbackDescriptors = callbackDescriptors; } @Override public Class getConfigClass() { return this.source; } @Override public List getMetaData() { return this.metaData; } @Override public List getMetaData(Class target) { List result = new ArrayList(); for (Annotation annotation : this.metaData) { if (target.isAssignableFrom(annotation.annotationType())) { result.add((T) annotation); } } return result; } @Override public CallbackDescriptor getCallbackDescriptor(Class metaDataType) { return getCallbackDescriptor(metaDataType, DefaultCallback.class); } @Override public CallbackDescriptor getCallbackDescriptor(Class metaDataType, Class callbackType) { return findCallbackDescriptor(metaDataType, callbackType); } @Override public T getExecutableCallbackDescriptor( Class metaDataType, Class executorType) { return getExecutableCallbackDescriptor(metaDataType, DefaultCallback.class, executorType); } @Override public T getExecutableCallbackDescriptor( Class metaDataType, Class callbackType, Class executorType) { return findCallbackDescriptor(metaDataType, callbackType); } private T findCallbackDescriptor(Class metaDataType, Class callbackType) { List foundDescriptors = callbackDescriptors.get(metaDataType); if (foundDescriptors == null || foundDescriptors.isEmpty()) { return null; } if (callbackType == null || DefaultCallback.class.equals(callbackType)) { if (foundDescriptors.size() > 1) { //TODO validate during bootstrapping throw new IllegalStateException("multiple descriptors for " + ((callbackType == null) ? DefaultCallback.class.getName() : callbackType.getName()) + " aren't allowed"); } return (T)foundDescriptors.iterator().next(); } for (CallbackDescriptor callbackDescriptor : foundDescriptors) { if (callbackDescriptor.isBoundTo(callbackType)) { return (T)callbackDescriptor; } } return null; } @Override public String toString() { return getPath(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultConfigNodeConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.view.metadata.Aggregated; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.SkipMetaDataMerge; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.spi.config.view.ConfigNodeConverter; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.util.AnnotationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.util.ViewConfigUtils; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class DefaultConfigNodeConverter implements ConfigNodeConverter { @Override public ConfigDescriptor convert(ViewConfigNode node) { List mergedMetaData = mergeMetaData(node.getMetaData(), node.getInheritedMetaData()); //e.g. replace default placeholders needed for the merge with real default values mergedMetaData = preProcessMetaData(mergedMetaData, node); Class sourceClass = node.getSource(); if (ViewConfigUtils.isFolderConfig(sourceClass)) { Folder folderAnnotation = findMetaDataByType(mergedMetaData, Folder.class); return new DefaultFolderConfigDescriptor(folderAnnotation.name(), node.getSource(), mergedMetaData, node.getCallbackDescriptors()); } else if (ViewConfig.class.isAssignableFrom(sourceClass)) { View viewAnnotation = findMetaDataByType(mergedMetaData, View.class); String viewId = viewAnnotation.basePath() + viewAnnotation.name() + "." + viewAnnotation.extension(); return new DefaultViewPathConfigDescriptor(viewId, (Class) node.getSource(), filterInheritedFolderMetaData(mergedMetaData), node.getCallbackDescriptors()); } else { throw new IllegalStateException(node.getSource() + " isn't a valid view-config"); } } private T findMetaDataByType(List metaData, Class target) { for (Annotation annotation : metaData) { if (target.equals(annotation.annotationType())) { return (T) annotation; } } return null; } private List mergeMetaData(Set metaData, List inheritedMetaData) { //TODO add qualifier support List nodeViewMetaData = new ArrayList(); List viewMetaDataFromStereotype = new ArrayList(); for (Annotation annotation : metaData) { if (annotation.annotationType().isAnnotationPresent(ViewMetaData.class)) { nodeViewMetaData.add(annotation); } //TODO move to stereotype-util, improve it and merge it with DefaultViewConfigInheritanceStrategy if (annotation.annotationType().isAnnotationPresent(Stereotype.class)) { for (Annotation metaAnnotation : annotation.annotationType().getAnnotations()) { if (metaAnnotation.annotationType().isAnnotationPresent(ViewMetaData.class)) { viewMetaDataFromStereotype.add(metaAnnotation); } } } } //merge meta-data of same level List result = mergeAnnotationInstances(viewMetaDataFromStereotype, nodeViewMetaData); if (inheritedMetaData != null && !inheritedMetaData.isEmpty()) { //merge meta-data with levels above result = mergeAnnotationInstances(inheritedMetaData, result); } return result; } private List mergeAnnotationInstances(List inheritedMetaData, List nodeMetaData) { List mergedResult = new ArrayList(); for (Annotation inheritedAnnotation : inheritedMetaData) { ViewMetaData viewMetaData = inheritedAnnotation.annotationType().getAnnotation(ViewMetaData.class); if (viewMetaData == null) { continue; } Aggregated aggregated = inheritedAnnotation.annotationType().getAnnotation(Aggregated.class); if (aggregated == null) { aggregated = viewMetaData.annotationType().getAnnotation(Aggregated.class); } if (aggregated.value()) //aggregation for the whole annotation is allowed { mergedResult.add(inheritedAnnotation); } else { Annotation currentNodeMetaData = findInResult(nodeMetaData, inheritedAnnotation); if (currentNodeMetaData == null) { Annotation mergedMetaData = findInResult(mergedResult, inheritedAnnotation); if (mergedMetaData == null) { mergedResult.add(inheritedAnnotation); } else { Annotation mergedAnnotation = mergeAnnotationInstance(mergedMetaData, inheritedAnnotation); mergedResult.add(mergedAnnotation); } } else { Annotation mergedAnnotation = mergeAnnotationInstance(currentNodeMetaData, inheritedAnnotation); mergedResult.add(mergedAnnotation); } } } //add all annotations at the beginning which weren't used for the merge mergedResult.addAll(0, nodeMetaData); return mergedResult; } private Annotation mergeAnnotationInstance(Annotation existingMetaData, Annotation inheritedMetaData) { Map values = new HashMap(); for (Method annotationMethod : existingMetaData.annotationType().getDeclaredMethods()) { annotationMethod.setAccessible(true); //TODO Annotation defaultAnnotation = AnnotationInstanceProvider.of(existingMetaData.annotationType()); try { Object defaultValue = null; try { defaultValue = annotationMethod.invoke(defaultAnnotation); } catch (Exception e) //happens with primitive data-types without default values { defaultValue = null; } Object existingValue = annotationMethod.invoke(existingMetaData); if (existingValue == null /*possible with literal instances*/ || existingValue.equals(defaultValue)) { Object inheritedValue = annotationMethod.invoke(inheritedMetaData); if (inheritedValue == null /*possible with literal instances*/ || inheritedValue.equals(defaultValue) || annotationMethod.isAnnotationPresent(SkipMetaDataMerge.class)) { values.put(annotationMethod.getName(), defaultValue); } else { values.put(annotationMethod.getName(), inheritedValue); } } else { values.put(annotationMethod.getName(), existingValue); } } catch (Exception e) { ExceptionUtils.throwAsRuntimeException(e); } } //TODO add aggregation in case of arrays return AnnotationInstanceProvider.of(existingMetaData.annotationType(), values); } private List preProcessMetaData(List mergedMetaData, ViewConfigNode node) { List result = new ArrayList(mergedMetaData.size()); for (Annotation annotation : mergedMetaData) { ViewMetaData viewMetaData = annotation.annotationType().getAnnotation(ViewMetaData.class); Class preProcessorClass = viewMetaData.preProcessor(); if (!ConfigPreProcessor.class.equals(preProcessorClass)) { String customPreProcessorClassName = ConfigResolver.getPropertyValue(preProcessorClass.getName(), null); if (customPreProcessorClassName != null) { Class customPreProcessorClass = ClassUtils.tryToLoadClassForName(customPreProcessorClassName, ConfigPreProcessor.class); if (customPreProcessorClass != null) { preProcessorClass = customPreProcessorClass; } else { throw new IllegalStateException(customPreProcessorClassName + " is configured to replace " + preProcessorClass.getName() + ", but it wasn't possible to load it."); } } ConfigPreProcessor preProcessor = ClassUtils.tryToInstantiateClass(preProcessorClass); Annotation resultToAdd = preProcessor.beforeAddToConfig(annotation, node); //it isn't possible to detect changed annotations if (resultToAdd != annotation) //check if the annotation(-instance) was changed { validateAnnotationChange(annotation); rewriteMetaDataOfNode(node.getMetaData(), annotation, resultToAdd); rewriteMetaDataOfNode(node.getInheritedMetaData(), annotation, resultToAdd); } result.add(resultToAdd); } else { result.add(annotation); } } return result; } private Annotation findInResult(List annotationList, Annotation annotationToFind) { for (Annotation annotation : annotationList) { if (annotationToFind.annotationType().equals(annotation.annotationType())) { annotationList.remove(annotation); return annotation; } } return null; } private List filterInheritedFolderMetaData(List mergedMetaData) { List result = new ArrayList(); for (Annotation metaData : mergedMetaData) { if (!Folder.class.equals(metaData.annotationType())) { result.add(metaData); } } return result; } protected void validateAnnotationChange(Annotation annotation) { Class annotationType = annotation.annotationType(); if (Folder.class.equals(annotationType) || View.class.equals(annotationType)) { return; } ViewMetaData viewMetaData = annotationType.getAnnotation(ViewMetaData.class); if (viewMetaData == null) { return; } Aggregated aggregated = viewMetaData.annotationType().getAnnotation(Aggregated.class); if (aggregated != null && aggregated.value()) { throw new IllegalStateException("it isn't supported to change aggregated meta-data," + "because inheritance won't work correctly"); } } protected void rewriteMetaDataOfNode(Collection metaData, Annotation oldMetaData, Annotation newMetaData) { Iterator metaDataIterator = metaData.iterator(); while (metaDataIterator.hasNext()) { Annotation currentMetaData = metaDataIterator.next(); if (AnnotationUtils.getQualifierHashCode(currentMetaData) == AnnotationUtils.getQualifierHashCode(oldMetaData)) { metaDataIterator.remove(); metaData.add(newMetaData); break; } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultErrorViewAwareExceptionHandlerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.api.projectstage.TestStage; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ProjectStageProducer; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.faces.FacesException; import jakarta.faces.application.ViewExpiredException; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.ExceptionHandler; import jakarta.faces.context.ExceptionHandlerWrapper; import jakarta.faces.context.FacesContext; import jakarta.faces.context.Flash; import jakarta.faces.event.ExceptionQueuedEvent; import jakarta.faces.event.ExceptionQueuedEventContext; import java.util.Iterator; public class DefaultErrorViewAwareExceptionHandlerWrapper extends ExceptionHandlerWrapper implements Deactivatable { private ExceptionHandler wrapped; private volatile ViewNavigationHandler viewNavigationHandler; /** * Constructor used by proxy libs */ protected DefaultErrorViewAwareExceptionHandlerWrapper() { } public DefaultErrorViewAwareExceptionHandlerWrapper(ExceptionHandler wrapped) { this.wrapped = wrapped; } @Override public void handle() throws FacesException { lazyInit(); Iterator exceptionQueuedEventIterator = getUnhandledExceptionQueuedEvents().iterator(); while (exceptionQueuedEventIterator.hasNext()) { ExceptionQueuedEventContext exceptionQueuedEventContext = (ExceptionQueuedEventContext) exceptionQueuedEventIterator.next().getSource(); @SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" }) Throwable throwable = exceptionQueuedEventContext.getException(); String viewId = null; if (!isExceptionToHandle(throwable)) { continue; } FacesContext facesContext = exceptionQueuedEventContext.getContext(); Flash flash = facesContext.getExternalContext().getFlash(); if (throwable instanceof ViewExpiredException) { viewId = ((ViewExpiredException) throwable).getViewId(); } else if (throwable instanceof ContextNotActiveException) { //the error page uses a cdi scope which isn't active as well //(it's recorded below - see flash.put(throwable.getClass().getName(), throwable);) if (flash.containsKey(ContextNotActiveException.class.getName())) { //TODO show it in case of project-stage development break; } if (facesContext.getViewRoot() != null) { viewId = facesContext.getViewRoot().getViewId(); } else { viewId = BeanProvider.getContextualReference(ViewConfigResolver.class) //has to return a value otherwise this handler wouldn't be active .getDefaultErrorViewConfigDescriptor().getViewId(); } } if (viewId != null) { UIViewRoot uiViewRoot = facesContext.getApplication().getViewHandler().createView(facesContext, viewId); if (uiViewRoot == null) { continue; } if (facesContext.isProjectStage(jakarta.faces.application.ProjectStage.Development) || ProjectStageProducer.getInstance().getProjectStage() == ProjectStage.Development || ProjectStageProducer.getInstance().getProjectStage() instanceof TestStage) { throwable.printStackTrace(); } facesContext.setViewRoot(uiViewRoot); exceptionQueuedEventIterator.remove(); //record the current exception -> to check it at the next call or to use it on the error-page flash.put(throwable.getClass().getName(), throwable); flash.keep(throwable.getClass().getName()); this.viewNavigationHandler.navigateTo(DefaultErrorView.class); break; } } this.wrapped.handle(); } //TODO it should be possible to configure the exceptions we handle //e.g. @View could specify which exception/s a page // - can recover from (-> redirect in case of a POST to refresh the state + optional message) // - can't recover from (-> redirect to the default-error page) protected boolean isExceptionToHandle(Throwable throwable) { return throwable instanceof ViewExpiredException || throwable instanceof ContextNotActiveException; } private void lazyInit() { if (this.viewNavigationHandler == null) { this.viewNavigationHandler = BeanProvider.getContextualReference(ViewNavigationHandler.class); } } @Override public ExceptionHandler getWrapped() { lazyInit(); return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultFolderConfigDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import java.lang.annotation.Annotation; import java.util.List; import java.util.Map; class DefaultFolderConfigDescriptor extends AbstractPathConfigDescriptor { private final String path; DefaultFolderConfigDescriptor(String path, Class configClass, List mergedMetaData, Map, List> callbackDescriptors) { super(configClass, mergedMetaData, callbackDescriptors); this.path = path; } @Override public String getPath() { return this.path; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultViewConfigInheritanceStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.Aggregated; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ViewConfigInheritanceStrategy; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.util.ViewConfigUtils; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Stack; //TODO remove parts which aren't needed any longer public class DefaultViewConfigInheritanceStrategy implements ViewConfigInheritanceStrategy { @Override public List resolveInheritedMetaData(ViewConfigNode viewConfigNode) { List inheritedAnnotations = new ArrayList(); Set processedTypes = new HashSet(); processedTypes.add(ViewConfig.class); //filter the base interface in any case Stack classesToAnalyze = new Stack(); addInterfaces(processedTypes, classesToAnalyze, viewConfigNode.getSource()); //don't add the page-class itself while (!classesToAnalyze.empty()) { Class currentClass = classesToAnalyze.pop(); if (processedTypes.contains(currentClass)) { continue; } processedTypes.add(currentClass); addInterfaces(processedTypes, classesToAnalyze, currentClass); //don't add the annotations of the final view-config class itself (we just need the inherited annotations) if (ViewConfigUtils.isFolderConfig(currentClass)) { inheritedAnnotations.addAll(findViewMetaData(currentClass, viewConfigNode)); } Class nextClass = currentClass.getSuperclass(); if (nextClass != null && !Object.class.equals(nextClass)) { if (!processedTypes.contains(nextClass)) { classesToAnalyze.push(nextClass); } } } //add meta-data inherited via stereotypes on the node itself inheritedAnnotations.addAll(findViewMetaData(viewConfigNode.getSource(), viewConfigNode)); return inheritedAnnotations; } protected List findViewMetaData(Class currentClass, ViewConfigNode viewConfigNode) { //don't include meta-data from the node itself, because it would be stored as inherited meta-data if (currentClass.equals(viewConfigNode.getSource())) { return Collections.emptyList(); } List result = new ArrayList(); for (Annotation annotation : currentClass.getAnnotations()) { Class annotationClass = annotation.annotationType(); if (annotationClass.getName().startsWith("java")) { continue; } addViewMetaData(annotation, result); } result = tryToReplaceWithMergedMetaDataFromAncestor(currentClass, viewConfigNode.getParent(), result); return result; } //only supported for meta-data which isn't aggregated protected List tryToReplaceWithMergedMetaDataFromAncestor( Class currentClass, ViewConfigNode parentViewConfigNode, List foundResult) { ViewConfigNode ancestorNode = findNodeWithClass(currentClass, parentViewConfigNode); if (ancestorNode == null) { return foundResult; } List result = new ArrayList(foundResult.size()); //only replace the meta-data found for the node and don't add all meta-data from the ancestor-node for (Annotation annotation : foundResult) { Annotation finalMetaData = getFinalMetaDataFromNode(ancestorNode, annotation); result.add(finalMetaData); } return result; } //the meta-data returned by this method is merged and potentially customized by a ConfigPreProcessor private Annotation getFinalMetaDataFromNode(ViewConfigNode viewConfigNode, Annotation annotation) { Class targetType = annotation.annotationType(); //skip @View and @Folder, because they get created dynamically to support their optional usage //the dynamic generation depends on the level and if it is a synthetic information if (View.class.equals(targetType) || Folder.class.equals(targetType)) { return annotation; } //skip aggregated meta-data, because it can't be replaced //(there is no info available about the instance which replaced the original one // which might be equivalent to the annotation passed to this method) ViewMetaData viewMetaData = annotation.annotationType().getAnnotation(ViewMetaData.class); if (viewMetaData == null) { return annotation; } Aggregated aggregated = viewMetaData.annotationType().getAnnotation(Aggregated.class); if (aggregated == null || aggregated.value()) { return annotation; } for (Annotation nodeMetaData : viewConfigNode.getMetaData()) { if (targetType.equals(nodeMetaData.annotationType())) { return nodeMetaData; } } return annotation; } private ViewConfigNode findNodeWithClass(Class nodeClass, ViewConfigNode viewConfigNode) { if (viewConfigNode == null || nodeClass == null) { return null; } if (nodeClass.equals(viewConfigNode.getSource())) { return viewConfigNode; } return findNodeWithClass(nodeClass, viewConfigNode.getParent()); } protected void addViewMetaData(Annotation currentAnnotation, List metaDataList) { Class annotationClass = currentAnnotation.annotationType(); if (annotationClass.isAnnotationPresent(ViewMetaData.class)) { metaDataList.add(currentAnnotation); } if (annotationClass.isAnnotationPresent(Stereotype.class)) { for (Annotation inheritedViaStereotype : annotationClass.getAnnotations()) { if (inheritedViaStereotype.annotationType().isAnnotationPresent(ViewMetaData.class)) { metaDataList.add(inheritedViaStereotype); } } } } protected void addInterfaces(Set processedTypes, Stack classesToAnalyze, Class nextClass) { for (Class interfaceToAdd : nextClass.getInterfaces()) { addInterfaces(processedTypes, classesToAnalyze, interfaceToAdd); if (!processedTypes.contains(interfaceToAdd)) { classesToAnalyze.push(interfaceToAdd); } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultViewConfigResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.spi.config.view.ConfigDescriptorValidator; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ConfigNodeConverter; import org.apache.deltaspike.core.spi.config.view.ViewConfigInheritanceStrategy; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.literal.FolderLiteral; import org.apache.deltaspike.jsf.api.literal.ViewLiteral; import org.apache.deltaspike.jsf.impl.util.ViewConfigUtils; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Stack; @Vetoed public class DefaultViewConfigResolver implements ViewConfigResolver { private Map, ViewConfigDescriptor> viewDefinitionToViewDefinitionEntryMapping; private Map viewPathToViewDefinitionEntryMapping; private Map folderDefinitionToViewDefinitionEntryMapping; private Map folderPathToViewDefinitionEntryMapping; private ViewConfigDescriptor defaultErrorView; public DefaultViewConfigResolver(ViewConfigNode rootViewConfigNode, ConfigNodeConverter configNodeConverter, ViewConfigInheritanceStrategy inheritanceStrategy, List configDescriptorValidators) { Map, ViewConfigDescriptor> viewConfigs = new HashMap, ViewConfigDescriptor>(); Map folderConfigs = new HashMap(); Map> foundViewIds = new HashMap>(); Stack nodesToConvert = new Stack(); nodesToConvert.addAll(rootViewConfigNode.getChildren()); while (!nodesToConvert.empty()) { ViewConfigNode currentNode = nodesToConvert.pop(); //e.g. @View is optional for users, but required from other parts of DeltaSpike -> ensure that it's in place addOptionalMetaDataToConfig(currentNode); currentNode.getInheritedMetaData().addAll(inheritanceStrategy.resolveInheritedMetaData(currentNode)); ConfigDescriptor currentConfigDescriptor = configNodeConverter.convert(currentNode); for (ConfigDescriptorValidator validator : configDescriptorValidators) { if (!validator.isValid(currentConfigDescriptor)) { throw new IllegalStateException(currentConfigDescriptor.getConfigClass().getName() + " is invalid"); } } if (currentConfigDescriptor instanceof ViewConfigDescriptor) { ViewConfigDescriptor currentViewConfigDescriptor = (ViewConfigDescriptor) currentConfigDescriptor; if (foundViewIds.containsKey(currentViewConfigDescriptor.getViewId())) { throw new IllegalStateException(currentViewConfigDescriptor.getViewId() + " is configured twice. " + "That isn't allowed - see: " + currentConfigDescriptor.getConfigClass().getName() + " and " + foundViewIds.get(currentViewConfigDescriptor.getViewId()).getName()); } else { foundViewIds.put( currentViewConfigDescriptor.getViewId(), currentViewConfigDescriptor.getConfigClass()); } if (this.defaultErrorView == null) { if (DefaultErrorView.class.isAssignableFrom(currentViewConfigDescriptor.getConfigClass())) { this.defaultErrorView = currentViewConfigDescriptor; } } else if (DefaultErrorView.class.isAssignableFrom(currentViewConfigDescriptor.getConfigClass())) { throw new IllegalStateException("It isn't allowed to configure multiple default-error-views. " + "Found default-error-views: " + this.defaultErrorView.getConfigClass() + " and " + currentViewConfigDescriptor.getConfigClass().getName()); } if (!viewConfigs.containsKey(currentViewConfigDescriptor.getConfigClass())) { viewConfigs.put(currentViewConfigDescriptor.getConfigClass(), currentViewConfigDescriptor); } } else { if (!folderConfigs.containsKey(currentConfigDescriptor.getConfigClass())) { folderConfigs.put(currentConfigDescriptor.getConfigClass(), currentConfigDescriptor); } } nodesToConvert.addAll(currentNode.getChildren()); } this.viewDefinitionToViewDefinitionEntryMapping = Collections.unmodifiableMap(viewConfigs); this.folderDefinitionToViewDefinitionEntryMapping = Collections.unmodifiableMap(folderConfigs); initCaches(); } protected void addOptionalMetaDataToConfig(ViewConfigNode currentNode) { Class sourceClass = currentNode.getSource(); if (ViewConfigUtils.isFolderConfig(sourceClass)) { for (Annotation annotation : currentNode.getMetaData()) { if (annotation.annotationType().equals(Folder.class)) { return; } } currentNode.getMetaData().add(new FolderLiteral(true)); return; } for (Annotation annotation : currentNode.getMetaData()) { if (annotation.annotationType().equals(View.class)) { return; } } currentNode.getMetaData().add(new ViewLiteral(true)); } @Override public ConfigDescriptor getConfigDescriptor(String path) { if (path == null) { return null; } ConfigDescriptor result = this.folderPathToViewDefinitionEntryMapping.get(path); if (result == null) { result = getViewConfigDescriptor(path); //TODO re-visit it } return result; } @Override public ViewConfigDescriptor getViewConfigDescriptor(String viewId) { if (viewId == null) { return null; } return this.viewPathToViewDefinitionEntryMapping.get(viewId); } @Override public ConfigDescriptor getConfigDescriptor(Class configClass) { ConfigDescriptor result = null; if (ViewConfig.class.isAssignableFrom(configClass)) { result = getViewConfigDescriptor(configClass); } if (result == null) { result = this.folderDefinitionToViewDefinitionEntryMapping.get(configClass); } return result; } @Override public List> getConfigDescriptors() { ConfigDescriptor[] folderResult = this.folderDefinitionToViewDefinitionEntryMapping.values() .toArray(new ConfigDescriptor[this.folderDefinitionToViewDefinitionEntryMapping.size()]); ConfigDescriptor[] viewResult = this.viewDefinitionToViewDefinitionEntryMapping.values() .toArray(new ConfigDescriptor[this.viewDefinitionToViewDefinitionEntryMapping.size()]); List> result = new ArrayList>(); result.addAll(Arrays.asList(folderResult)); result.addAll(Arrays.asList(viewResult)); return result; } @Override public ViewConfigDescriptor getViewConfigDescriptor(Class viewDefinitionClass) { if (DefaultErrorView.class.equals(viewDefinitionClass)) { return getDefaultErrorViewConfigDescriptor(); } return this.viewDefinitionToViewDefinitionEntryMapping.get(viewDefinitionClass); } @Override public List getViewConfigDescriptors() { ViewConfigDescriptor[] result = this.viewDefinitionToViewDefinitionEntryMapping.values() .toArray(new ViewConfigDescriptor[this.viewDefinitionToViewDefinitionEntryMapping.size()]); return new ArrayList(Arrays.asList(result)); } @Override public ViewConfigDescriptor getDefaultErrorViewConfigDescriptor() { return this.defaultErrorView; } protected void initCaches() { //folders Map folderPathMapping = new HashMap(); for (ConfigDescriptor folderConfigDescriptor : this.folderDefinitionToViewDefinitionEntryMapping.values()) { if (folderPathMapping.containsKey(folderConfigDescriptor.toString())) { throw new IllegalStateException("Duplicated config for the same folder configured. See: " + folderPathMapping.get( folderConfigDescriptor.toString()).getConfigClass().getName() + " and " + folderConfigDescriptor.getConfigClass().getName()); } folderPathMapping.put(folderConfigDescriptor.getPath(), folderConfigDescriptor); } this.folderPathToViewDefinitionEntryMapping = Collections.unmodifiableMap(folderPathMapping); //pages Map viewPathMapping = new HashMap(); for (ViewConfigDescriptor pageConfigDescriptor : this.viewDefinitionToViewDefinitionEntryMapping.values()) { if (viewPathMapping.containsKey(pageConfigDescriptor.getViewId())) { throw new IllegalStateException("Duplicated config for the same page configured. See: " + viewPathMapping.get( pageConfigDescriptor.getViewId()).getConfigClass().getName() + " and " + pageConfigDescriptor.getConfigClass().getName()); } viewPathMapping.put(pageConfigDescriptor.getPath(), pageConfigDescriptor); } this.viewPathToViewDefinitionEntryMapping = Collections.unmodifiableMap(viewPathMapping); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/DefaultViewPathConfigDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import java.lang.annotation.Annotation; import java.util.List; import java.util.Map; class DefaultViewPathConfigDescriptor extends AbstractPathConfigDescriptor implements ViewConfigDescriptor { private final String viewId; DefaultViewPathConfigDescriptor(String viewId, Class configClass, List mergedMetaData, Map, List> callbackDescriptors) { super(configClass, mergedMetaData, callbackDescriptors); this.viewId = viewId; } @Override public String getPath() { return this.viewId; } @Override public String getViewId() { return this.viewId; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/FolderConfigNode.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.util.List; import java.util.Map; import java.util.Set; public class FolderConfigNode extends AbstractConfigNode { //not all interfaces have to implement the ViewConfig interface private final Class nodeId; public FolderConfigNode(Class nodeId, ViewConfigNode parent, Set nodeMetaData) { super(parent, nodeMetaData); this.nodeId = nodeId; } public FolderConfigNode(ViewConfigNode nodeToCopy, Class viewConfigClass) { super(nodeToCopy.getParent(), nodeToCopy.getMetaData()); getInheritedMetaData().addAll(nodeToCopy.getInheritedMetaData()); getChildren().addAll(nodeToCopy.getChildren()); for (Map.Entry, List> callbackDescriptorEntry : nodeToCopy.getCallbackDescriptors().entrySet()) { for (CallbackDescriptor callbackDescriptor : callbackDescriptorEntry.getValue()) { registerCallbackDescriptors(callbackDescriptorEntry.getKey(), callbackDescriptor); } } this.nodeId = viewConfigClass; } @Override public Class getSource() { return this.nodeId; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/PageViewConfigNode.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.util.Set; public class PageViewConfigNode extends AbstractConfigNode { private final Class nodeId; public PageViewConfigNode(Class nodeId, ViewConfigNode parent, Set nodeMetaData) { super(parent, nodeMetaData); this.nodeId = nodeId; } @Override public Class getSource() { return this.nodeId; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewConfigExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.ViewRef; import org.apache.deltaspike.core.spi.config.view.ConfigDescriptorValidator; import org.apache.deltaspike.core.api.config.view.metadata.InlineViewMetaData; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.config.view.ConfigNodeConverter; import org.apache.deltaspike.core.spi.config.view.InlineMetaDataTransformer; import org.apache.deltaspike.core.spi.config.view.TargetViewConfigProvider; import org.apache.deltaspike.core.spi.config.view.ViewConfigInheritanceStrategy; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.spi.config.view.ViewConfigRoot; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.impl.util.ViewConfigUtils; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterDeploymentValidation; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.BeforeShutdown; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; public class ViewConfigExtension implements Extension, Deactivatable { private boolean isActivated = true; private ViewConfigNode rootViewConfigNode; private ViewConfigResolver viewConfigResolver; private boolean transformed = false; { resetRootNode(); } @SuppressWarnings("UnusedDeclaration") protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { this.isActivated = ClassDeactivationUtils.isActivated(getClass()); } @SuppressWarnings("UnusedDeclaration") protected void buildViewConfigMetaDataTree(@Observes final ProcessAnnotatedType pat) { if (!isActivated) { return; } buildViewConfigMetaDataTreeFor( pat.getAnnotatedType().getJavaClass(), pat.getAnnotatedType().getAnnotations(), new VetoCallback() { @Override public void veto() { pat.veto(); } }); } protected void buildViewConfigMetaDataTreeFor(Class beanClass, Set annotations, VetoCallback vetoCallback) { if (ViewConfig.class.isAssignableFrom(beanClass)) { addConfigClass(beanClass, annotations); vetoCallback.veto(); } else { if (ViewConfigUtils.isFolderConfig(beanClass) && beanClass.isAnnotationPresent(Folder.class)) { addConfigClass(beanClass, annotations); vetoCallback.veto(); } else { addIndirectlyInheritedMetaData(beanClass, annotations); } } } public void addIndirectlyInheritedMetaData(Class configClass) { addIndirectlyInheritedMetaData( configClass, new HashSet(Arrays.asList(configClass.getAnnotations()))); } protected void addIndirectlyInheritedMetaData(Class configClass, Set annotations) { for (Annotation annotation : annotations) { InlineViewMetaData inlineViewMetaData = annotation.annotationType().getAnnotation(InlineViewMetaData.class); if (inlineViewMetaData != null) { Class targetViewConfigProviderClass = inlineViewMetaData.targetViewConfigProvider(); TargetViewConfigProvider targetViewConfigProvider = ClassUtils.tryToInstantiateClass(targetViewConfigProviderClass); for (Class viewConfigRef : targetViewConfigProvider.getTarget(annotation)) { ViewConfigNode viewConfigNode = findNode(viewConfigRef); if (viewConfigNode == null) { addPageDefinition(viewConfigRef); viewConfigNode = findNode(viewConfigRef); if (viewConfigNode == null) { throw new IllegalStateException("No node created for: " + viewConfigRef); } } Class inlineNodeTransformerClass = inlineViewMetaData.inlineMetaDataTransformer(); if (!InlineMetaDataTransformer.class.equals(inlineNodeTransformerClass)) { InlineMetaDataTransformer inlineMetaDataTransformer = ClassUtils.tryToInstantiateClass(inlineNodeTransformerClass); viewConfigNode.getInheritedMetaData().add( inlineMetaDataTransformer.convertToViewMetaData(annotation, configClass)); } else //no custom transformer registered -> add the annotation itself { viewConfigNode.getInheritedMetaData().add(annotation); } } break; } } } public void addPageDefinition(Class viewConfigClass) { addConfigClass(viewConfigClass, new HashSet(Arrays.asList(viewConfigClass.getAnnotations()))); } public void addFolderDefinition(Class configClass) { if (ViewConfigUtils.isFolderConfig(configClass)) { addConfigClass(configClass, new HashSet(Arrays.asList(configClass.getAnnotations()))); } else { throw new IllegalArgumentException(configClass != null ? configClass.getName() : "null" + " is an invalid config for folders"); } } protected void addConfigClass(Class viewConfigClass, Set viewConfigAnnotations) { if (isInternal(viewConfigClass)) { return; } String className = viewConfigClass.getName(); if (!className.contains(".")) { if (className.contains("$")) { className = className.substring(0, className.indexOf("$")); } throw new IllegalStateException("Please move the class '" + className + "' to a package!"); } for (Annotation annotation : viewConfigAnnotations) { if (annotation.annotationType().equals(ViewConfigRoot.class)) { if (this.rootViewConfigNode.getSource() != null) { throw new IllegalStateException("@" + ViewConfigRoot.class.getName() + " has been found at " + viewConfigClass.getName() + " and " + this.rootViewConfigNode.getSource().getName()); } this.rootViewConfigNode.getMetaData().add(annotation); this.rootViewConfigNode = new FolderConfigNode(this.rootViewConfigNode, viewConfigClass); //needed for cdi 1.1+ with bean-discovery-mode 'annotated' if (viewConfigClass.getAnnotation(ApplicationScoped.class) != null) { Set manuallyDiscoveredViewConfigs = new HashSet(); findNestedClasses(viewConfigClass, manuallyDiscoveredViewConfigs); for (Class foundClass : manuallyDiscoveredViewConfigs) { buildViewConfigMetaDataTreeFor( foundClass, new HashSet(Arrays.asList(foundClass.getAnnotations())), new VetoCallback() { @Override public void veto() { } }); } } break; } } List treePath = ViewConfigUtils.toNodeList(viewConfigClass); ViewConfigNode previousRootNode = null; for (Class currentNode : treePath) { //can only return a node if a folder was added already ViewConfigNode baseNode = findNode(currentNode); if (baseNode == null) { Set metaData = viewConfigAnnotations; if (!currentNode.equals(viewConfigClass)) //small tweak { metaData = new HashSet(Arrays.asList(currentNode.getAnnotations())); } previousRootNode = addNode(previousRootNode, currentNode, metaData); } else { previousRootNode = baseNode; } } } private void findNestedClasses(Class viewConfigClass, Set nestedClasses) { for (Class nestedClass : viewConfigClass.getDeclaredClasses()) { nestedClasses.add(nestedClass); findNestedClasses(nestedClass, nestedClasses); } } private boolean isInternal(Class configClass) { return ViewConfig.class.equals(configClass) || DefaultErrorView.class.equals(configClass) || ViewRef.Manual.class.equals(configClass); } private ViewConfigNode addNode(ViewConfigNode parentNode, Class idOfNewNode, Set viewConfigAnnotations) { if (parentNode == null) { parentNode = this.rootViewConfigNode; } ViewConfigNode viewConfigNode; if (ViewConfigUtils.isFolderConfig(idOfNewNode)) { viewConfigNode = new FolderConfigNode(idOfNewNode, parentNode, viewConfigAnnotations); } else { viewConfigNode = new PageViewConfigNode( (Class) idOfNewNode, parentNode, viewConfigAnnotations); } parentNode.getChildren().add(viewConfigNode); return viewConfigNode; } public ViewConfigNode findNode(Class nodeClass) { if (nodeClass == null) { return null; } List path = ViewConfigUtils.toNodeList(nodeClass); ViewConfigNode currentNode = this.rootViewConfigNode; next: for (int i = 0; i < path.size(); i++) { Class nodeId = path.get(i); for (ViewConfigNode node : currentNode.getChildren()) { if (node.getSource().equals(nodeId)) { currentNode = node; if (i == (path.size() - 1)) { return currentNode; } continue next; } } return null; } return null; } @SuppressWarnings("UnusedDeclaration") public void buildViewConfig(@Observes AfterDeploymentValidation adv) { if (!isActivated) { return; } //needed to transform the metadata-tree during the bootstrapping process transformMetaDataTree(); this.transformed = true; } protected void transformMetaDataTree() { if (!this.isActivated) { return; } if (this.viewConfigResolver == null) { ConfigNodeConverter configNodeConverter = new DefaultConfigNodeConverter(); ViewConfigInheritanceStrategy inheritanceStrategy = new DefaultViewConfigInheritanceStrategy(); List configDescriptorValidators = new ArrayList(); for (Annotation annotation : this.rootViewConfigNode.getMetaData()) { if (annotation.annotationType().equals(ViewConfigRoot.class)) { ViewConfigRoot viewConfigRoot = (ViewConfigRoot) annotation; configNodeConverter = createCustomConfigNodeConverter(viewConfigRoot, configNodeConverter); inheritanceStrategy = createCustomInheritanceStrategy(viewConfigRoot, inheritanceStrategy); configDescriptorValidators = createCustomConfigDescriptorValidators(viewConfigRoot); this.viewConfigResolver = createCustomViewConfigResolver( viewConfigRoot, configNodeConverter, inheritanceStrategy, configDescriptorValidators); break; } } if (this.viewConfigResolver == null) { this.viewConfigResolver = new DefaultViewConfigResolver( this.rootViewConfigNode, configNodeConverter, inheritanceStrategy, configDescriptorValidators); } resetRootNode(); } } private ViewConfigResolver createCustomViewConfigResolver(ViewConfigRoot viewConfigRoot, ConfigNodeConverter configNodeConverter, ViewConfigInheritanceStrategy inheritanceStrategy, List validators) { Class viewConfigResolverClass = viewConfigRoot.viewConfigResolver(); if (!ViewConfigResolver.class.equals(viewConfigResolverClass)) { try { Constructor viewConfigResolverConstructor = viewConfigResolverClass .getConstructor(new Class[]{ ViewConfigNode.class, ConfigNodeConverter.class, ViewConfigInheritanceStrategy.class, List.class}); return viewConfigResolverConstructor .newInstance(this.rootViewConfigNode, configNodeConverter, inheritanceStrategy, validators); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } return null; } private ConfigNodeConverter createCustomConfigNodeConverter(ViewConfigRoot viewConfigRoot, ConfigNodeConverter defaultConverter) { Class converterClass = viewConfigRoot.configNodeConverter(); if (!ConfigNodeConverter.class.equals(converterClass)) { try { return converterClass.newInstance(); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } return defaultConverter; } private ViewConfigInheritanceStrategy createCustomInheritanceStrategy(ViewConfigRoot viewConfigRoot, ViewConfigInheritanceStrategy defaultStrategy) { Class strategyClass = viewConfigRoot.viewConfigInheritanceStrategy(); if (!ViewConfigInheritanceStrategy.class.equals(strategyClass)) { try { return strategyClass.newInstance(); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } return defaultStrategy; } private List createCustomConfigDescriptorValidators(ViewConfigRoot viewConfigRoot) { List result = new ArrayList(); for (Class validatorClass : viewConfigRoot.configDescriptorValidators()) { try { ConfigDescriptorValidator validator = validatorClass.newInstance(); result.add(validator); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } return result; } public void freeViewConfigCache(@Observes BeforeShutdown bs) { this.viewConfigResolver = null; this.transformed = false; } private void resetRootNode() { this.rootViewConfigNode = new FolderConfigNode(null, null, new HashSet()); } boolean isActivated() { return isActivated; } boolean isTransformed() { return transformed; } ViewConfigResolver getViewConfigResolver() { return viewConfigResolver; } interface VetoCallback { void veto(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewConfigPathValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.servlet.ServletContextEvent; import jakarta.servlet.ServletContextListener; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; public class ViewConfigPathValidator implements ServletContextListener, Deactivatable { private static final Logger LOGGER = Logger.getLogger(ViewConfigPathValidator.class.getName()); @Override public void contextInitialized(ServletContextEvent sce) { if (ClassDeactivationUtils.isActivated(getClass())) { ViewConfigResolver viewConfigResolver; try { viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); } catch (Exception e) { LOGGER.log(Level.WARNING, "Container issue detected -> can't validate view-configs. " + "This exception is usually the effect (but not the reason) of a failed startup. " + "You can deactivate " + getClass().getName() + " via a custom " + ClassDeactivator.class.getName() + " to verify it.", e); return; } List supportedExtensions = new ArrayList(); supportedExtensions.add(View.Extension.XHTML); supportedExtensions.add(View.Extension.JSP); validateViewConfigPaths(sce, viewConfigResolver, supportedExtensions); } } //allows to test and re-use it in a custom listener // (if a custom listener is needed for supporting custom extensions or // this listener is deactivated e.g. to change the order) protected void validateViewConfigPaths(ServletContextEvent sce, ViewConfigResolver viewConfigResolver, List supportedExtensions) { for (ConfigDescriptor configDescriptor : viewConfigResolver.getConfigDescriptors()) { try { if (configDescriptor instanceof ViewConfigDescriptor) { //currently other extensions aren't supported String viewId = ((ViewConfigDescriptor) configDescriptor).getViewId(); String extension = viewId.substring(viewId.lastIndexOf('.') + 1); if (!supportedExtensions.contains(extension)) { continue; } } if (!isValidPath(sce, configDescriptor)) { if (configDescriptor instanceof DefaultFolderConfigDescriptor && !configDescriptor.getConfigClass().isAnnotationPresent(Folder.class)) { LOGGER.fine(configDescriptor.getConfigClass().getName() + " looks like a marker interface" + " only used for providing meta-data, because the path " + configDescriptor.getPath() + " doesn't exist and the config-class isn't annotated with " + Folder.class.getName()); continue; } throw new IllegalStateException("path '" + configDescriptor.getPath() + "' is missing, but mapped by: " + configDescriptor.getConfigClass().getName()); } } catch (Exception e) { printException(e); throw ExceptionUtils.throwAsRuntimeException(e); } } } protected boolean isValidPath(ServletContextEvent sce, ConfigDescriptor configDescriptor) { try { return sce.getServletContext().getResource(configDescriptor.getPath()) != null; } catch (MalformedURLException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } protected void printException(Exception e) { //for easier analysis (in combination with several servers) LOGGER.log(Level.SEVERE, "invalid view-config found", e); } @Override public void contextDestroyed(ServletContextEvent sce) { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewConfigResolverProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.spi.config.view.ConfigDescriptorValidator; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashSet; import java.util.logging.Logger; @ApplicationScoped public class ViewConfigResolverProducer { private static final Logger LOG = Logger.getLogger(ViewConfigResolverProducer.class.getName()); @Inject private ViewConfigExtension viewConfigExtension; public ViewConfigResolverProducer() { } public ViewConfigResolverProducer(ViewConfigExtension viewConfigExtension) { this.viewConfigExtension = viewConfigExtension; } @Produces @ApplicationScoped public ViewConfigResolver createViewConfigResolver() { if (!viewConfigExtension.isActivated()) { return createEmptyDefaultViewConfigResolver(); } if (!viewConfigExtension.isTransformed()) //esp. for easier unit-tests { viewConfigExtension.transformMetaDataTree(); } ViewConfigResolver viewConfigResolver = viewConfigExtension.getViewConfigResolver(); if (viewConfigResolver == null) { LOG.warning("It wasn't possible to create a ViewConfigResolver"); viewConfigResolver = createEmptyDefaultViewConfigResolver(); } return viewConfigResolver; } private DefaultViewConfigResolver createEmptyDefaultViewConfigResolver() { return new DefaultViewConfigResolver( new FolderConfigNode( null, null, new HashSet()), null, null, new ArrayList()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/ViewControllerActionListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view; import org.apache.deltaspike.core.api.config.view.controller.PreViewAction; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jsf.impl.util.ViewControllerUtils; import jakarta.faces.context.FacesContext; import jakarta.faces.event.ActionEvent; import jakarta.faces.event.ActionListener; /** * ActionListener which invokes {@link PreViewAction} callbacks of page-beans */ public class ViewControllerActionListener implements ActionListener, Deactivatable { private final ActionListener wrapped; private final boolean activated; /** * Constructor for wrapping the given {@link ActionListener} * @param wrapped action-listener which should be wrapped */ public ViewControllerActionListener(ActionListener wrapped) { this.wrapped = wrapped; this.activated = ClassDeactivationUtils.isActivated(getClass()); } @Override public void processAction(ActionEvent actionEvent) { if (this.activated) { ViewConfigDescriptor viewConfigDescriptor = BeanProvider.getContextualReference(ViewConfigResolver.class) .getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId()); ViewControllerUtils.executeViewControllerCallback(viewConfigDescriptor, PreViewAction.class); } this.wrapped.processAction(actionEvent); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/DefaultNavigationParameterContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import jakarta.enterprise.context.RequestScoped; import java.util.Collections; import java.util.HashMap; import java.util.Map; /** * Request scoped storage for page-parameters. * Can be used to add parameters dynamically to the final navigation string */ @RequestScoped public class DefaultNavigationParameterContext implements NavigationParameterContext { private static final long serialVersionUID = 6027959542775130265L; private Map parameters = new HashMap(); protected DefaultNavigationParameterContext() { } public Map getPageParameters() { return Collections.unmodifiableMap(this.parameters); } public void addPageParameter(String key, Object param) { if (param == null) { this.parameters.remove(key); return; } String value = param.toString().trim(); if (value.startsWith("#{") && value.endsWith("}")) { value = JsfUtils.getValueOfExpressionAsString(value); } //simple version - we could add multi-ref support, if we really need it //but this method might be called multiple times for the same parameter/s this.parameters.put(key, value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/DefaultNavigationParameterStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import org.apache.deltaspike.jsf.spi.config.view.navigation.NavigationParameterStrategy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.util.ArrayList; import java.util.Collections; import java.util.List; @Dependent public class DefaultNavigationParameterStrategy implements NavigationParameterStrategy { private static final long serialVersionUID = 198321901578229292L; @Inject private NavigationParameterContext navigationParameterContext; @Override public Object execute(InvocationContext ic) throws Exception { List parameterList = new ArrayList(); NavigationParameter navigationParameter = ic.getMethod().getAnnotation(NavigationParameter.class); if (navigationParameter != null) { parameterList.add(navigationParameter); } NavigationParameter.List navigationParameterList = ic.getMethod().getAnnotation(NavigationParameter.List.class); if (navigationParameterList != null) { Collections.addAll(parameterList, navigationParameterList.value()); } for (NavigationParameter currentParameter : parameterList) { JsfUtils.addStaticNavigationParameter( this.navigationParameterContext, currentParameter.key(), currentParameter.value()); } return ic.proceed(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/DefaultViewNavigationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import jakarta.enterprise.context.ApplicationScoped; import jakarta.faces.context.FacesContext; /** * Navigation handler for view-configs */ @ApplicationScoped public class DefaultViewNavigationHandler implements ViewNavigationHandler { protected DefaultViewNavigationHandler() { } @Override public void navigateTo(Class targetView) { FacesContext facesContext = FacesContext.getCurrentInstance(); facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, targetView.getName()); facesContext.renderResponse(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/NavigationCaseMapWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import org.apache.deltaspike.jsf.impl.util.RequestParameter; import jakarta.faces.application.ConfigurableNavigationHandler; import jakarta.faces.application.NavigationCase; import jakarta.faces.application.NavigationHandler; import java.util.List; import java.util.Set; import java.util.Map; import java.util.HashSet; import java.util.HashMap; import java.util.Collection; import java.util.logging.Logger; /** * Destructive operations aren't supported (compared to the SubKeyMap used in MyFaces). * Reason: It isn't allowed to remove navigation cases * (which are based on {@link org.apache.deltaspike.core.api.config.view.ViewConfig}) */ public class NavigationCaseMapWrapper implements Map> { private static final Logger LOG = Logger.getLogger(NavigationCaseMapWrapper.class.getName()); private Map> wrappedNavigationCaseMap; private final NavigationHandler wrapped; private final Map> viewConfigBasedNavigationCaseCache; /** * Constructor for wrapping the given navigation-cases * * @param navigationCases current navigation-cases * @param wrapped wrapped navigation-handler */ public NavigationCaseMapWrapper(Map> navigationCases, NavigationHandler wrapped) { this.wrappedNavigationCaseMap = navigationCases; this.wrapped = wrapped; this.viewConfigBasedNavigationCaseCache = createViewConfigBasedNavigationCases(false); } private Map> createViewConfigBasedNavigationCases(boolean allowParameters) { Map> result; if (this.wrapped instanceof ConfigurableNavigationHandler) { result = new DelegatingMap((ConfigurableNavigationHandler)this.wrapped); } else { LOG.warning("the wrapped navigation-handler doesn't extend " + ConfigurableNavigationHandler.class.getName() + ". therefore std. navigation-rules might not work correctly with mojarra"); result = new HashMap>(); } Collection viewConfigDescriptors = BeanProvider.getContextualReference(ViewConfigResolver.class).getViewConfigDescriptors(); if (!viewConfigDescriptors.isEmpty()) { Set navigationCase = new HashSet(); Map> parameters = null; if (allowParameters) { parameters = resolveParameters(); } boolean includeParameters; for (ViewConfigDescriptor entry : viewConfigDescriptors) { View viewMetaData = entry.getMetaData(View.class).iterator().next(); includeParameters = View.ViewParameterMode.INCLUDE .equals(viewMetaData.viewParams()); navigationCase.add(new NavigationCase("*", null, null, null, entry.getViewId(), includeParameters ? parameters : null, View.NavigationMode.REDIRECT.equals(viewMetaData.navigation()), includeParameters)); result.put(entry.getViewId(), navigationCase); } } return result; } private Map> resolveParameters() { Map> parameters = new HashMap>(); for (RequestParameter parameter : JsfUtils.getViewConfigPageParameters()) { parameters.put(parameter.getKey(), parameter.getValueList()); } return parameters; } /** * @return the final size (might be a combination of the configured navigation cases (via XML) and the * {@link org.apache.deltaspike.core.api.config.view.ViewConfig}s */ @Override public int size() { return this.wrappedNavigationCaseMap.size() + this.viewConfigBasedNavigationCaseCache.size(); } @Override public boolean isEmpty() { return this.wrappedNavigationCaseMap.isEmpty() && this.viewConfigBasedNavigationCaseCache.isEmpty(); } @Override public boolean containsKey(Object key) { return this.wrappedNavigationCaseMap.containsKey(key) || this.viewConfigBasedNavigationCaseCache.containsKey(key); } @Override public boolean containsValue(Object value) { return this.wrappedNavigationCaseMap.containsValue(value) || this.viewConfigBasedNavigationCaseCache.containsValue(value); } /** * XML configuration overrules {@link org.apache.deltaspike.core.api.config.view.ViewConfig}s */ @Override public Set get(Object key) { Set result = this.wrappedNavigationCaseMap.get(key); if (result == null) { return createViewConfigBasedNavigationCases(true).get(key); } return result; } @Override public Set put(String key, Set value) { return this.wrappedNavigationCaseMap.put(key, value); } @Override public Set remove(Object key) { return this.wrappedNavigationCaseMap.remove(key); } @Override public void putAll(Map> m) { this.wrappedNavigationCaseMap.putAll(m); } @Override public void clear() { this.wrappedNavigationCaseMap.clear(); } /** * @return a combination of navigation-cases configured via XML and * {@link org.apache.deltaspike.core.api.config.view.ViewConfig}s */ @Override public Set keySet() { Set result = new HashSet(); result.addAll(this.wrappedNavigationCaseMap.keySet()); result.addAll(this.viewConfigBasedNavigationCaseCache.keySet()); return result; } /** * @return a combination of navigation-cases configured via XML and * {@link org.apache.deltaspike.core.api.config.view.ViewConfig}s */ @Override public Collection> values() { Collection> result = new HashSet>(); result.addAll(this.wrappedNavigationCaseMap.values()); result.addAll(createViewConfigBasedNavigationCases(true).values()); return result; } /** * @return a combination of navigation-cases configured via XML and * {@link org.apache.deltaspike.core.api.config.view.ViewConfig}s */ @Override public Set>> entrySet() { Set>> result = new HashSet>>(); result.addAll(this.wrappedNavigationCaseMap.entrySet()); result.addAll(createViewConfigBasedNavigationCases(true).entrySet()); return result; } //currently not a complete handling, but enough to fix the issues with mojarra private class DelegatingMap extends HashMap> { private static final long serialVersionUID = -955468874397821639L; private final ConfigurableNavigationHandler wrapped; private DelegatingMap(ConfigurableNavigationHandler wrapped) { this.wrapped = wrapped; } @Override public Set put(String key, Set value) { if (value == null) { return null; } Set result = new HashSet(); //filter entries created by createViewConfigBasedNavigationCases for (NavigationCase navigationCase : value) { if (!(navigationCase.getFromOutcome() == null && navigationCase.getFromAction() == null)) { result.add(navigationCase); } } //delegate to the wrapped instance -> the innermost handler needs to receive it //(because mojarra uses ConfigurableNavigationHandler#getNavigationCases // to add cases for std. nav.rules from the outside) return this.wrapped.getNavigationCases().put(key, result); } @Override public Set get(Object key) { Set navigationCases = super.get(key); if (navigationCases == null) { navigationCases = new HashSet(); put((String)key, navigationCases); } return new DelegatingSet(navigationCases, this.wrapped, (String)key); } } //currently not a complete handling, but enough to fix the issues with mojarra private class DelegatingSet extends HashSet { private static final long serialVersionUID = -7040572530963900394L; private final ConfigurableNavigationHandler wrapped; private String navigationCaseKey; private DelegatingSet(Collection c, ConfigurableNavigationHandler wrapped, String navigationCaseKey) { super(c); this.wrapped = wrapped; this.navigationCaseKey = navigationCaseKey; } @Override public boolean add(NavigationCase navigationCase) { Set navigationCases = this.wrapped.getNavigationCases().get(this.navigationCaseKey); if (navigationCases == null) { navigationCases = new HashSet(); this.wrapped.getNavigationCases().put(this.navigationCaseKey, navigationCases); } return navigationCases.add(navigationCase); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/NavigationParameterInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.jsf.spi.config.view.navigation.NavigationParameterStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @NavigationParameter(key = "", value = "") @Interceptor @Priority(1000) public class NavigationParameterInterceptor implements Serializable { private static final long serialVersionUID = 1762625956958428994L; @Inject private NavigationParameterStrategy navigationParameterStrategy; @AroundInvoke public Object addParameter(InvocationContext invocationContext) throws Exception { return this.navigationParameterStrategy.execute(invocationContext); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/NavigationParameterListInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import jakarta.annotation.Priority; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.jsf.spi.config.view.navigation.NavigationParameterStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @NavigationParameter.List( { } ) @Interceptor @Priority(1000) public class NavigationParameterListInterceptor implements Serializable { private static final long serialVersionUID = 2762625956958428994L; @Inject private NavigationParameterStrategy navigationParameterStrategy; @AroundInvoke public Object addParameterList(InvocationContext invocationContext) throws Exception { return this.navigationParameterStrategy.execute(invocationContext); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/config/view/navigation/ViewConfigAwareNavigationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.config.view.navigation; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.ViewRef; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.core.api.config.view.navigation.event.PreViewConfigNavigateEvent; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.faces.application.NavigationHandler; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; public class ViewConfigAwareNavigationHandler extends NavigationHandler { private Set otherOutcomes = new CopyOnWriteArraySet(); private Map viewConfigs = new ConcurrentHashMap(); private final NavigationHandler navigationHandler; private volatile BeanManager beanManager; private NavigationParameterContext navigationParameterContext; private ViewConfigResolver viewConfigResolver; /** * Constructor which allows to use the given {@link NavigationHandler} * * @param navigationHandler navigation-handler of jsf */ public ViewConfigAwareNavigationHandler(NavigationHandler navigationHandler) { this.navigationHandler = navigationHandler; } //Security checks will be performed by the view-handler provided by ds @Override public void handleNavigation(FacesContext facesContext, String fromAction, String outcome) { lazyInit(); if (outcome != null && outcome.contains(".")) { String originalOutcome = outcome; if (!this.otherOutcomes.contains(outcome)) { //it isn't possible to support interfaces due to cdi restrictions if (outcome.startsWith("class ")) { outcome = outcome.substring(6); } ViewConfigDescriptor entry = this.viewConfigs.get(outcome); if (entry == null) { if (DefaultErrorView.class.getName().equals(originalOutcome)) { entry = this.viewConfigResolver.getDefaultErrorViewConfigDescriptor(); } } boolean allowCaching = true; if (entry == null) { Class loadedClass = ClassUtils.tryToLoadClassForName(outcome); if (loadedClass == null) { this.otherOutcomes.add(originalOutcome); } else if (ViewConfig.class.isAssignableFrom(loadedClass)) { //a sub-classed page-config for annotating it with different view params if (loadedClass.getAnnotation(View.class) == null && loadedClass.getSuperclass().getAnnotation(View.class) != null) { allowCaching = false; addConfiguredViewParameters(loadedClass); loadedClass = loadedClass.getSuperclass(); } entry = this.viewConfigResolver .getViewConfigDescriptor((Class) loadedClass); } } if (entry != null) { //in case of false it has been added already if (allowCaching) { this.viewConfigs.put(outcome, entry); addConfiguredViewParameters(entry.getConfigClass()); } String oldViewId = null; if (facesContext.getViewRoot() != null) { oldViewId = facesContext.getViewRoot().getViewId(); } PreViewConfigNavigateEvent navigateEvent = firePreViewConfigNavigateEvent(oldViewId, entry); entry = tryToUpdateEntry(entry, navigateEvent); if (entry != null) { outcome = convertEntryToOutcome(facesContext.getExternalContext(), entry); } } } } this.navigationHandler.handleNavigation(facesContext, fromAction, outcome); } private void addConfiguredViewParameters(Class viewConfigClass) { if (this.navigationParameterContext != null) { NavigationParameter navigationParameter = viewConfigClass.getAnnotation(NavigationParameter.class); if (navigationParameter != null) { addConfiguredPageParameter(navigationParameter); } else { NavigationParameter.List pageParameterList = viewConfigClass.getAnnotation(NavigationParameter.List.class); if (pageParameterList != null) { for (NavigationParameter currentNavigationParameter : pageParameterList.value()) { addConfiguredPageParameter(currentNavigationParameter); } } } } } private void addConfiguredPageParameter(NavigationParameter viewParameter) { JsfUtils.addStaticNavigationParameter( this.navigationParameterContext, viewParameter.key(), viewParameter.value()); } private String convertEntryToOutcome(ExternalContext externalContext, ViewConfigDescriptor entry) { View viewMetaData = entry.getMetaData(View.class).iterator().next(); boolean performRedirect = View.NavigationMode.REDIRECT.equals(viewMetaData.navigation()); boolean includeViewParameters = View.ViewParameterMode.INCLUDE.equals(viewMetaData.viewParams()); StringBuilder result = new StringBuilder(entry.getViewId()); if (performRedirect) { result.append("?faces-redirect=true"); } if (includeViewParameters) { if (performRedirect) { result.append("&"); } else { result.append("?"); } result.append("includeViewParams=true"); return JsfUtils.addPageParameters(externalContext, result.toString(), false); } return result.toString(); } private ViewConfigDescriptor tryToUpdateEntry(ViewConfigDescriptor viewConfigDescriptor, PreViewConfigNavigateEvent navigateEvent) { if (navigateEvent.getToView() == null) { return null; } if (navigateEvent.getToView().equals(viewConfigDescriptor.getConfigClass())) { return viewConfigDescriptor; } return this.viewConfigResolver.getViewConfigDescriptor(navigateEvent.getToView()); } private PreViewConfigNavigateEvent firePreViewConfigNavigateEvent(String oldViewId, ViewConfigDescriptor newViewConfigDescriptor) { ViewConfigDescriptor oldViewConfigDescriptor = this.viewConfigResolver.getViewConfigDescriptor(oldViewId); PreViewConfigNavigateEvent navigateEvent; if (oldViewConfigDescriptor != null) { navigateEvent = new PreViewConfigNavigateEvent( oldViewConfigDescriptor.getConfigClass(), newViewConfigDescriptor.getConfigClass()); } else { navigateEvent = new PreViewConfigNavigateEvent( ViewRef.Manual.class, newViewConfigDescriptor.getConfigClass()); } this.beanManager.getEvent().fire(navigateEvent); return navigateEvent; } private void lazyInit() { if (this.beanManager == null) { init(); } } private synchronized void init() { if (this.beanManager == null) { this.navigationParameterContext = BeanProvider.getContextualReference(NavigationParameterContext.class); this.viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); this.beanManager = BeanManagerProvider.getInstance().getBeanManager(); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/exception/control/BridgeExceptionHandlerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.exception.control; import java.util.Iterator; import jakarta.faces.FacesException; import jakarta.faces.context.ExceptionHandler; import jakarta.faces.context.ExceptionHandlerWrapper; import jakarta.faces.context.FacesContext; import jakarta.faces.event.AbortProcessingException; import jakarta.faces.event.ExceptionQueuedEvent; import jakarta.faces.event.PhaseId; import jakarta.faces.event.SystemEvent; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import org.apache.deltaspike.jsf.impl.util.SecurityUtils; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.api.authorization.ErrorViewAwareAccessDeniedException; public class BridgeExceptionHandlerWrapper extends ExceptionHandlerWrapper implements Deactivatable { private final ExceptionHandler wrapped; public BridgeExceptionHandlerWrapper(ExceptionHandler wrapped) { this.wrapped = wrapped; } @Override public ExceptionHandler getWrapped() { return wrapped; } @Override public void handle() throws FacesException { FacesContext context = FacesContext.getCurrentInstance(); if (context == null || context.getResponseComplete()) { return; } Iterable exceptionQueuedEvents = getUnhandledExceptionQueuedEvents(); if (exceptionQueuedEvents != null && exceptionQueuedEvents.iterator() != null) { Iterator iterator = exceptionQueuedEvents.iterator(); while (iterator.hasNext()) { Throwable throwable = iterator.next().getContext().getException(); Throwable rootCause = getRootCause(throwable); if (rootCause instanceof AccessDeniedException) { processAccessDeniedException(rootCause); iterator.remove(); continue; } // a handle method might redirect and set responseComplete if (context.getResponseComplete()) { break; } } } super.handle(); } @Override public Throwable getRootCause(Throwable throwable) { return JsfUtils.getRootCause(throwable); } @Override public void processEvent(SystemEvent event) throws AbortProcessingException { //handle exceptions which occur in a phase-listener (beforePhase) for PhaseId.RENDER_RESPONSE //needed because #handle gets called too late in this case if (event instanceof ExceptionQueuedEvent) { ExceptionQueuedEvent exceptionQueuedEvent = (ExceptionQueuedEvent)event; FacesContext facesContext = exceptionQueuedEvent.getContext().getContext(); if (facesContext.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE && exceptionQueuedEvent.getContext().inBeforePhase()) { Throwable exception = getRootCause(exceptionQueuedEvent.getContext().getException()); if (exception instanceof AccessDeniedException) { processAccessDeniedException(exception); } } } super.processEvent(event); } private void processAccessDeniedException(Throwable throwable) { if (throwable instanceof ErrorViewAwareAccessDeniedException) { SecurityUtils.handleSecurityViolationWithoutNavigation((AccessDeniedException) throwable); } else { ErrorViewAwareAccessDeniedException securityException = new ErrorViewAwareAccessDeniedException( ((AccessDeniedException)throwable).getViolations(), DefaultErrorView.class); SecurityUtils.handleSecurityViolationWithoutNavigation(securityException); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/action/DeltaSpikeActionListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.action; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jsf.impl.config.view.ViewControllerActionListener; import jakarta.faces.event.ActionEvent; import jakarta.faces.event.ActionListener; /** * Aggregates {@link ActionListener} implementations provided by DeltaSpike to ensure a deterministic behaviour */ public class DeltaSpikeActionListener implements ActionListener, Deactivatable { private final ActionListener wrapped; private final boolean activated; /** * Constructor for wrapping the given {@link ActionListener} * @param wrapped action-listener which should be wrapped */ public DeltaSpikeActionListener(ActionListener wrapped) { this.wrapped = wrapped; this.activated = ClassDeactivationUtils.isActivated(getClass()); } @Override public void processAction(ActionEvent actionEvent) { if (this.activated) { getWrappedActionListener().processAction(actionEvent); } else { this.wrapped.processAction(actionEvent); } } private ActionListener getWrappedActionListener() { //TODO re-visit it //was: //SecurityViolationAwareActionListener securityViolationAwareActionListener = // new SecurityViolationAwareActionListener(this.wrapped); return new ViewControllerActionListener(this.wrapped); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/AfterPhaseBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import org.apache.deltaspike.jsf.api.listener.phase.AfterPhase; import jakarta.enterprise.util.AnnotationLiteral; /** * Helper which allows to create instances of {@link AfterPhase} */ abstract class AfterPhaseBinding extends AnnotationLiteral implements AfterPhase { } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/BeforePhaseBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import org.apache.deltaspike.jsf.api.listener.phase.BeforePhase; import jakarta.enterprise.util.AnnotationLiteral; /** * Helper which allows to create instances of {@link BeforePhase} */ abstract class BeforePhaseBinding extends AnnotationLiteral implements BeforePhase { } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/DeltaSpikePhaseListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import org.apache.deltaspike.core.api.config.view.controller.InitView; import org.apache.deltaspike.core.api.config.view.controller.PostRenderView; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jsf.impl.security.ViewRootAccessHandler; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import org.apache.deltaspike.jsf.impl.util.SecurityUtils; import org.apache.deltaspike.jsf.impl.util.ViewControllerUtils; import org.apache.deltaspike.security.api.authorization.ErrorViewAwareAccessDeniedException; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; import jakarta.faces.event.PhaseEvent; import jakarta.faces.event.PhaseId; import jakarta.faces.event.PhaseListener; import java.util.logging.Logger; @Vetoed //don't use PhaseListener as type - JsfRequestLifecyclePhaseListener would fire to this listener as well public class DeltaSpikePhaseListener implements PhaseListener, Deactivatable { private static final long serialVersionUID = -4458288760053069922L; private final boolean activated; private Boolean securityModuleActivated; private final PhaseListener jsfRequestLifecyclePhaseListener = new JsfRequestLifecyclePhaseListener(); private volatile ViewConfigResolver viewConfigResolver; public DeltaSpikePhaseListener() { this.activated = ClassDeactivationUtils.isActivated(getClass()); } @Override public void beforePhase(PhaseEvent phaseEvent) { if (!this.activated) { return; } if (this.viewConfigResolver == null) { lazyInit(); } processInitView(phaseEvent); //delegate to JsfRequestLifecyclePhaseListener as a last step this.jsfRequestLifecyclePhaseListener.beforePhase(phaseEvent); if (PhaseId.RENDER_RESPONSE.equals(phaseEvent.getPhaseId())) { onBeforeRenderResponse(phaseEvent.getFacesContext()); } } private void onBeforeRenderResponse(FacesContext facesContext) { checkSecuredView(facesContext); processPreRenderView(facesContext); } @Override public void afterPhase(PhaseEvent phaseEvent) { if (!this.activated) { return; } if (this.viewConfigResolver == null) { lazyInit(); } processInitView(phaseEvent); if (PhaseId.RESTORE_VIEW.equals(phaseEvent.getPhaseId())) { onAfterRestoreView(phaseEvent.getFacesContext()); } else if (PhaseId.RENDER_RESPONSE.equals(phaseEvent.getPhaseId())) { onAfterRenderResponse(phaseEvent.getFacesContext()); } //delegate to JsfRequestLifecyclePhaseListener as a last step this.jsfRequestLifecyclePhaseListener.afterPhase(phaseEvent); } private void onAfterRestoreView(FacesContext facesContext) { JsfUtils.tryToRestoreMessages(facesContext); } private void onAfterRenderResponse(FacesContext facesContext) { processPostRenderView(facesContext); } @Override public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } private void checkSecuredView(FacesContext facesContext) { if (!this.securityModuleActivated) { return; } try { BeanProvider.getContextualReference(ViewRootAccessHandler.class).checkAccessTo(facesContext.getViewRoot()); } catch (ErrorViewAwareAccessDeniedException accessDeniedException) { SecurityUtils.tryToHandleSecurityViolation(accessDeniedException); facesContext.renderResponse(); } } private synchronized void lazyInit() { if (this.viewConfigResolver != null) { return; } this.securityModuleActivated = BeanProvider.getContextualReference(EditableAccessDecisionVoterContext.class, true) != null; this.viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); if (!this.securityModuleActivated) { Logger.getLogger(getClass().getName()) //it's the only case for which a logger is needed in this class .info("security-module-impl isn't used -> " + getClass().getName() + "#checkSecuredView gets deactivated"); } } private void processInitView(PhaseEvent event) { if (event.getPhaseId().equals(PhaseId.RESTORE_VIEW) && !isRedirectRequest(event.getFacesContext())) { return; } //TODO check if we have to restrict the other callbacks as well //leads to a call of @BeforePhase but not the corresponding @AfterPhase call of the corresponding callbacks //TODO don't call the callbacks in case of an initial redirct //was: /* if(Boolean.TRUE.equals(event.getFacesContext().getExternalContext().getRequestMap() .get(WindowContextManagerObserver.INITIAL_REDIRECT_PERFORMED_KEY))) { return; } */ FacesContext facesContext = event.getFacesContext(); if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId() != null) { processInitView(event.getFacesContext().getViewRoot().getViewId()); } } private void processInitView(String viewId) { try { WindowMetaData windowMetaData = BeanProvider.getContextualReference(WindowMetaData.class); //view already initialized in this or any prev. request if (viewId.equals(windowMetaData.getInitializedViewId())) { return; } //override the view-id if we have a new view windowMetaData.setInitializedViewId(viewId); ViewConfigDescriptor viewDefinitionEntry = this.viewConfigResolver.getViewConfigDescriptor(viewId); if (viewDefinitionEntry == null) { return; } ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, InitView.class); } catch (ContextNotActiveException e) { //TODO discuss how we handle it } } private void processPreRenderView(FacesContext facesContext) { UIViewRoot uiViewRoot = facesContext.getViewRoot(); if (uiViewRoot != null) { ViewConfigDescriptor viewDefinitionEntry = this.viewConfigResolver.getViewConfigDescriptor(uiViewRoot.getViewId()); ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, PreRenderView.class); } } private void processPostRenderView(FacesContext facesContext) { UIViewRoot uiViewRoot = facesContext.getViewRoot(); if (uiViewRoot != null) { ViewConfigDescriptor viewDefinitionEntry = this.viewConfigResolver.getViewConfigDescriptor(uiViewRoot.getViewId()); ViewControllerUtils.executeViewControllerCallback(viewDefinitionEntry, PostRenderView.class); } } private boolean isRedirectRequest(FacesContext facesContext) { return facesContext.getResponseComplete(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/JsfRequestLifecycleBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.jsf.api.listener.phase.AfterPhase; import org.apache.deltaspike.jsf.api.listener.phase.BeforePhase; import org.apache.deltaspike.jsf.api.listener.phase.JsfPhaseId; import org.apache.deltaspike.jsf.api.listener.phase.JsfPhaseListener; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Event; import jakarta.enterprise.inject.Instance; import jakarta.faces.event.PhaseEvent; import jakarta.faces.event.PhaseId; import jakarta.faces.event.PhaseListener; import jakarta.inject.Inject; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.ListIterator; @ApplicationScoped public class JsfRequestLifecycleBroadcaster { @Inject private Event phaseEvent; @Inject @BeforePhase(JsfPhaseId.ANY_PHASE) private Event beforeAnyPhaseEvent; @Inject @AfterPhase(JsfPhaseId.ANY_PHASE) private Event afterAnyPhaseEvent; private List phaseListeners = new ArrayList(); /** * Constructor used by proxy libs */ protected JsfRequestLifecycleBroadcaster() { } @Inject protected JsfRequestLifecycleBroadcaster(Instance phaseListenerInstance) { Class phaseListenerClass; for (PhaseListener currentPhaseListener : phaseListenerInstance) { phaseListenerClass = ProxyUtils.getUnproxiedClass(currentPhaseListener.getClass()); if (phaseListenerClass.isAnnotationPresent(JsfPhaseListener.class)) { if (Deactivatable.class.isAssignableFrom(phaseListenerClass) && !ClassDeactivationUtils.isActivated(phaseListenerClass)) { continue; } this.phaseListeners.add(currentPhaseListener); } } //higher ordinals first sortDescending(this.phaseListeners); } private static void sortDescending(List phaseListeners) { Collections.sort(phaseListeners, new Comparator() { @Override public int compare(PhaseListener phaseListener1, PhaseListener phaseListener2) { return (phaseListener1.getClass().getAnnotation(JsfPhaseListener.class).ordinal() > phaseListener2.getClass().getAnnotation(JsfPhaseListener.class).ordinal()) ? -1 : 1; } }); } protected void broadcastBeforeEvent(PhaseEvent phaseEvent) { //TODO discuss exception handling //fire to phase-observer methods this.phaseEvent.select(createAnnotationLiteral(phaseEvent.getPhaseId(), true)).fire(phaseEvent); this.beforeAnyPhaseEvent.fire(phaseEvent); //fire to ds-phase-listeners for (PhaseListener phaseListener : this.phaseListeners) { PhaseId targetPhase = phaseListener.getPhaseId(); if (targetPhase == PhaseId.ANY_PHASE || targetPhase == phaseEvent.getPhaseId()) { phaseListener.beforePhase(phaseEvent); } } } protected void broadcastAfterEvent(PhaseEvent phaseEvent) { //TODO discuss exception handling //fire to phase-observer methods this.phaseEvent.select(createAnnotationLiteral(phaseEvent.getPhaseId(), false)).fire(phaseEvent); this.afterAnyPhaseEvent.fire(phaseEvent); //fire to ds-phase-listeners //call the listeners in reverse-order (like jsf) ListIterator phaseListenerIterator = this.phaseListeners.listIterator(phaseListeners.size()); while (phaseListenerIterator.hasPrevious()) { PhaseListener phaseListener = phaseListenerIterator.previous(); PhaseId targetPhase = phaseListener.getPhaseId(); if (targetPhase == PhaseId.ANY_PHASE || targetPhase == phaseEvent.getPhaseId()) { phaseListener.afterPhase(phaseEvent); } } } protected Annotation createAnnotationLiteral(jakarta.faces.event.PhaseId phaseId, boolean isBeforeEvent) { if (isBeforeEvent) { return createBeforeLiteral(phaseId); } return createAfterLiteral(phaseId); } protected Annotation createBeforeLiteral(final jakarta.faces.event.PhaseId phaseId) { return new BeforePhaseBinding() { private static final long serialVersionUID = 749645435335842723L; @Override public JsfPhaseId value() { return JsfPhaseId.convertFromFacesClass(phaseId); } }; } protected Annotation createAfterLiteral(final jakarta.faces.event.PhaseId phaseId) { return new AfterPhaseBinding() { private static final long serialVersionUID = 390037768660184656L; @Override public JsfPhaseId value() { return JsfPhaseId.convertFromFacesClass(phaseId); } }; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/JsfRequestLifecyclePhaseListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.faces.event.PhaseEvent; import jakarta.faces.event.PhaseId; import jakarta.faces.event.PhaseListener; /** * PhaseListener for triggering {@link JsfRequestLifecycleBroadcaster} */ @Typed(Deactivatable.class) //don't use PhaseListener - the broadcaster would fire to this listener as well public class JsfRequestLifecyclePhaseListener implements PhaseListener, Deactivatable { private static final long serialVersionUID = -3351903831660165998L; private final boolean activated; public JsfRequestLifecyclePhaseListener() { this.activated = ClassDeactivationUtils.isActivated(getClass()); } @Override public void beforePhase(PhaseEvent phaseEvent) { if (this.activated) { resolveBroadcaster().broadcastBeforeEvent(phaseEvent); } } @Override public void afterPhase(PhaseEvent phaseEvent) { if (this.activated) { resolveBroadcaster().broadcastAfterEvent(phaseEvent); } } @Override public PhaseId getPhaseId() { return PhaseId.ANY_PHASE; } private JsfRequestLifecycleBroadcaster resolveBroadcaster() { //cdi has to inject the events,... return BeanProvider.getContextualReference(JsfRequestLifecycleBroadcaster.class); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/phase/WindowMetaData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.phase; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.jsf.impl.message.FacesMessageEntry; import java.io.Serializable; import java.util.List; @WindowScoped public class WindowMetaData implements Serializable { private static final long serialVersionUID = -413165700186583037L; private String initializedViewId; /** * used per default instead of Flash#setKeepMessages, * because there are less issues in view of multi-window support esp. before jsf v2.2 and * a custom window-handler might have special requirements. */ private List facesMessageEntryList; public String getInitializedViewId() { return initializedViewId; } public void setInitializedViewId(String initializedViewId) { this.initializedViewId = initializedViewId; } public void setFacesMessageEntryList(List facesMessageEntryList) { this.facesMessageEntryList = facesMessageEntryList; } public List getFacesMessageEntryList() { return facesMessageEntryList; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeApplicationWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; import jakarta.faces.application.Application; import jakarta.faces.application.ApplicationWrapper; import jakarta.faces.application.ProjectStage; import jakarta.faces.context.FacesContext; import jakarta.faces.event.PreDestroyViewMapEvent; import jakarta.faces.event.SystemEvent; public class DeltaSpikeApplicationWrapper extends ApplicationWrapper { private final Application wrapped; private final boolean preDestroyViewMapEventFilterMode; private final ProjectStage projectStage; public DeltaSpikeApplicationWrapper( Application wrapped, JsfModuleConfig jsfModuleConfig, boolean preDestroyViewMapEventFilterMode, ProjectStage projectStage) { this.wrapped = wrapped; this.preDestroyViewMapEventFilterMode = preDestroyViewMapEventFilterMode; this.projectStage = projectStage; } @Override public ProjectStage getProjectStage() { if (this.projectStage == null) { return getWrapped().getProjectStage(); } return this.projectStage; } @Override public void publishEvent(FacesContext facesContext, Class systemEventClass, Object source) { if (!PreDestroyViewMapEvent.class.isAssignableFrom(systemEventClass) || isPreDestroyViewMapEventAllowed(facesContext)) { super.publishEvent(facesContext, systemEventClass, source); } } private boolean isPreDestroyViewMapEventAllowed(FacesContext facesContext) { return !this.preDestroyViewMapEventFilterMode || !Boolean.TRUE.equals(facesContext.getExternalContext().getRequestMap().get( SecurityAwareViewHandler.PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED)); } @Override public Application getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeExternalContextWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.ExternalContextWrapper; import java.io.IOException; import jakarta.faces.context.FacesContext; import jakarta.faces.lifecycle.ClientWindow; import org.apache.deltaspike.jsf.impl.clientwindow.DeltaSpikeClientWindow; import org.apache.deltaspike.jsf.impl.util.ClientWindowHelper; public class DeltaSpikeExternalContextWrapper extends ExternalContextWrapper implements Deactivatable { private final ExternalContext wrapped; DeltaSpikeExternalContextWrapper(ExternalContext wrapped) { this.wrapped = wrapped; } @Override public void redirect(String url) throws IOException { FacesContext facesContext = FacesContext.getCurrentInstance(); // skip if we are in initialRedirect mode because // save messages via flash scope will fail because the JSF lifecycle isn't initialized if (!ClientWindowHelper.isInitialRedirect(facesContext)) { JsfUtils.saveFacesMessages(this.wrapped); } ClientWindow clientWindow = getClientWindow(); if (clientWindow != null && clientWindow instanceof DeltaSpikeClientWindow) { url = ((DeltaSpikeClientWindow) clientWindow).interceptRedirect(facesContext, url); } this.wrapped.redirect(url); } @Override public ExternalContext getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.faces.context.FacesContext; import jakarta.faces.context.FacesContextFactory; import jakarta.faces.lifecycle.Lifecycle; public class DeltaSpikeFacesContextFactory extends FacesContextFactory implements Deactivatable { private final FacesContextFactory wrappedFacesContextFactory; private final boolean deactivated; /** * Constructor for wrapping the given {@link FacesContextFactory} * * @param wrappedFacesContextFactory wrapped faces-context-factory which should be used */ public DeltaSpikeFacesContextFactory(FacesContextFactory wrappedFacesContextFactory) { this.wrappedFacesContextFactory = wrappedFacesContextFactory; this.deactivated = !ClassDeactivationUtils.isActivated(getClass()); } /** * Wrapps the created {@link jakarta.faces.context.FacesContext} with {@link DeltaSpikeFacesContextWrapper} *

* {@inheritDoc} */ @Override public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle) { FacesContext facesContext = this.wrappedFacesContextFactory.getFacesContext(context, request, response, lifecycle); if (facesContext == null || this.deactivated || facesContext instanceof DeltaSpikeFacesContextWrapper) { return facesContext; } return new DeltaSpikeFacesContextWrapper(facesContext); } /** * {@inheritDoc} */ @Override public FacesContextFactory getWrapped() { return wrappedFacesContextFactory; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeFacesContextWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import java.lang.annotation.Annotation; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.projectstage.TestStage; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.impl.config.view.DefaultErrorViewAwareExceptionHandlerWrapper; import org.apache.deltaspike.jsf.impl.message.FacesMessageEntry; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.faces.application.Application; import jakarta.faces.application.FacesMessage; import jakarta.faces.application.ProjectStage; import jakarta.faces.context.ExceptionHandler; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import jakarta.faces.context.FacesContextWrapper; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.jsf.impl.exception.control.BridgeExceptionHandlerWrapper; import org.apache.deltaspike.jsf.impl.navigation.NavigationHandlerAwareApplication; import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; class DeltaSpikeFacesContextWrapper extends FacesContextWrapper { private final FacesContext wrappedFacesContext; private BeanManager beanManager; private JsfRequestBroadcaster jsfRequestBroadcaster; private boolean defaultErrorViewExceptionHandlerActivated; private boolean bridgeExceptionHandlerActivated; private Annotation bridgeExceptionQualifier; private ExternalContext wrappedExternalContext; private JsfModuleConfig jsfModuleConfig; private volatile Boolean initialized; private volatile Boolean isNavigationAwareApplicationWrapperActivated; private boolean preDestroyViewMapEventFilterMode; private ProjectStage projectStage; DeltaSpikeFacesContextWrapper(FacesContext wrappedFacesContext) { this.wrappedFacesContext = wrappedFacesContext; if (ClassDeactivationUtils.isActivated(DeltaSpikeExternalContextWrapper.class)) { this.wrappedExternalContext = new DeltaSpikeExternalContextWrapper(wrappedFacesContext.getExternalContext()); } else { this.wrappedExternalContext = wrappedFacesContext.getExternalContext(); } setCurrentInstance(this); } /** * Broadcasts the {@link org.apache.deltaspike.core.api.lifecycle.Destroyed} event * {@inheritDoc} */ @Override public void release() { // try/finally shouldn't be required... try { if (!this.wrappedFacesContext.getApplication().getResourceHandler() .isResourceRequest(this.wrappedFacesContext)) { broadcastDestroyedJsfRequestEvent(); } } finally { super.release(); } } @Override public ExceptionHandler getExceptionHandler() { lazyInit(); ExceptionHandler exceptionHandler = this.wrappedFacesContext.getExceptionHandler(); if (this.bridgeExceptionHandlerActivated) { exceptionHandler = new BridgeExceptionHandlerWrapper(exceptionHandler); } if (this.defaultErrorViewExceptionHandlerActivated) { exceptionHandler = new DefaultErrorViewAwareExceptionHandlerWrapper(exceptionHandler); } return exceptionHandler; } private void broadcastDestroyedJsfRequestEvent() { lazyInit(); if (this.jsfRequestBroadcaster != null) { this.jsfRequestBroadcaster.broadcastDestroyedJsfRequestEvent(this); } } private void lazyInit() { if (this.initialized == null) { init(); } } private synchronized void init() { // switch into paranoia mode if (this.initialized == null) { this.beanManager = BeanManagerProvider.getInstance().getBeanManager(); this.jsfModuleConfig = BeanProvider.getContextualReference(this.beanManager, JsfModuleConfig.class, false); if (ClassDeactivationUtils.isActivated(JsfRequestBroadcaster.class)) { this.jsfRequestBroadcaster = BeanProvider.getContextualReference(JsfRequestBroadcaster.class, true); } ViewConfigResolver viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); //deactivate it, if there is no default-error-view available this.defaultErrorViewExceptionHandlerActivated = viewConfigResolver.getDefaultErrorViewConfigDescriptor() != null && ClassDeactivationUtils.isActivated(DefaultErrorViewAwareExceptionHandlerWrapper.class); this.bridgeExceptionHandlerActivated = ClassDeactivationUtils.isActivated(BridgeExceptionHandlerWrapper.class); this.bridgeExceptionQualifier = AnnotationInstanceProvider.of(jsfModuleConfig.getExceptionQualifier()); this.preDestroyViewMapEventFilterMode = ClassDeactivationUtils.isActivated(SecurityAwareViewHandler.class); this.isNavigationAwareApplicationWrapperActivated = ClassDeactivationUtils.isActivated(NavigationHandlerAwareApplication.class); org.apache.deltaspike.core.api.projectstage.ProjectStage dsProjectStage = ProjectStageProducer.getInstance().getProjectStage(); for (ProjectStage ps : ProjectStage.values()) { if (ps.name().equals(dsProjectStage.getClass().getSimpleName())) { this.projectStage = ps; break; } } if (this.projectStage == null && dsProjectStage instanceof TestStage) { this.projectStage = ProjectStage.Development; } if (this.projectStage == ProjectStage.Production) { this.projectStage = null; //reset it to force the delegation to the default handling } this.initialized = true; } } /** * Adds the {@link FacesMessage} also to a request scoped list to allow to preserve them later on * (in case of redirects) * * {@inheritDoc} */ @Override public void addMessage(String componentId, FacesMessage facesMessage) { this.wrappedFacesContext.addMessage(componentId, facesMessage); //don't store it directly in the window context - it would trigger a too early restore (in some cases) Map requestMap = getExternalContext().getRequestMap(); @SuppressWarnings({ "unchecked" }) List facesMessageEntryList = (List)requestMap.get(FacesMessageEntry.class.getName()); if (facesMessageEntryList == null) { facesMessageEntryList = new CopyOnWriteArrayList(); requestMap.put(FacesMessageEntry.class.getName(), facesMessageEntryList); } facesMessageEntryList.add(new FacesMessageEntry(componentId, facesMessage)); } @Override public ExternalContext getExternalContext() { return this.wrappedExternalContext; } @Override public Application getApplication() { lazyInit(); Application wrappedApplication = this.wrappedFacesContext.getApplication(); if (this.isNavigationAwareApplicationWrapperActivated) { wrappedApplication = new NavigationHandlerAwareApplication(wrappedApplication); } return new DeltaSpikeApplicationWrapper( wrappedApplication, this.jsfModuleConfig, this.preDestroyViewMapEventFilterMode, this.projectStage); } @Override public FacesContext getWrapped() { return this.wrappedFacesContext; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleFactoryWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.faces.lifecycle.Lifecycle; import jakarta.faces.lifecycle.LifecycleFactory; import java.util.Iterator; public class DeltaSpikeLifecycleFactoryWrapper extends LifecycleFactory implements Deactivatable { private final LifecycleFactory wrapped; private final boolean deactivated; /** * Constructor for wrapping the given {@link LifecycleFactory} * * @param wrapped lifecycle-factory which should be wrapped */ public DeltaSpikeLifecycleFactoryWrapper(LifecycleFactory wrapped) { this.wrapped = wrapped; this.deactivated = !ClassDeactivationUtils.isActivated(getClass()); } @Override public void addLifecycle(String s, Lifecycle lifecycle) { wrapped.addLifecycle(s, lifecycle); } @Override public Lifecycle getLifecycle(String s) { Lifecycle result = this.wrapped.getLifecycle(s); if (this.deactivated) { return result; } return new DeltaSpikeLifecycleWrapper(result); } @Override public Iterator getLifecycleIds() { return wrapped.getLifecycleIds(); } @Override public LifecycleFactory getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/DeltaSpikeLifecycleWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import jakarta.faces.context.FacesContext; import jakarta.faces.event.PhaseListener; import jakarta.faces.lifecycle.ClientWindow; import jakarta.faces.lifecycle.Lifecycle; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessContext; import org.apache.deltaspike.jsf.impl.clientwindow.ClientSideClientWindow; import org.apache.deltaspike.jsf.impl.clientwindow.LazyClientWindow; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; class DeltaSpikeLifecycleWrapper extends Lifecycle { private final Lifecycle wrapped; private JsfRequestBroadcaster jsfRequestBroadcaster; private ClientWindowConfig clientWindowConfig; private WindowContext windowContext; private DeltaSpikeContextExtension contextExtension; private volatile Boolean initialized; DeltaSpikeLifecycleWrapper(Lifecycle wrapped) { this.wrapped = wrapped; } Lifecycle getWrapped() { return wrapped; } @Override public void addPhaseListener(PhaseListener phaseListener) { this.wrapped.addPhaseListener(phaseListener); } /** * Broadcasts * {@link org.apache.deltaspike.core.api.lifecycle.Initialized} and * {@link org.apache.deltaspike.core.api.lifecycle.Destroyed} * //TODO StartupEvent */ @Override public void execute(FacesContext facesContext) { //can happen due to the window-handling of deltaspike if (facesContext.getResponseComplete()) { return; } lazyInit(); //TODO broadcastApplicationStartupBroadcaster(); broadcastInitializedJsfRequestEvent(facesContext); // ClientWindow handling ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow(); if (clientWindow != null) { String windowId = clientWindow.getId(); if (windowId != null) { windowContext.activateWindow(windowId); } } if (!FacesContext.getCurrentInstance().getResponseComplete()) { this.wrapped.execute(facesContext); } } @Override public PhaseListener[] getPhaseListeners() { return this.wrapped.getPhaseListeners(); } @Override public void removePhaseListener(PhaseListener phaseListener) { this.wrapped.removePhaseListener(phaseListener); } /** * Performs cleanup tasks after the rendering process */ @Override public void render(FacesContext facesContext) { this.wrapped.render(facesContext); if (facesContext.getViewRoot() != null && facesContext.getViewRoot().getViewId() != null) { ViewAccessContext viewAccessContext = contextExtension.getViewAccessScopedContext(); if (viewAccessContext != null) { viewAccessContext.onProcessingViewFinished(facesContext.getViewRoot().getViewId()); } } } @Override public void attachWindow(FacesContext facesContext) { lazyInit(); ClientWindowConfig.ClientWindowRenderMode clientWindowRenderMode = clientWindowConfig.getClientWindowRenderMode(facesContext); if (clientWindowRenderMode == ClientWindowConfig.ClientWindowRenderMode.DELEGATED) { this.wrapped.attachWindow(facesContext); } else { if (!facesContext.getResponseComplete()) { if (clientWindowRenderMode == ClientWindowConfig.ClientWindowRenderMode.LAZY) { facesContext.getExternalContext().setClientWindow(new LazyClientWindow()); facesContext.getExternalContext().getClientWindow().decode(facesContext); } else if (clientWindowRenderMode == ClientWindowConfig.ClientWindowRenderMode.CLIENTWINDOW) { facesContext.getExternalContext().setClientWindow(new ClientSideClientWindow()); facesContext.getExternalContext().getClientWindow().decode(facesContext); } else if (clientWindowRenderMode == ClientWindowConfig.ClientWindowRenderMode.NONE) { // do nothing } } } } private void broadcastInitializedJsfRequestEvent(FacesContext facesContext) { if (this.jsfRequestBroadcaster != null) { this.jsfRequestBroadcaster.broadcastInitializedJsfRequestEvent(facesContext); } } private void lazyInit() { if (this.initialized == null) { init(); } } private synchronized void init() { // switch into paranoia mode if (this.initialized == null) { if (ClassDeactivationUtils.isActivated(JsfRequestBroadcaster.class)) { this.jsfRequestBroadcaster = BeanProvider.getContextualReference(JsfRequestBroadcaster.class, true); } this.windowContext = BeanProvider.getContextualReference(WindowContext.class, true); this.contextExtension = BeanProvider.getContextualReference(DeltaSpikeContextExtension.class, true); this.clientWindowConfig = BeanProvider.getContextualReference(ClientWindowConfig.class); this.initialized = true; } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/request/JsfRequestBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.request; import org.apache.deltaspike.core.spi.activation.Deactivatable; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Destroyed; import jakarta.enterprise.context.Initialized; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.event.Event; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; /** * Broadcaster for * {@link jakarta.enterprise.context.Initialized} * {@link jakarta.enterprise.context.Destroyed} * with * {@link jakarta.faces.bean.RequestScoped} as annotation-parameter and * {@link FacesContext} as event-payload */ @ApplicationScoped public class JsfRequestBroadcaster implements Deactivatable { @Inject @Initialized(RequestScoped.class) private Event initEvent; @Inject @Destroyed(RequestScoped.class) private Event destroyedEvent; /** * Broadcasts @Initialized-event(s) * * @param facesContext current faces-context */ public void broadcastInitializedJsfRequestEvent(FacesContext facesContext) { this.initEvent.fire(facesContext); } /** * Broadcasts @Destroyed-event(s) * * @param facesContext current faces-context */ public void broadcastDestroyedJsfRequestEvent(FacesContext facesContext) { this.destroyedEvent.fire(facesContext); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/listener/system/JsfSystemEventBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.listener.system; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.faces.event.AbortProcessingException; import jakarta.faces.event.SystemEvent; import jakarta.faces.event.SystemEventListener; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; /** * Broadcasts JSF events to CDI observers. */ public class JsfSystemEventBroadcaster implements SystemEventListener, Deactivatable { private boolean isActivated = true; public JsfSystemEventBroadcaster() { this.isActivated = ClassDeactivationUtils.isActivated(getClass()); } @Override public boolean isListenerForSource(Object source) { return true; } @Override public void processEvent(SystemEvent e) throws AbortProcessingException { if (!this.isActivated) { return; } BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); beanManager.getEvent().fire(e); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/DefaultJsfMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import java.lang.reflect.Proxy; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.message.JsfMessage; /** * Default implementation of JsfMessage. * The complexity of setting the FacesMessage is * done in the {@link JsfMessageBundleInvocationHandler}. */ @Vetoed public class DefaultJsfMessage implements JsfMessage { private final String clientId; private final Class type; private final MessageBundleInvocationHandler invocationHandler; /** * The Message type * @param type * @param clientId */ public DefaultJsfMessage(Class type, String clientId, MessageBundleInvocationHandler invocationHandler) { this.type = type; this.clientId = clientId; this.invocationHandler = invocationHandler; if (! type.isInterface() || type.getAnnotation(MessageBundle.class) == null) { throw new IllegalArgumentException("JsfMessage must only be used for interfaces " + "annotated with @MessageBundle!"); } } @Override public JsfMessage forClientId(String clientId) { return new DefaultJsfMessage<>(type, clientId, invocationHandler); } @Override public JsfMessage forComponent(UIComponent uiComponent) { return forClientId(uiComponent.getClientId()); } @Override public T addError() { return getMessage(FacesMessage.SEVERITY_ERROR); } @Override public T addFatal() { return getMessage(FacesMessage.SEVERITY_FATAL); } @Override public T addInfo() { return getMessage(FacesMessage.SEVERITY_INFO); } @Override public T addWarn() { return getMessage(FacesMessage.SEVERITY_WARN); } @Override public T get() { return getMessage(null); } private T getMessage(FacesMessage.Severity severity) { return type.cast(Proxy.newProxyInstance(ClassUtils.getClassLoader(null), new Class[]{type}, new JsfMessageBundleInvocationHandler(severity, clientId, invocationHandler))); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/FacesMessageEntry.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.application.FacesMessage; import java.io.Serializable; /** * Entry for {@link FacesMessage} which have to be stored longer than a request */ @Vetoed public class FacesMessageEntry implements Serializable { private static final long serialVersionUID = 6831499672107426470L; private String componentId; private FacesMessage facesMessage; protected FacesMessageEntry() { } /** * Constructor for creating the entry for the given component-id and {@link FacesMessage} * @param componentId current component-id * @param facesMessage current faces-message */ public FacesMessageEntry(String componentId, FacesMessage facesMessage) { this.componentId = componentId; this.facesMessage = facesMessage; } /** * Returns the current component-id * @return component-id of the entry */ public String getComponentId() { return componentId; } /** * Returns the current {@link FacesMessage} * @return faces-message of the entry */ public FacesMessage getFacesMessage() { return facesMessage; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfAwareLocaleResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import org.apache.deltaspike.core.impl.message.DefaultLocaleResolver; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; import java.util.Iterator; import java.util.Locale; @ApplicationScoped @Specializes public class JsfAwareLocaleResolver extends DefaultLocaleResolver { private static final long serialVersionUID = -8776583393262804931L; @Override public Locale getLocale() { FacesContext facesContext = FacesContext.getCurrentInstance(); if (facesContext != null && facesContext.getCurrentPhaseId() != null) { UIViewRoot viewRoot = facesContext.getViewRoot(); Locale result = null; if (viewRoot != null) { // if a ViewRoot is present we return the Locale from there result = viewRoot.getLocale(); } if (result != null) { Iterator supportedLocale = facesContext.getApplication().getSupportedLocales(); boolean supportedLocaleConfigured = false; while (supportedLocale.hasNext()) { supportedLocaleConfigured = true; if (result.equals(supportedLocale.next())) { return result; } } if (!supportedLocaleConfigured) { return result; } } result = facesContext.getApplication().getDefaultLocale(); if (result != null) { return result; } } // return the default Locale, if no Locale was found return super.getLocale(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageBundleInvocationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler; import org.apache.deltaspike.jsf.api.message.JsfMessage; /** * This Proxy InvocationHandler automatically registers the * returned messages in the FacesContext if a severity is set. */ @Vetoed public class JsfMessageBundleInvocationHandler implements InvocationHandler { private final FacesMessage.Severity severity; private final String clientId; private final MessageBundleInvocationHandler invocationHandler; public JsfMessageBundleInvocationHandler(FacesMessage.Severity severity, String clientId, MessageBundleInvocationHandler invocationHandler) { this.severity = severity; this.clientId = clientId; this.invocationHandler = invocationHandler; } @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { Object message = invocationHandler.invoke(proxy, method, args); if (severity == null) { if (message instanceof Message) { return message; } return getMessageCategory(message, JsfMessage.CATEGORY_SUMMARY); } else { String summary = getMessageCategory(message, JsfMessage.CATEGORY_SUMMARY); String detail = getMessageCategory(message, JsfMessage.CATEGORY_DETAIL); FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(severity, summary, detail)); return message; } } private String getMessageCategory(Object message, String category) { if (message == null) { return null; } if (message instanceof String) { return (String) message; } else if (message instanceof Message) { return ((Message) message).toString(category); } else { throw new IllegalArgumentException("message must be of either type String or Message but was: " + message.getClass() + " value: " + message); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.InjectionPoint; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler; import org.apache.deltaspike.jsf.api.message.JsfMessage; /** * Produces a dependent JsfMessage */ @ApplicationScoped public class JsfMessageProducer { @Produces @Dependent public JsfMessage createJsfMessage(InjectionPoint injectionPoint, MessageBundleInvocationHandler invocationHandler) { if (!(injectionPoint.getType() instanceof ParameterizedType)) { throw new IllegalArgumentException("JsfMessage must be used as generic type"); } ParameterizedType paramType = (ParameterizedType) injectionPoint.getType(); Type[] actualTypes = paramType.getActualTypeArguments(); if (actualTypes.length != 1) { throw new IllegalArgumentException("JsfMessage must have the MessageBundle as generic type parameter"); } try { @SuppressWarnings("unchecked") Class type = (Class) actualTypes[0]; return createJsfMessageFor(injectionPoint, type, invocationHandler); } catch (ClassCastException e) { throw new IllegalArgumentException("Incorrect class found when trying to convert to parameterized type",e); } } private JsfMessage createJsfMessageFor(InjectionPoint injectionPoint, Class rawType, MessageBundleInvocationHandler invocationHandler) { // X TODO check if the JsfMessage should get injected into a UIComponent and use #getClientId() return new DefaultJsfMessage<>(rawType, null, invocationHandler); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/message/JsfMessageResolver.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.message; import org.apache.deltaspike.core.api.message.MessageContext; import org.apache.deltaspike.core.impl.message.DefaultMessageResolver; import jakarta.enterprise.inject.Specializes; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; import java.util.ArrayList; import java.util.List; @Specializes public class JsfMessageResolver extends DefaultMessageResolver { @Override protected List getMessageSources(MessageContext messageContext) { List result = new ArrayList<>(super.getMessageSources(messageContext) /*unmodifiable-list*/); FacesContext facesContext = FacesContext.getCurrentInstance(); if (facesContext == null || facesContext.getCurrentPhaseId() == null) { return result; } String bundleName = facesContext.getApplication().getMessageBundle(); if (bundleName != null) { result.add(bundleName); } result.add(FacesMessage.FACES_MESSAGES); //default messages from jsf return result; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/navigation/DeltaSpikeNavigationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.navigation; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.navigation.NavigationCaseMapWrapper; import org.apache.deltaspike.jsf.impl.config.view.navigation.ViewConfigAwareNavigationHandler; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import jakarta.faces.application.ConfigurableNavigationHandler; import jakarta.faces.application.NavigationCase; import jakarta.faces.application.NavigationHandler; import jakarta.faces.context.FacesContext; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import org.apache.deltaspike.jsf.impl.scope.viewaccess.ViewAccessScopedAwareNavigationHandler; public class DeltaSpikeNavigationHandler extends ConfigurableNavigationHandler implements Deactivatable { private Set otherOutcomes = new CopyOnWriteArraySet<>(); private Map viewConfigBasedNavigationCaseCache = new ConcurrentHashMap<>(); private final NavigationHandler wrapped; private final boolean activated; private final boolean vasnhActivated; /** * Constructor for wrapping the given {@link NavigationHandler} * * @param navigationHandler navigation-handler which should be wrapped */ public DeltaSpikeNavigationHandler(NavigationHandler navigationHandler) { this.wrapped = navigationHandler; this.activated = ClassDeactivationUtils.isActivated(getClass()); this.vasnhActivated = ClassDeactivationUtils.isActivated(ViewAccessScopedAwareNavigationHandler.class); } @Override public void handleNavigation(FacesContext context, String fromAction, String outcome) { if (!this.activated || isUnhandledExceptionQueued(context)) { this.wrapped.handleNavigation(context, fromAction, outcome); } else { //don't refactor it - currently we need the lazy wrapping due to special jsf2 constellations getWrappedNavigationHandler().handleNavigation(context, fromAction, outcome); } } private boolean isUnhandledExceptionQueued(FacesContext context) { return context.getExceptionHandler().getUnhandledExceptionQueuedEvents() != null && context.getExceptionHandler().getUnhandledExceptionQueuedEvents().iterator().hasNext(); } private NavigationHandler getWrappedNavigationHandler() { NavigationHandler navigationHandler = new ViewConfigAwareNavigationHandler(this.wrapped); if (vasnhActivated) { navigationHandler = new ViewAccessScopedAwareNavigationHandler(navigationHandler); } return navigationHandler; } @Override public NavigationCase getNavigationCase(FacesContext context, String action, String outcome) { if (this.wrapped instanceof ConfigurableNavigationHandler) { if (!this.activated) { return ((ConfigurableNavigationHandler)this.wrapped).getNavigationCase(context, action, outcome); } if (action == null && outcome != null && outcome.contains(".") && outcome.startsWith("class ") && !otherOutcomes.contains(outcome)) { String originalOutcome = outcome; NavigationCase navigationCase = this.viewConfigBasedNavigationCaseCache.get(originalOutcome); if (navigationCase != null) { return navigationCase; } outcome = outcome.substring(6); ViewConfigDescriptor entry = null; if (DefaultErrorView.class.getName().equals(originalOutcome)) { ViewConfigResolver viewConfigResolver = JsfUtils.getViewConfigResolver(); entry = viewConfigResolver.getDefaultErrorViewConfigDescriptor(); } if (entry == null) { Object loadedClass = ClassUtils.tryToLoadClassForName(outcome); if (loadedClass == null) { this.otherOutcomes.add(originalOutcome); } else if (ViewConfig.class.isAssignableFrom((Class) loadedClass)) { entry = JsfUtils.getViewConfigResolver() .getViewConfigDescriptor((Class) loadedClass); } } if (entry != null) { View.NavigationMode navigationMode = entry.getMetaData(View.class).iterator().next().navigation(); navigationCase = new NavigationCase("*", null, null, null, entry.getViewId(), null, View.NavigationMode.REDIRECT.equals(navigationMode), false); this.viewConfigBasedNavigationCaseCache.put(originalOutcome, navigationCase); return navigationCase; } } return ((ConfigurableNavigationHandler) this.wrapped).getNavigationCase(context, action, outcome); } return null; } @Override public Map> getNavigationCases() { Map> result = null; if (this.wrapped instanceof ConfigurableNavigationHandler) { result = ((ConfigurableNavigationHandler) this.wrapped).getNavigationCases(); } if (result == null) { result = new HashMap<>(); } if (!this.activated) { return result; } return new NavigationCaseMapWrapper(result, this.wrapped); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/navigation/DeltaSpikeNavigationHandlerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.navigation; import jakarta.faces.application.ConfigurableNavigationHandler; import jakarta.faces.application.ConfigurableNavigationHandlerWrapper; import jakarta.faces.application.NavigationCase; import jakarta.faces.context.FacesContext; import java.util.Map; import java.util.Set; //ATTENTION: don't rename/move this class as long as we need the workaround in impl-ee6 //(further details are available at: DELTASPIKE-655 and DELTASPIKE-659) @SuppressWarnings("UnusedDeclaration") public class DeltaSpikeNavigationHandlerWrapper extends ConfigurableNavigationHandlerWrapper { private final ConfigurableNavigationHandler wrapped; private final DeltaSpikeNavigationHandler deltaSpikeNavigationHandler; public DeltaSpikeNavigationHandlerWrapper(ConfigurableNavigationHandler wrapped) { this.wrapped = wrapped; //only for delegating the methods implemented by DeltaSpikeNavigationHandler this.deltaSpikeNavigationHandler = new DeltaSpikeNavigationHandler(wrapped); } @Override public void handleNavigation(FacesContext context, String fromAction, String outcome) { this.deltaSpikeNavigationHandler.handleNavigation(context, fromAction, outcome); } @Override public Map> getNavigationCases() { return this.deltaSpikeNavigationHandler.getNavigationCases(); } @Override public NavigationCase getNavigationCase(FacesContext context, String fromAction, String outcome) { return this.deltaSpikeNavigationHandler.getNavigationCase(context, fromAction, outcome); } @Override public ConfigurableNavigationHandler getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/navigation/NavigationHandlerAwareApplication.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.navigation; import jakarta.faces.application.ConfigurableNavigationHandler; import org.apache.deltaspike.core.spi.activation.Deactivatable; import jakarta.faces.application.Application; import jakarta.faces.application.ApplicationWrapper; import jakarta.faces.application.NavigationHandler; public class NavigationHandlerAwareApplication extends ApplicationWrapper implements Deactivatable { private final Application wrapped; public NavigationHandlerAwareApplication(Application wrapped) { this.wrapped = wrapped; } @Override public NavigationHandler getNavigationHandler() { NavigationHandler wrappedNavigationHandler = this.wrapped.getNavigationHandler(); return new DeltaSpikeNavigationHandlerWrapper((ConfigurableNavigationHandler) wrappedNavigationHandler); } @Override public Application getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/resource/DeltaSpikeResource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.resource; import jakarta.faces.application.Resource; import jakarta.faces.application.ResourceWrapper; /** * {@link ResourceWrapper} which appends the version of DeltaSpike to the URL. */ public class DeltaSpikeResource extends ResourceWrapper { private final Resource wrapped; private final String version; public DeltaSpikeResource(Resource resource, String version) { super(); this.wrapped = resource; this.version = version; } @Override public Resource getWrapped() { return wrapped; } @Override public String getRequestPath() { return super.getRequestPath() + "&v=" + version; } @Override public String getContentType() { return getWrapped().getContentType(); } @Override public String getLibraryName() { return getWrapped().getLibraryName(); } @Override public String getResourceName() { return getWrapped().getResourceName(); } @Override public void setContentType(String contentType) { getWrapped().setContentType(contentType); } @Override public void setLibraryName(String libraryName) { getWrapped().setLibraryName(libraryName); } @Override public void setResourceName(String resourceName) { getWrapped().setResourceName(resourceName); } @Override public String toString() { return getWrapped().toString(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/resource/DeltaSpikeResourceHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.resource; import jakarta.faces.application.Resource; import jakarta.faces.application.ResourceHandler; import jakarta.faces.application.ResourceHandlerWrapper; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; /** * {@link ResourceHandlerWrapper} to deliver uncompressed resources in {@link ProjectStage#Development}. */ public class DeltaSpikeResourceHandler extends ResourceHandlerWrapper implements Deactivatable { private static final String LIBRARY = "deltaspike"; private static final String LIBRARY_UNCOMPRESSED = "deltaspike-uncompressed"; private final ResourceHandler wrapped; private final String version; private final boolean activated; public DeltaSpikeResourceHandler(ResourceHandler resourceHandler) { super(); wrapped = resourceHandler; version = ClassUtils.getJarVersion(this.getClass()); activated = ClassDeactivationUtils.isActivated(this.getClass()); } @Override public Resource createResource(String resourceName, String libraryName) { Resource resource = wrapped.createResource(resourceName, libraryName); if (activated && resource != null && libraryName != null && LIBRARY.equals(libraryName)) { if (ProjectStageProducer.getInstance().getProjectStage() == ProjectStage.Development) { resource = wrapped.createResource(resourceName, LIBRARY_UNCOMPRESSED); } resource = new DeltaSpikeResource(resource, version); } return resource; } @Override public ResourceHandler getWrapped() { return wrapped; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/viewaccess/ViewAccessScopedAwareNavigationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.scope.viewaccess; import jakarta.faces.application.NavigationHandler; import jakarta.faces.context.FacesContext; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.impl.scope.DeltaSpikeContextExtension; import org.apache.deltaspike.core.impl.scope.viewaccess.ViewAccessContext; import org.apache.deltaspike.core.spi.activation.Deactivatable; public class ViewAccessScopedAwareNavigationHandler extends NavigationHandler implements Deactivatable { private final NavigationHandler navigationHandler; private volatile Boolean initialized; private DeltaSpikeContextExtension contextExtension; public ViewAccessScopedAwareNavigationHandler(NavigationHandler navigationHandler) { this.navigationHandler = navigationHandler; } @Override public void handleNavigation(FacesContext context, String fromAction, String outcome) { // remember viewId before navigation String viewId = null; if (context.getViewRoot() != null) { viewId = context.getViewRoot().getViewId(); } this.navigationHandler.handleNavigation(context, fromAction, outcome); if (viewId != null && context.isPostback() /*need for supporting view-actions correctly - see DELTASPIKE-795*/) { lazyInit(); ViewAccessContext viewAccessContext = contextExtension.getViewAccessScopedContext(); if (viewAccessContext != null) { viewAccessContext.onProcessingViewFinished(viewId); } } } private void lazyInit() { if (this.initialized == null) { init(); } } private synchronized void init() { // switch into paranoia mode if (this.initialized == null) { contextExtension = BeanProvider.getContextualReference(DeltaSpikeContextExtension.class, true); this.initialized = true; } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/scope/window/JsfWindowContextQuotaHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.scope.window; import org.apache.deltaspike.core.impl.scope.window.DefaultWindowContextQuotaHandler; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; import jakarta.annotation.PostConstruct; import jakarta.enterprise.inject.Specializes; import jakarta.inject.Inject; @Specializes public class JsfWindowContextQuotaHandler extends DefaultWindowContextQuotaHandler { @Inject private ClientWindowConfig clientWindowConfig; @Override @PostConstruct protected void init() { this.maxWindowContextCount = this.clientWindowConfig.getMaxWindowContextCount(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/SecurityAwareViewHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.security; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.util.SecurityUtils; import org.apache.deltaspike.security.api.authorization.ErrorViewAwareAccessDeniedException; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import jakarta.faces.application.ViewHandler; import jakarta.faces.application.ViewHandlerWrapper; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; public class SecurityAwareViewHandler extends ViewHandlerWrapper implements Deactivatable { public static final String PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED = SecurityAwareViewHandler.class.getName() + "#PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED"; protected final ViewHandler wrapped; private final boolean activated; private volatile Boolean securityModuleActivated; /** * Constructor for wrapping the given {@link ViewHandler} * * @param wrapped view-handler which should be wrapped */ public SecurityAwareViewHandler(ViewHandler wrapped) { this.wrapped = wrapped; this.activated = ClassDeactivationUtils.isActivated(getClass()); } @Override public ViewHandler getWrapped() { return this.wrapped; } @Override public UIViewRoot createView(FacesContext context, String viewId) { UIViewRoot result = this.wrapped.createView(context, viewId); if (!this.activated) { return result; } if (this.securityModuleActivated == null) { lazyInit(); } if (!this.securityModuleActivated) { return result; } UIViewRoot originalViewRoot = context.getViewRoot(); Map viewMap = null; if (originalViewRoot != null) { Map originalViewMap = originalViewRoot.getViewMap(false); if (originalViewMap != null && !originalViewMap.isEmpty()) { viewMap = new HashMap(); viewMap.putAll(originalViewMap); } } //workaround for PreDestroyViewMapEvent which would be caused by the security check deactivatePreDestroyViewMapEvent(context); //we have to use it as current view if an AccessDecisionVoter uses the JSF API to check access to the view-id context.setViewRoot(result); try { ViewRootAccessHandler viewRootAccessHandler = BeanProvider.getContextualReference(ViewRootAccessHandler.class); viewRootAccessHandler.checkAccessTo(result); } catch (ErrorViewAwareAccessDeniedException accessDeniedException) { ViewConfigResolver viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); ViewConfigDescriptor errorViewDescriptor = viewConfigResolver .getViewConfigDescriptor(accessDeniedException.getErrorView()); if (errorViewDescriptor != null && View.NavigationMode.REDIRECT == errorViewDescriptor.getMetaData(View.class).iterator().next().navigation() /*always available*/ && BeanProvider.getContextualReference(JsfModuleConfig.class) .isAlwaysUseNavigationHandlerOnSecurityViolation()) { SecurityUtils.tryToHandleSecurityViolation(accessDeniedException); } else { SecurityUtils.handleSecurityViolationWithoutNavigation(accessDeniedException); } if (errorViewDescriptor != null) { return this.wrapped.createView(context, errorViewDescriptor.getViewId()); } else { //only in case of GET requests, because an exception during POST requests leads to re-rendering //the previous page (including the error message) if (!context.isPostback() && context.getViewRoot() != null) { context.getViewRoot().setViewId(null); } } throw accessDeniedException; //security exception without error-view } finally { activatePreDestroyViewMapEvent(context); if (originalViewRoot != null) { context.setViewRoot(originalViewRoot); if (viewMap != null) { originalViewRoot.getViewMap().putAll(viewMap); } } } return result; } private synchronized void lazyInit() { if (this.securityModuleActivated != null) { return; } this.securityModuleActivated = BeanProvider.getContextualReference(EditableAccessDecisionVoterContext.class, true) != null; if (!this.securityModuleActivated) { Logger.getLogger(getClass().getName()) //it's the only case for which a logger is needed in this class .info("security-module-impl isn't used -> " + getClass().getName() + " gets deactivated"); } } private void deactivatePreDestroyViewMapEvent(FacesContext facesContext) { facesContext.getExternalContext().getRequestMap().put(PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED, Boolean.TRUE); } private void activatePreDestroyViewMapEvent(FacesContext facesContext) { facesContext.getExternalContext().getRequestMap().put(PRE_DESTROY_VIEW_MAP_EVENT_FILTER_ENABLED, Boolean.FALSE); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/security/ViewRootAccessHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.security; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.jsf.impl.util.SecurityUtils; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import jakarta.enterprise.context.RequestScoped; import jakarta.faces.component.UIViewRoot; import jakarta.inject.Inject; import java.util.ArrayList; import java.util.List; import java.util.Stack; @RequestScoped public class ViewRootAccessHandler { @Inject private ViewConfigResolver viewConfigResolver; private List checkedViewIds = new ArrayList(); public void checkAccessTo(UIViewRoot uiViewRoot) { if (uiViewRoot == null) { return; } String viewId = uiViewRoot.getViewId(); if (!checkView(viewId)) { return; } this.checkedViewIds.add(viewId); ConfigDescriptor configDescriptor = this.viewConfigResolver.getViewConfigDescriptor(viewId); //topmost nodes get checked first Stack configDescriptorStack = new Stack(); if (configDescriptor != null) { configDescriptorStack.push(configDescriptor); } List parentPathList = new ArrayList(); createPathList(viewId, parentPathList); ConfigDescriptor pathDescriptor; for (String path : parentPathList) { pathDescriptor = this.viewConfigResolver.getConfigDescriptor(path); if (pathDescriptor != null) { configDescriptorStack.push(pathDescriptor); } } EditableAccessDecisionVoterContext accessDecisionVoterContext = BeanProvider.getContextualReference(EditableAccessDecisionVoterContext.class, false); for (ConfigDescriptor currentConfigDescriptor : configDescriptorStack) { SecurityUtils.invokeVoters(accessDecisionVoterContext, currentConfigDescriptor); } } private void createPathList(String currentPath, List pathList) { if (!currentPath.contains("/")) { return; } String parentFolder = currentPath.substring(0, currentPath.lastIndexOf("/")); pathList.add(parentFolder + "/"); createPathList(parentFolder, pathList); } private boolean checkView(String viewId) { return viewId != null && !this.checkedViewIds.contains(viewId); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/token/DoubleSubmitAwarePhaseListener.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.token; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.jsf.api.listener.phase.JsfPhaseListener; import jakarta.faces.context.FacesContext; import jakarta.faces.event.PhaseEvent; import jakarta.faces.event.PhaseId; import jakarta.faces.event.PhaseListener; import jakarta.inject.Inject; import java.util.Map; //ignore jsf-ajax requests since they have to be queued according to the spec. //ignore get-requests since they >shouldn't< change the state (we couldn't support them at all) //post-requests don't get pipelined -> no need to sync. them per session //browser-window-handling is done implicitly (PostRequestTokenManager is window-scoped) @JsfPhaseListener(ordinal = 9000) public class DoubleSubmitAwarePhaseListener implements PhaseListener, Deactivatable { private static final long serialVersionUID = -4247051429332418226L; @Inject private PostRequestTokenManager postRequestTokenManager; @Override public void afterPhase(PhaseEvent event) { FacesContext facesContext = event.getFacesContext(); //only check full POST requests if (facesContext.isPostback() && !facesContext.getPartialViewContext().isAjaxRequest()) { String receivedPostRequestToken = facesContext.getExternalContext() .getRequestParameterMap().get(PostRequestTokenMarker.POST_REQUEST_TOKEN_KEY); if (receivedPostRequestToken == null) { receivedPostRequestToken = findPostRequestTokenWithPrefix(facesContext); } if (!this.postRequestTokenManager.isValidRequest(receivedPostRequestToken)) { facesContext.renderResponse(); } } } @Override public void beforePhase(PhaseEvent event) { //refresh the token in case of GET-requests to avoid that the token is re-used on the next page if (!event.getFacesContext().isPostback()) { this.postRequestTokenManager.createNewToken(); } } @Override public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } protected String findPostRequestTokenWithPrefix(FacesContext facesContext) { for (Map.Entry parameterEntry : facesContext.getExternalContext().getRequestParameterMap().entrySet()) { if (parameterEntry.getKey().endsWith(PostRequestTokenMarker.POST_REQUEST_TOKEN_WITH_PREFIX_KEY) || parameterEntry.getKey().endsWith(PostRequestTokenMarker.POST_REQUEST_TOKEN_WITH_MANUAL_PREFIX_KEY)) { return parameterEntry.getValue(); } } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/token/PostRequestTokenManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.token; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import jakarta.inject.Inject; import jakarta.inject.Named; import java.io.Serializable; import java.util.UUID; @WindowScoped @Named("dsPostRequestToken") public class PostRequestTokenManager implements Serializable { private static final long serialVersionUID = 5387627547198129897L; private volatile String currentToken; private boolean allowPostRequestWithoutDoubleSubmitPrevention = true; protected PostRequestTokenManager() { } @Inject public PostRequestTokenManager(JsfModuleConfig config) { this.allowPostRequestWithoutDoubleSubmitPrevention = config.isAllowPostRequestWithoutDoubleSubmitPrevention(); } public void createNewToken() { this.currentToken = UUID.randomUUID().toString().replace("-", ""); } public synchronized boolean isValidRequest(String token) { if (token == null) { return this.allowPostRequestWithoutDoubleSubmitPrevention; } String previousToken = this.currentToken; createNewToken(); return token.equals(previousToken); } public String getCurrentToken() { return this.currentToken; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/token/PostRequestTokenMarker.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.token; public interface PostRequestTokenMarker { String POST_REQUEST_TOKEN_KEY = "dsprt"; String POST_REQUEST_TOKEN_WITH_PREFIX_KEY = ":" + POST_REQUEST_TOKEN_KEY; String POST_REQUEST_TOKEN_WITH_MANUAL_PREFIX_KEY = "_" + POST_REQUEST_TOKEN_KEY; } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ClientWindowHelper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.FacesException; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import jakarta.faces.lifecycle.ClientWindow; import jakarta.faces.render.ResponseStateManager; import jakarta.servlet.http.HttpServletResponse; import org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @Vetoed public abstract class ClientWindowHelper { private static final Logger LOG = Logger.getLogger(ClientWindowHelper.class.getName()); private static final String INITIAL_REDIRECT_WINDOW_ID = ClientWindowHelper.class.getName() + ".INITIAL_REDIRECT_WINDOW_ID"; public abstract class RequestParameters { public static final String REQUEST_TOKEN = "dsrid"; } public abstract class Cookies { public static final String REQUEST_WINDOW_ID_PREFIX = "dsrwid-"; } public static String constructRequestUrl(FacesContext facesContext, ExternalContext externalContext) { String url = externalContext.getRequestContextPath() + externalContext.getRequestServletPath(); if (externalContext.getRequestPathInfo() != null) { url += externalContext.getRequestPathInfo(); } url = JsfUtils.addRequestParameters(externalContext, url, true); // always remove jfwid to force adding new jfwid as JSF impl otherwise just ignores it url = JsfUtils.removeUrlParameter(url, ResponseStateManager.CLIENT_WINDOW_URL_PARAM); // TODO currently this is broken in Mojarra and will be fixed in 4.0.6 // url = externalContext.encodeRedirectURL(url, null); // let's reuse the logic from MyFaces instead HttpServletResponse servletResponse = (HttpServletResponse) externalContext.getResponse(); url = servletResponse.encodeRedirectURL(encodeURL(url, facesContext, servletResponse.getCharacterEncoding())); return url; } // copied from MyFaces private static String encodeURL(String baseUrl, FacesContext facesContext, String encoding) { if (baseUrl == null) { throw new NullPointerException("baseUrl is null"); } String fragment = null; String queryString = null; Map> paramMap = null; //extract any URL fragment int index = baseUrl.indexOf('#'); if (index != -1) { fragment = baseUrl.substring(index + 1); baseUrl = baseUrl.substring(0, index); } //extract the current query string and add the params to the paramMap index = baseUrl.indexOf('?'); if (index != -1) { queryString = baseUrl.substring(index + 1); baseUrl = baseUrl.substring(0, index); String[] nameValuePairs = queryString.split("&"); for (int i = 0; i < nameValuePairs.length; i++) { String[] currentPair = nameValuePairs[i].split("="); String currentName = currentPair[0]; if (paramMap == null) { paramMap = new HashMap<>(5, 1f); } List values = paramMap.get(currentName); if (values == null) { values = new ArrayList<>(1); paramMap.put(currentName, values); } try { values.add(currentPair.length > 1 ? URLDecoder.decode(currentPair[1], encoding) : ""); } catch (UnsupportedEncodingException e) { //shouldn't ever get here throw new UnsupportedOperationException("Encoding type=" + encoding + " not supported", e); } } } ClientWindow window = facesContext.getExternalContext().getClientWindow(); if (window != null && window.isClientWindowRenderModeEnabled(facesContext)) { if (paramMap == null) { paramMap = new HashMap<>(5, 1f); } if (!paramMap.containsKey(ResponseStateManager.CLIENT_WINDOW_URL_PARAM)) { paramMap.put(ResponseStateManager.CLIENT_WINDOW_URL_PARAM, Arrays.asList(window.getId())); } Map additionalQueryURLParameters = window.getQueryURLParameters(facesContext); if (additionalQueryURLParameters != null) { for (Map.Entry entry : additionalQueryURLParameters.entrySet()) { paramMap.put(entry.getKey(), Arrays.asList(entry.getValue())); } } } boolean hasParams = paramMap != null && !paramMap.isEmpty(); if (!hasParams && fragment == null) { return baseUrl; } // start building the new URL StringBuilder newUrl = new StringBuilder(baseUrl.length() + 10); newUrl.append(baseUrl); //now add the updated param list onto the url if (hasParams) { boolean isFirstPair = true; for (Map.Entry> pair : paramMap.entrySet()) { for (int i = 0; i < pair.getValue().size(); i++) { String value = pair.getValue().get(i); if (!isFirstPair) { newUrl.append('&'); } else { newUrl.append('?'); isFirstPair = false; } newUrl.append(pair.getKey()); newUrl.append('='); if (value != null) { try { newUrl.append(URLEncoder.encode(value, encoding)); } catch (UnsupportedEncodingException e) { //shouldn't ever get here throw new UnsupportedOperationException("Encoding type=" + encoding + " not supported", e); } } } } } //add the fragment back on (if any) if (fragment != null) { newUrl.append('#'); newUrl.append(fragment); } return newUrl.toString(); } /** * Handles the initial redirect for the LAZY mode, if no windowId is available in the current request URL. * * @param facesContext the {@link FacesContext} * @param newWindowId the new windowId */ public static void handleInitialRedirect(FacesContext facesContext, String newWindowId) { // store the new windowId as context attribute to prevent infinite loops // #sendRedirect will append the windowId (from ClientWindow#getWindowId again) to the redirectUrl facesContext.getAttributes().put(INITIAL_REDIRECT_WINDOW_ID, newWindowId); ExternalContext externalContext = facesContext.getExternalContext(); String url = constructRequestUrl(facesContext, externalContext); // remember the initial redirect windowId till the next request - see #729 addRequestWindowIdCookie(facesContext, newWindowId, newWindowId); try { externalContext.redirect(url); } catch (IOException e) { throw new FacesException("Could not send initial redirect!", e); } } public static boolean isInitialRedirect(FacesContext facesContext) { return facesContext.getAttributes().containsKey(INITIAL_REDIRECT_WINDOW_ID); } public static String getInitialRedirectWindowId(FacesContext facesContext) { return (String) facesContext.getAttributes().get(INITIAL_REDIRECT_WINDOW_ID); } public static void addRequestWindowIdCookie(FacesContext context, String requestToken, String windowId) { /* Sadly doesn't work due to SameSite is not allowed on Java cookies ^^ Map properties = new HashMap(); properties.put("path", "/"); properties.put("maxAge", 30); context.getExternalContext().addResponseCookie( Cookies.REQUEST_WINDOW_ID_PREFIX + requestToken, windowId, properties); */ context.getExternalContext().addResponseHeader("Set-Cookie", Cookies.REQUEST_WINDOW_ID_PREFIX + requestToken + "=" + windowId + "; path=/; maxAge=30; SameSite=Strict"); } public static Object getRequestWindowIdCookie(FacesContext context, String requestToken) { Map cookieMap = context.getExternalContext().getRequestCookieMap(); if (cookieMap.containsKey(Cookies.REQUEST_WINDOW_ID_PREFIX + requestToken)) { return cookieMap.get(Cookies.REQUEST_WINDOW_ID_PREFIX + requestToken); } return null; } public static int getMaxWindowIdLength() { int result = JsfBaseConfig.ScopeCustomization.WindowRestriction.ID_MAX_LENGTH; if (result > JsfBaseConfig.ScopeCustomization.WindowRestriction.ID_MAX_LENGTH_DEFAULT) { if (LOG.isLoggable(Level.WARNING)) { LOG.warning("ATTENTION: if you change this value to be significant longer than 10, " + "you can introduce a security issue in WindowIdHtmlRenderer. " + "If you increase it because window.name contains a value already, " + "please revisit that usage or " + "create shorter unique ids since they just need to be unique within the user-session."); } } return result; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/JsfUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.impl.listener.phase.WindowMetaData; import org.apache.deltaspike.jsf.impl.message.FacesMessageEntry; import jakarta.el.ELException; import jakarta.enterprise.context.ContextNotActiveException; import jakarta.faces.FacesException; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; import org.apache.deltaspike.core.util.StringUtils; public abstract class JsfUtils { private static final String SB_ADD_PARAMETER = "SB:" + JsfUtils.class + "#addParameter"; public static T getValueOfExpression(String expression, Class targetType) { FacesContext facesContext = FacesContext.getCurrentInstance(); return facesContext.getApplication().evaluateExpressionGet(facesContext, expression, targetType); } public static String getValueOfExpressionAsString(String expression) { Object result = getValueOfExpression(expression, Object.class); return result != null ? result.toString() : "null"; } public static Set getViewConfigPageParameters() { ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); Set result = new HashSet<>(); if (externalContext == null || //detection of early config for different mojarra versions externalContext.getRequestParameterValuesMap() == null || externalContext.getRequest() == null) { return result; } NavigationParameterContext navigationParameterContext = BeanProvider.getContextualReference(NavigationParameterContext.class); for (Map.Entry entry : navigationParameterContext.getPageParameters().entrySet()) { //TODO add multi-value support result.add(new RequestParameter(entry.getKey(), new String[]{entry.getValue()})); } return result; } /** * Adds the current page-parameters to the given url * * @param externalContext current external-context * @param url current url * @param encodeValues flag which indicates if parameter values should be encoded or not * @return url with request-parameters */ public static String addPageParameters(ExternalContext externalContext, String url, boolean encodeValues) { StringBuilder finalUrl = new StringBuilder(url); boolean existingParameters = url.contains("?"); for (RequestParameter requestParam : getViewConfigPageParameters()) { String key = requestParam.getKey(); for (String parameterValue : requestParam.getValues()) { if (!url.contains(key + "=" + parameterValue) && !url.contains(key + "=" + encodeUrlParameterValue(parameterValue, externalContext))) { if (!existingParameters) { finalUrl.append("?"); existingParameters = true; } else { finalUrl.append("&"); } appendUrlParameter(finalUrl, key, parameterValue, encodeValues, externalContext); } } } return finalUrl.toString(); } /** * Adds a paramter to the given url. * * @param externalContext current external-context * @param url current url * @param encodeValues flag which indicates if parameter values should be encoded or not * @param name the paramter name * @param value the paramter value * @return url with appended parameter */ public static String addParameter(ExternalContext externalContext, String url, boolean encodeValues, String name, String value) { // don't append if already available if (url.contains(name + "=" + value) || url.contains(name + "=" + encodeUrlParameterValue(value, externalContext))) { return url; } StringBuilder finalUrl = SharedStringBuilder.get(SB_ADD_PARAMETER); finalUrl.append(url); if (url.contains("?")) { finalUrl.append("&"); } else { finalUrl.append("?"); } appendUrlParameter(finalUrl, name, value, encodeValues, externalContext); return finalUrl.toString(); } /** * Adds the current request-parameters to the given url * * @param externalContext current external-context * @param url current url * @param encodeValues flag which indicates if parameter values should be encoded or not * @return url with request-parameters */ public static String addRequestParameters(ExternalContext externalContext, String url, boolean encodeValues) { if (externalContext.getRequestParameterValuesMap().isEmpty()) { return url; } StringBuilder finalUrl = new StringBuilder(url); boolean existingParameters = url.contains("?"); for (Map.Entry entry : externalContext.getRequestParameterValuesMap().entrySet()) { for (String value : entry.getValue()) { if (!url.contains(entry.getKey() + "=" + value) && !url.contains(entry.getKey() + "=" + encodeUrlParameterValue(value, externalContext))) { if (StringUtils.isEmpty(entry.getKey()) && StringUtils.isEmpty(value)) { continue; } if (!existingParameters) { finalUrl.append("?"); existingParameters = true; } else { finalUrl.append("&"); } appendUrlParameter(finalUrl, entry.getKey(), value, encodeValues, externalContext); } } } return finalUrl.toString(); } protected static void appendUrlParameter(StringBuilder url, String name, String value, boolean encode, ExternalContext externalContext) { if (encode) { url.append(encodeUrlParameterValue(name, externalContext)); } else { url.append(name); } url.append("="); if (encode) { url.append(encodeUrlParameterValue(value, externalContext)); } else { url.append(value); } } public static String removeUrlParameter(String url, String name) { if (url == null || !url.contains(name) || (!url.contains("?") && !url.contains("&"))) { return url; } String[] array = url.split("\\?"); String params = Arrays.asList(array[1].split("&")) .stream() .filter(item -> !item.split("=")[0].equalsIgnoreCase(name) && !"".equals(item.split("=")[1])) .collect(Collectors.joining("&")); if (params == null || params.isBlank()) { return array[0]; } return String.join("?", array[0], params); } /** * Encodes the given value using URLEncoder.encode() with the charset returned * from ExternalContext.getResponseCharacterEncoding(). * This is exactly how the ExternalContext impl encodes URL parameter values. * * @param value value which should be encoded * @param externalContext current external-context * @return encoded value */ public static String encodeUrlParameterValue(String value, ExternalContext externalContext) { // copied from MyFaces ServletExternalContextImpl.encodeURL() try { return URLEncoder.encode(value, externalContext.getResponseCharacterEncoding()); } catch (UnsupportedEncodingException e) { throw new UnsupportedOperationException("Encoding type=" + externalContext.getResponseCharacterEncoding() + " not supported", e); } } public static ViewConfigResolver getViewConfigResolver() { return BeanProvider.getContextualReference(ViewConfigResolver.class); } public static void saveFacesMessages(ExternalContext externalContext) { JsfModuleConfig jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); if (!jsfModuleConfig.isAlwaysKeepMessages()) { return; } try { WindowMetaData windowMetaData = BeanProvider.getContextualReference(WindowMetaData.class); Map requestMap = externalContext.getRequestMap(); @SuppressWarnings({ "unchecked" }) List facesMessageEntryList = (List)requestMap.get(FacesMessageEntry.class.getName()); if (facesMessageEntryList == null) { facesMessageEntryList = new CopyOnWriteArrayList(); } windowMetaData.setFacesMessageEntryList(facesMessageEntryList); } catch (ContextNotActiveException e) { //TODO log it in case of project-stage development //we can't handle it correctly -> delegate to the jsf-api (which has some restrictions esp. before v2.2) FacesContext.getCurrentInstance().getExternalContext().getFlash().setKeepMessages(true); } } public static void tryToRestoreMessages(FacesContext facesContext) { JsfModuleConfig jsfModuleConfig = BeanProvider.getContextualReference(JsfModuleConfig.class); if (!jsfModuleConfig.isAlwaysKeepMessages()) { return; } try { WindowMetaData windowMetaData = BeanProvider.getContextualReference(WindowMetaData.class); @SuppressWarnings({ "unchecked" }) List facesMessageEntryList = windowMetaData.getFacesMessageEntryList(); List originalMessageList = new ArrayList<>(facesContext.getMessageList()); if (facesMessageEntryList != null) { for (FacesMessageEntry messageEntry : facesMessageEntryList) { if (isNewMessage(originalMessageList, messageEntry.getFacesMessage())) { facesContext.addMessage(messageEntry.getComponentId(), messageEntry.getFacesMessage()); } } facesMessageEntryList.clear(); } } catch (ContextNotActiveException e) { //TODO discuss how we handle it } } public static Throwable getRootCause(Throwable throwable) { while ((ELException.class.isInstance(throwable) || FacesException.class.isInstance(throwable) || InvocationTargetException.class.isInstance(throwable)) && throwable.getCause() != null) { throwable = throwable.getCause(); } return throwable; } public static boolean isNewMessage(List facesMessages, FacesMessage messageToCheck) { for (FacesMessage facesMessage : facesMessages) { if ((facesMessage.getSummary() != null && facesMessage.getSummary().equals(messageToCheck.getSummary()) || facesMessage.getSummary() == null && messageToCheck.getSummary() == null) && (facesMessage.getDetail() != null && facesMessage.getDetail().equals(messageToCheck.getDetail()) || facesMessage.getDetail() == null && messageToCheck.getDetail() == null)) { return false; } } return true; } public static void logWrongModuleUsage(String name) { Logger.getLogger(name).log( Level.WARNING, "You are using the JSF module for JSF 2.0/2.1 with JSF 2.2+ which " + "might cause issues in your application in different areas. Please upgrade " + "org.apache.deltaspike.modules:deltaspike-jsf-module-impl-ee6 to " + "org.apache.deltaspike.modules:deltaspike-jsf-module-impl"); } public static void addStaticNavigationParameter( NavigationParameterContext navigationParameterContext, String key, String value) { Map existingParameters = navigationParameterContext.getPageParameters(); String existingValue = existingParameters.get(key); if (existingValue != null && value != null) //support null for special cases to reset an entry { return; } navigationParameterContext.addPageParameter(key, value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/RequestParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import java.util.Arrays; import java.util.List; public class RequestParameter { private final String key; private final String[] values; /** * Constructor for creating a parameter for the given key and values * @param key current key * @param values current values */ RequestParameter(String key, String[] values) { this.key = key; this.values = values; } /** * Key of the parameter * @return current key */ public String getKey() { return key; } /** * Exposes the values of the parameter as list * @return values of the parameter */ public List getValueList() { return Arrays.asList(this.values); } /** * Exposes the values of the parameter as array * @return values of the parameter */ public String[] getValues() { return values; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/SecurityUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import org.apache.deltaspike.security.api.authorization.AccessDecisionState; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.api.authorization.ErrorViewAwareAccessDeniedException; import org.apache.deltaspike.security.api.authorization.Secured; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import org.apache.deltaspike.security.spi.authorization.SecurityViolationHandler; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; import java.lang.annotation.Annotation; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @Vetoed public abstract class SecurityUtils { public static void invokeVoters(EditableAccessDecisionVoterContext accessDecisionVoterContext, ConfigDescriptor viewConfigDescriptor) { if (viewConfigDescriptor == null) { return; } List securedMetaData = viewConfigDescriptor.getMetaData(Secured.class); if (securedMetaData.isEmpty()) { return; } accessDecisionVoterContext.addMetaData(ViewConfig.class.getName(), viewConfigDescriptor.getConfigClass()); for (Annotation viewMetaData : viewConfigDescriptor.getMetaData()) { if (!viewMetaData.annotationType().equals(Secured.class)) { accessDecisionVoterContext.addMetaData(viewMetaData.annotationType().getName(), viewMetaData); } } Secured.Descriptor securedDescriptor = viewConfigDescriptor .getExecutableCallbackDescriptor(Secured.class, Secured.Descriptor.class); AccessDecisionState voterState = AccessDecisionState.VOTE_IN_PROGRESS; try { accessDecisionVoterContext.setState(voterState); List> violations = securedDescriptor.execute(accessDecisionVoterContext); Set allViolations = createViolationResult(violations); if (!allViolations.isEmpty()) { voterState = AccessDecisionState.VIOLATION_FOUND; for (SecurityViolation violation : allViolations) { accessDecisionVoterContext.addViolation(violation); } Class errorView = securedMetaData.iterator().next().errorView(); throw new ErrorViewAwareAccessDeniedException(allViolations, errorView); } } finally { if (AccessDecisionState.VOTE_IN_PROGRESS.equals(voterState)) { voterState = AccessDecisionState.NO_VIOLATION_FOUND; } accessDecisionVoterContext.setState(voterState); } } private static Set createViolationResult(List> violations) { if (violations == null || violations.isEmpty()) { return Collections.emptySet(); } Set result = new HashSet(); for (Set securityViolationSet : violations) { result.addAll(securityViolationSet); } return result; } /** * Processes a security violation without triggering the navigation to the error page * * @param exception current exception */ public static void handleSecurityViolationWithoutNavigation(RuntimeException exception) { tryToHandleSecurityViolation(exception, false); } /** * Processes a security violation including the navigation to the error page * * @param exception current exception */ public static void tryToHandleSecurityViolation(RuntimeException exception) { tryToHandleSecurityViolation(exception, true); } private static void tryToHandleSecurityViolation(RuntimeException runtimeException, boolean allowNavigation) { ErrorViewAwareAccessDeniedException exception = extractException(runtimeException); if (exception == null) { throw runtimeException; } Class errorView = null; Class inlineErrorView = exception.getErrorView(); if (inlineErrorView != null && !DefaultErrorView.class.getName().equals(inlineErrorView.getName())) { errorView = inlineErrorView; } if (errorView == null) { ViewConfigResolver viewConfigResolver = BeanProvider.getContextualReference(ViewConfigResolver.class); ViewConfigDescriptor errorPageDescriptor = viewConfigResolver.getDefaultErrorViewConfigDescriptor(); if (errorPageDescriptor != null) { errorView = errorPageDescriptor.getConfigClass(); } } if (errorView == null && allowNavigation) { throw exception; } processApplicationSecurityException(exception, errorView, allowNavigation); } private static ErrorViewAwareAccessDeniedException extractException(Throwable exception) { if (exception == null) { return null; } if (exception instanceof ErrorViewAwareAccessDeniedException) { return (ErrorViewAwareAccessDeniedException) exception; } return extractException(exception.getCause()); } private static void processApplicationSecurityException(AccessDeniedException exception, Class errorView, boolean allowNavigation) { SecurityViolationHandler securityViolationHandler = BeanProvider.getContextualReference(SecurityViolationHandler.class, true); if (securityViolationHandler != null) { //optional (custom handler) - allows to handle custom implementations of SecurityViolation securityViolationHandler.processSecurityViolations(exception.getViolations()); } else { addViolationsAsMessage(exception.getViolations()); } if (allowNavigation) { BeanProvider.getContextualReference(ViewNavigationHandler.class).navigateTo(errorView); } } private static void addViolationsAsMessage(Set violations) { String message; for (SecurityViolation violation : violations) { //TODO discuss it (with CODI handling such messages was easier) message = violation.getReason(); if (!isMessageAddedAlready(message)) { FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, message); FacesContext.getCurrentInstance().addMessage(null, facesMessage); } } } private static boolean isMessageAddedAlready(String message) { FacesContext facesContext = FacesContext.getCurrentInstance(); if (facesContext == null || message == null) { return false; } List existingMessages = facesContext.getMessageList(); if (existingMessages == null) { return false; } for (FacesMessage facesMessage : existingMessages) { if (message.equals(facesMessage.getSummary())) { return true; } } return false; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/SharedStringBuilder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import jakarta.enterprise.inject.Vetoed; import jakarta.faces.context.FacesContext; @Vetoed public abstract class SharedStringBuilder { /** * Get a shared {@link StringBuilder} instance. * * @param context The {@link FacesContext} * @param key The unique key per use case. * @return The shared {@link StringBuilder} instance */ public static StringBuilder get(FacesContext context, String key) { StringBuilder builder = (StringBuilder) context.getAttributes().get(key); if (builder == null) { builder = new StringBuilder(); context.getAttributes().put(key, builder); } else { builder.setLength(0); } return builder; } /** * Get a shared {@link StringBuilder} instance. * * @param key The unique key per use case. * @return The shared {@link StringBuilder} instance */ public static StringBuilder get(String key) { return get(FacesContext.getCurrentInstance(), key); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewConfigUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; public abstract class ViewConfigUtils { public static boolean isFolderConfig(Class configClass) { return configClass != null && ( (ViewConfig.class.isAssignableFrom(configClass) && Modifier.isAbstract(configClass.getModifiers()) || Modifier.isInterface(configClass.getModifiers()) ) || configClass.isAnnotationPresent(Folder.class)); } //TODO public static List toNodeList(Class nodeClass) { List treePath = new ArrayList(); while (nodeClass != null) { treePath.add(0, nodeClass); nodeClass = nodeClass.getEnclosingClass(); } return treePath; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/util/ViewControllerUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.util; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import org.apache.deltaspike.core.api.config.view.metadata.SimpleCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import java.lang.annotation.Annotation; public abstract class ViewControllerUtils { public static void executeViewControllerCallback(ViewConfigDescriptor viewDefinitionEntry, Class callbackType) { if (viewDefinitionEntry == null) { return; } SimpleCallbackDescriptor initViewCallbackDescriptor = viewDefinitionEntry.getExecutableCallbackDescriptor( ViewControllerRef.class, callbackType, SimpleCallbackDescriptor.class); if (initViewCallbackDescriptor != null) { initViewCallbackDescriptor.execute(); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/java/org/apache/deltaspike/jsf/impl/view/DeltaSpikeViewHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.jsf.impl.view; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.jsf.impl.security.SecurityAwareViewHandler; import jakarta.faces.application.ViewHandler; import jakarta.faces.application.ViewHandlerWrapper; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; /** * Aggregates all {@link ViewHandler} implementations provided by DeltaSpike */ public class DeltaSpikeViewHandler extends ViewHandlerWrapper implements Deactivatable { protected final ViewHandler wrapped; private volatile Boolean initialized; private ViewHandler securityAwareViewHandler; /** * Constructor for wrapping the given {@link ViewHandler} * * @param wrapped view-handler which should be wrapped */ public DeltaSpikeViewHandler(ViewHandler wrapped) { this.wrapped = wrapped; } //allows custom implementations to override the SecurityAwareViewHandler protected ViewHandler createSecurityAwareViewHandler() { return new SecurityAwareViewHandler(this.wrapped); } @Override public UIViewRoot createView(FacesContext facesContext, String viewId) { lazyInit(); if (this.securityAwareViewHandler == null) { return this.wrapped.createView(facesContext, viewId); } return this.securityAwareViewHandler.createView(facesContext, viewId); } @Override public ViewHandler getWrapped() { return this.wrapped; } private void lazyInit() { if (this.initialized == null) { init(); } } private synchronized void init() { // switch into paranoia mode if (this.initialized == null) { if (ClassDeactivationUtils.isActivated(getClass())) { this.securityAwareViewHandler = createSecurityAwareViewHandler(); } else { this.securityAwareViewHandler = null; } this.initialized = true; } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/deltaspike.taglib.xml ================================================ http://deltaspike.apache.org/jsf windowId org.apache.deltaspike.WindowIdHolder org.apache.deltaspike.WindowIdHolder preventDoubleSubmit org.apache.deltaspike.PostRequestTokenHolder org.apache.deltaspike.PostRequestTokenHolder ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/faces-config.xml ================================================ apache_deltaspike org.apache.deltaspike.jsf.impl.listener.phase.DeltaSpikePhaseListener org.apache.deltaspike.jsf.impl.view.DeltaSpikeViewHandler org.apache.deltaspike.jsf.impl.listener.action.DeltaSpikeActionListener org.apache.deltaspike.jsf.impl.resource.DeltaSpikeResourceHandler org.apache.deltaspike.jsf.impl.listener.system.JsfSystemEventBroadcaster jakarta.faces.event.ExceptionQueuedEvent org.apache.deltaspike.jsf.impl.listener.system.JsfSystemEventBroadcaster jakarta.faces.event.PostConstructApplicationEvent org.apache.deltaspike.jsf.impl.listener.system.JsfSystemEventBroadcaster jakarta.faces.event.PreDestroyApplicationEvent org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeLifecycleFactoryWrapper org.apache.deltaspike.jsf.impl.listener.request.DeltaSpikeFacesContextFactory ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/resources/deltaspike/windowhandler.js ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ window.dswh = window.dswh || { DEBUG_MODE : false, TEMP_WINDOW_NAME : 'tempWindowId', MANAGED_WINDOW_NAME_PREFIX : 'ds-', initialized: false, windowId : null, clientWindowRenderMode : null, maxWindowIdLength : 10, cfg : null, init : function(windowId, clientWindowRenderMode, maxWindowIdLength, cfg) { if (dswh.initialized === true) { return; } dswh.initialized = true; dswh.utils.log('------- DeltaSpike windowhandler.js -------'); dswh.utils.log('--- #init(\'' + windowId + '\', \'' + clientWindowRenderMode + '\',' + maxWindowIdLength + ',' + dswh.utils.stringify(cfg) + ')'); dswh.utils.log('window.name: ' + window.name); this.windowId = windowId; this.clientWindowRenderMode = clientWindowRenderMode; this.maxWindowIdLength = maxWindowIdLength; if (cfg) { this.cfg = cfg; } else { this.cfg = {}; } var targetStrategy = this.strategy[clientWindowRenderMode]; if (targetStrategy) { dswh.utils.log('--- #validate'); targetStrategy.validate(); // early init // this is required if e.g. the onload attr is defined on the body tag and our onload handler won't be called // ATTENTION: the ds:windowId component must be placed as last body tag dswh.utils.log('--- #init(false)'); targetStrategy.init(false); // JSF ajax callback if (window.faces) { faces.ajax.addOnEvent(function(event) { if (event.status === "success") { dswh.utils.log('--- #init(true)'); targetStrategy.init(true); } }); } // PF ajax callback if (window.$ && window.PrimeFaces) { $(document).on('pfAjaxComplete', function () { dswh.utils.log('--- #init(true)'); targetStrategy.init(true); }); } // init via onload // just as fallback if ds:windowId is not placed at last body tag var oldWindowOnLoad = window.onload; window.onload = function(evt) { try { (oldWindowOnLoad) ? oldWindowOnLoad(evt) : null; } finally { dswh.utils.log('--- #init(false)'); targetStrategy.init(false); } }; } }, strategy : { 'CLIENTWINDOW' : { validate : function() { this.cleanupCookies(); this.assertWindowId(); }, init : function(ajax) { this.overwriteLinkOnClickEvents(); this.overwriteButtonOnClickEvents(); }, assertWindowId : function() { dswh.utils.log('--- #assertWindowId'); // ensure that windowIds get checked even if no windowhandler.html is used if (!dswh.utils.isWindowNameDefined() || !dswh.utils.isManagedWindowName()) { dswh.utils.log('window name not defined or unmanaged - request new windowId'); dswh.utils.requestNewWindowId(); } }, overwriteLinkOnClickEvents : function() { var tokenizedRedirectEnabled = dswh.cfg.tokenizedRedirect; var storeWindowTreeEnabled = dswh.utils.isHtml5() && dswh.cfg.storeWindowTreeOnLinkClick; dswh.utils.log('--- #overwriteLinkOnClickEvents'); dswh.utils.log('tokenizedRedirect: ' + dswh.cfg.tokenizedRedirect); dswh.utils.log('storeWindowTreeOnLinkClick: ' + dswh.cfg.storeWindowTreeOnLinkClick); if (tokenizedRedirectEnabled || storeWindowTreeEnabled) { var links = document.getElementsByTagName("a"); for (var i = 0; i < links.length; i++) { var link = links[i]; var target = link.getAttribute('target'); if (dswh.strategy.CLIENTWINDOW.isHrefDefined(link) === true && (!target || target === '_self')) { if (!link.onclick) { link.onclick = function(evt) { // IE handling added evt = evt || window.event; // skip open in new tab if (!evt.ctrlKey) { if (storeWindowTreeEnabled) { dswh.strategy.CLIENTWINDOW.storeWindowTree(); } if (tokenizedRedirectEnabled) { dswh.strategy.CLIENTWINDOW.tokenizedRedirect(this); return false; } return true; } }; } else { // prevent double decoration if (!("" + link.onclick).match(".*storeWindowTree().*")) { //the function wrapper is important otherwise the //last onclick handler would be assigned to oldonclick (function storeEvent() { var oldonclick = link.onclick; link.onclick = function(evt) { // IE handling added evt = evt || window.event; var proceed = oldonclick.bind(this)(evt); if (typeof proceed === 'undefined' || proceed === true) { // skip open in new tab if (!evt.ctrlKey) { if (storeWindowTreeEnabled) { dswh.strategy.CLIENTWINDOW.storeWindowTree(); } if (tokenizedRedirectEnabled) { dswh.strategy.CLIENTWINDOW.tokenizedRedirect(this); return false; } } } return proceed; }; })(); } } } } } }, overwriteButtonOnClickEvents : function() { var storeWindowTreeEnabled = dswh.utils.isHtml5() && dswh.cfg.storeWindowTreeOnButtonClick; dswh.utils.log('--- #overwriteButtonOnClickEvents'); dswh.utils.log('storeWindowTreeOnButtonClick: ' + dswh.cfg.storeWindowTreeOnButtonClick); if (storeWindowTreeEnabled) { var inputs = document.getElementsByTagName("input"); for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; if (input.getAttribute("type") === "submit" || input.getAttribute("type") === "button") { if (!input.onclick) { input.onclick = function() { dswh.strategy.CLIENTWINDOW.storeWindowTree(); return true; }; } else { // prevent double decoration if (!("" + input.onclick).match(".*storeWindowTree().*")) { //the function wrapper is important otherwise the //last onclick handler would be assigned to oldonclick (function storeEvent() { var oldonclick = input.onclick; input.onclick = function(evt) { //ie handling added evt = evt || window.event; dswh.strategy.CLIENTWINDOW.storeWindowTree(); return oldonclick.bind(this)(evt); }; })(); } } } } } }, isHrefDefined : function(link) { var href = link.getAttribute("href"); if (!href || href === null) { return false; } // trim href = href.replace(/^\s+|\s+$/g, ''); if (href === '') { return false; } if (href.indexOf('#') === 0) { return false; } if (href.lastIndexOf('javascript:', 0) === 0) { return false; } return true; }, tokenizedRedirect : function(link) { dswh.utils.log('--- #tokenizedRedirect'); var requestToken = dswh.utils.generateNewRequestToken(); dswh.utils.storeCookie('dsrwid-' + requestToken, dswh.windowId, 3); window.location = dswh.utils.setUrlParam(link.href, 'dsrid', requestToken); }, /** * store the current body in the html5 localstorage */ storeWindowTree : function() { dswh.utils.log('--- #storeWindowTree'); // first we store all CSS we also need on the intermediate page var headNodes = document.getElementsByTagName("head")[0].childNodes; var oldSS = new Array(); var j = 0; for (var i = 0; i < headNodes.length; i++) { var tagName = headNodes[i].tagName; if (tagName && dswh.utils.equalsIgnoreCase(tagName, "link") && dswh.utils.equalsIgnoreCase(headNodes[i].getAttribute("type"), "text/css")) { // sort out media="print" and stuff var media = headNodes[i].getAttribute("media"); if (!media || dswh.utils.equalsIgnoreCase(media, "all") || dswh.utils.equalsIgnoreCase(media, 'screen')) { oldSS[j++] = headNodes[i].getAttribute("href"); } } } localStorage.setItem(window.name + '_css', dswh.utils.stringify(oldSS)); var body = document.getElementsByTagName("body")[0]; localStorage.setItem(window.name + '_body', body.innerHTML); var attributes = {}; for (var i = 0; i < body.attributes.length; i++) { var attribute = body.attributes[i]; attributes[attribute.name] = attribute.value; } localStorage.setItem(window.name + '_bodyAttributes', dswh.utils.stringify(attributes)); var scrollTop = (window.pageYOffset || document.documentElement.scrollTop) - (document.documentElement.clientTop || 0); localStorage.setItem(window.name + '_scrollTop', scrollTop); var scrollLeft = (window.pageXOffset || document.documentElement.scrollLeft) - (document.documentElement.clientLeft || 0); localStorage.setItem(window.name + '_scrollLeft', scrollLeft); }, cleanupCookies : function() { dswh.utils.log('--- #cleanupCookies'); var dsrid = dswh.utils.getUrlParameter(window.location.href, 'dsrid'); if (dsrid) { dswh.utils.expireCookie('dsrwid-' + dsrid); } } }, 'LAZY' : { validate : function() { this.cleanupCookies(); this.assertWindowId(); }, init : function(ajax) { }, assertWindowId : function() { var jfwid = dswh.utils.getUrlParameter(window.location.href, 'jfwid'); dswh.utils.log('--- #assertWindowId'); dswh.utils.log('jfwid: ' + jfwid); // window name is defined -> existing tab if (dswh.utils.isWindowNameDefined()) { // is the current window name a already managed by DS? if (dswh.utils.isManagedWindowName()) { var windowId = dswh.utils.getWindowIdFromWindowName(); // we triggered the windowId recreation last request if (windowId === dswh.TEMP_WINDOW_NAME) { // enabled initial redirect // -> use the new windowId from the url if (jfwid) { dswh.utils.log('assign window name from request parameter'); dswh.utils.setWindowIdAsWindowName(jfwid); } // disabled initial redirect // -> use the new windowId from the rendered config as no url param is available else { dswh.utils.log('assign window name from server windowId'); dswh.utils.setWindowIdAsWindowName(dswh.windowId); } } // security check like on the server side else if (windowId.length > dswh.maxWindowIdLength) { dswh.utils.log('window id from window name exeeds maxWindowIdLength - request new windowId'); dswh.utils.requestNewWindowId(); } // window name doesn't match requested windowId // -> redirect to the same view with current windowId from the window name else if (windowId !== jfwid) { dswh.utils.log('reload url with window name'); window.location = dswh.utils.setUrlParam(window.location.href, 'jfwid', windowId); } } else { dswh.utils.log('window name is unmanaged - request new windowId'); dswh.utils.requestNewWindowId(); } } // window name is undefined -> "open in new tab/window" was used else { // url param available? if (jfwid) { // initial redirect // -> the windowId is valid - we don't need to a second request if (dswh.cfg.initialRedirectWindowId && jfwid === dswh.cfg.initialRedirectWindowId) { dswh.utils.log('assign window name from initialRedirectWindowId'); dswh.utils.setWindowIdAsWindowName(dswh.cfg.initialRedirectWindowId); } // != initial redirect // -> request a new windowId to avoid multiple tabs with the same windowId else { dswh.utils.log('request new windowId'); dswh.utils.requestNewWindowId(); } } // as no url parameter is available, the request is a new tab with disabled initial redirect // -> just use the windowId from the renderer else if (dswh.windowId) { dswh.utils.log('assign window name from server windowId'); dswh.utils.setWindowIdAsWindowName(dswh.windowId); } } }, cleanupCookies : function() { dswh.utils.log('--- #cleanupCookies'); var jfwid = dswh.utils.getUrlParameter(window.location.href, 'jfwid'); if (jfwid) { dswh.utils.expireCookie('dsrwid-' + jfwid); } } } }, utils : { findRootWindow: function() { var w = window; while(w.frameElement) { var parent = w.parent; if (parent === undefined) { break; } w = parent; }; return w; }, isWindowNameDefined : function() { var w = dswh.utils.findRootWindow(); return w.name && w.name.length > 0; }, isManagedWindowName : function() { var w = dswh.utils.findRootWindow(); if (!w.name) { return false; } return w.name.indexOf(dswh.MANAGED_WINDOW_NAME_PREFIX) === 0; }, getWindowIdFromWindowName : function() { return dswh.utils.findRootWindow().name.substring(dswh.MANAGED_WINDOW_NAME_PREFIX.length); }, setWindowIdAsWindowName : function(windowId) { dswh.utils.findRootWindow().name = dswh.MANAGED_WINDOW_NAME_PREFIX + windowId; }, requestNewWindowId : function() { // set temp window name to remember the current state dswh.utils.setWindowIdAsWindowName(dswh.TEMP_WINDOW_NAME); // we remove the jfwid if available and redirect to the same url again to create a new windowId window.location = dswh.utils.setUrlParam(window.location.href, 'jfwid', null); // set temp window name to remember the current state (again - sometimes required for IE!?) dswh.utils.setWindowIdAsWindowName(dswh.TEMP_WINDOW_NAME); }, isHtml5 : function() { try { return !!localStorage.getItem; } catch(e) { return false; } }, stringify : function(someArray) { // some browsers don't understand JSON - guess which one ... :( if (JSON) { return JSON.stringify(someArray); } return someArray.join("|||"); }, unstringify : function(serialized) { if (JSON) { return JSON.parse(serialized); } return serialized.split("|||"); }, equalsIgnoreCase : function(source, destination) { //either both are not set or null if (!source && !destination) { return true; } //source or dest is set while the other is not if (!source || !destination) return false; //in any other case we do a strong string comparison return source.toLowerCase() === destination.toLowerCase(); }, getUrlParameter : function(uri, name) { // create an anchor object with the uri and let the browser parse it var a = document.createElement('a'); a.href = uri; // check if a query string is available var queryString = a.search; if (queryString && queryString.length > 0) { // create an array of query parameters - substring(1) removes the ? at the beginning of the query var queryParameters = queryString.substring(1).split("&"); for (var i = 0; i < queryParameters.length; i++) { var queryParameter = queryParameters[i].split("="); if (queryParameter[0] === name) { return queryParameter.length > 1 ? decodeURIComponent(queryParameter[1]) : ""; } } } return null; }, setUrlParam : function(uri, parameterName, parameterValue) { var a = document.createElement('a'); a.href = uri; // set empty string as value if not defined or empty if (!parameterValue || parameterValue.replace(/^\s+|\s+$/g, '').length === 0) { parameterValue = ''; } // check if value is empty if (parameterValue.length === 0) { // both value and query string is empty (or doesn't contain the param), don't touch the url if (a.search.length === 0 || a.search.indexOf(parameterName + "=") === -1) { return a.href; } } // query string is empty, just append our new parameter if (a.search.length === 0) { a.search = '?' + encodeURIComponent(parameterName) + "=" + encodeURIComponent(parameterValue); return a.href; } var oldParameters = a.search.substring(1).split('&'); var newParameters = []; newParameters.push(parameterName + "=" + encodeURIComponent(parameterValue)); // loop old parameters, remove empty ones and remove the parameter with the same name as the new one for (var i = 0; i < oldParameters.length; i++) { var oldParameterPair = oldParameters[i]; if (oldParameterPair.length > 0) { var oldParameterName = oldParameterPair.split('=')[0]; var oldParameterValue = oldParameterPair.split('=')[1]; // don't add empty parameters again if (oldParameterValue && oldParameterValue.replace(/^\s+|\s+$/g, '').length > 0) { // skip the the old parameter if it's the same as the new parameter if (oldParameterName !== parameterName) { newParameters.push(oldParameterName + "=" + oldParameterValue); } } } } // join new parameters a.search = '?' + newParameters.join('&'); return a.href; }, expireCookie : function(cookieName) { var date = new Date(); date.setTime(date.getTime()-(10*24*60*60*1000)); // - 10 day var expires = ";max-age=0;expires=" + date.toGMTString(); document.cookie = cookieName + "=" + expires + "; path=/; SameSite=Strict"; }, generateNewRequestToken : function() { return "" + Math.floor(Math.random() * 999); }, generateNewWindowId : function() { return "" + Math.floor((Math.random() * (9999 - 1000)) + 1000); }, storeCookie : function(name, value, seconds) { var expiresDate = new Date(); expiresDate.setTime(expiresDate.getTime() + (seconds * 1000)); var expires = "; expires=" + expiresDate.toGMTString(); document.cookie = name + '=' + value + expires + "; path=/; SameSite=Strict"; }, log : function(message) { if (dswh.DEBUG_MODE === true) { console.log(message); } } } }; // required for IE8 if (!Function.prototype.bind) { Function.prototype.bind = function (oThis) { if (typeof this !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } var aArgs = Array.prototype.slice.call(arguments, 1), fToBind = this, fNOP = function () { }, fBound = function () { return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); }; fNOP.prototype = this.prototype; fBound.prototype = new fNOP(); return fBound; }; } ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/META-INF/web-fragment.xml ================================================ deltaspike_jsf_module org.apache.deltaspike.jsf.impl.config.view.ViewConfigPathValidator ================================================ FILE: deltaspike/modules/jsf/impl/src/main/resources/static/windowhandler.html ================================================ Loading...

Your browser does not support JavaScript.
Click here to continue without JavaScript.
================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/TestJsfModuleConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config; import org.apache.deltaspike.jsf.api.config.JsfModuleConfig; import org.apache.deltaspike.jsf.spi.scope.window.ClientWindowConfig; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Specializes; @Specializes @ApplicationScoped public class TestJsfModuleConfig extends JsfModuleConfig { private static final long serialVersionUID = -7188892423502607762L; @Override public ClientWindowConfig.ClientWindowRenderMode getDefaultWindowMode() { return ClientWindowConfig.ClientWindowRenderMode.LAZY; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc001/PageBean001.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc001; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import jakarta.enterprise.inject.Model; @Model class PageBean001 { private boolean called = false; @PreRenderView protected void preRenderViewCallbackMethod() { called = true; } public boolean getCalled() { return called; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc001/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; @ViewControllerRef(PageBean001.class) class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc001/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc001; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Method; import java.util.List; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); //TODO related to the discussion about #getInheritedMetaData (see TODOs in other use-cases) Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testSimpleViewConfigWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class)); Assert.assertEquals(PageBean001.class, viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class).getCallbackMethods().keySet().iterator().next()); Assert.assertEquals("preRenderViewCallbackMethod", ((List) viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class).getCallbackMethods().values().iterator().next()).iterator().next().getName()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc001/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc001; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-controller-uc001.war") .addPackage(PageBean001.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("controller/simplePageConfig.xhtml", "/simplePageConfig.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigation() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "simplePageConfig.xhtml").toString()); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("pageBean001Called")), "true").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc002/PageBean002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc002; import org.apache.deltaspike.core.api.config.view.controller.PostRenderView; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; @Named("pageBean") @RequestScoped class PageBean002 { private boolean called = false; @PostRenderView protected void postRenderViewCallbackMethod() { called = true; } public boolean getCalled() { return called; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc002/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; @ViewControllerRef(value = PageBean002.class, name = "pageBean" /*TODO*/) //e.g. in case of producers with different @Named(...) class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc002/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc002; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import org.apache.deltaspike.core.api.config.view.controller.PostRenderView; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Method; import java.util.List; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); //TODO related to the discussion about #getInheritedMetaData (see TODOs in other use-cases) Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testSimpleViewConfigWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PostRenderView.class)); Assert.assertEquals(PageBean002.class, viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PostRenderView.class).getCallbackMethods().keySet().iterator().next()); Assert.assertEquals("postRenderViewCallbackMethod", ((List) viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PostRenderView.class).getCallbackMethods().values().iterator().next()).iterator().next().getName()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc002/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc002; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-controller-uc002.war") .addPackage(PageBean002.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("controller/simplePageConfig.xhtml", "/simplePageConfig.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigation() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "simplePageConfig.xhtml").toString()); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("pageBean002Called")), "true").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc003/PageBean003.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc003; import org.apache.deltaspike.core.api.config.view.ViewRef; import org.apache.deltaspike.core.api.config.view.controller.InitView; import org.apache.deltaspike.core.api.config.view.controller.PreViewAction; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import jakarta.enterprise.inject.Model; @Model @ViewRef(config = SimplePageConfig.class) class PageBean003 { private boolean called = false; @InitView @PreViewAction protected void callbackMethod1() { called = true; } @PreRenderView protected void callbackMethod2() { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc003/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc003/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc003; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.api.config.view.controller.*; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Method; import java.util.List; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithViewControllerCallback1() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); this.viewConfigExtension.addIndirectlyInheritedMetaData(PageBean003.class); testMetaDataTree(); } @Test public void testSimpleMetaDataTreeWithViewControllerCallback2() { this.viewConfigExtension.addIndirectlyInheritedMetaData(PageBean003.class); this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); testMetaDataTree(); } private void testMetaDataTree() { ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(1, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testSimpleViewConfigWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); this.viewConfigExtension.addIndirectlyInheritedMetaData(PageBean003.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, InitView.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreViewAction.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class)); Assert.assertNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PostRenderView.class)); Assert.assertEquals(PageBean003.class, viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, InitView.class).getCallbackMethods().keySet().iterator().next()); Assert.assertEquals("callbackMethod1", ((List) viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, InitView.class).getCallbackMethods().values().iterator().next()).iterator().next().getName()); Assert.assertEquals(PageBean003.class, viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreViewAction.class).getCallbackMethods().keySet().iterator().next()); Assert.assertEquals("callbackMethod1", ((List) viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreViewAction.class).getCallbackMethods().values().iterator().next()).iterator().next().getName()); Assert.assertEquals(PageBean003.class, viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class).getCallbackMethods().keySet().iterator().next()); Assert.assertEquals("callbackMethod2", ((List) viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class).getCallbackMethods().values().iterator().next()).iterator().next().getName()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc003/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc003; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-controller-uc003.war") .addPackage(PageBean003.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("controller/simplePageConfig.xhtml", "/simplePageConfig.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigation() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "simplePageConfig.xhtml").toString()); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("pageBean003Called")), "true").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/PageBean004.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import jakarta.enterprise.inject.Model; @Model public class PageBean004 { @PreRenderView protected void preRenderViewCallbackMethod() { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; @ViewControllerRef(PageBean004.class) @TestSecured(SimpleTestAccessDecisionVoter.class) public class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/SimpleTestAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import java.util.HashSet; import java.util.Set; public class SimpleTestAccessDecisionVoter implements TestAccessDecisionVoter { @Override public Set checkPermission(String param1, String param2) { Set result = new HashSet(); result.add(param1); result.add(param2); return result; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/TestAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import java.util.Set; public interface TestAccessDecisionVoter { @DefaultCallback Set checkPermission(String param1, String param2); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/TestSecured.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ExecutableCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.List; import java.util.Set; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target( TYPE ) @Retention(RUNTIME) @Documented @ViewMetaData(preProcessor = TestSecured.AnnotationPreProcessor.class) public @interface TestSecured { Class[] value(); class AnnotationPreProcessor implements ConfigPreProcessor { //for a real implementation see e.g.: //org.apache.deltaspike.security.api.authorization.Secured //org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef @Override public TestSecured beforeAddToConfig(TestSecured metaData, ViewConfigNode viewConfigNode) { List descriptors = viewConfigNode.getCallbackDescriptors(TestSecured.class); if (descriptors.isEmpty()) //just for testing different constellations - usually not needed! { descriptors.add(new Descriptor(metaData.value(), DefaultCallback.class)); } return metaData; //no change needed } } //can be used from outside to get a typed result static class Descriptor extends ExecutableCallbackDescriptor> { public Descriptor(Class[] beanClasses, Class callbackMarker) { super(beanClasses, callbackMarker); } public List> execute(String param1, String param2) { return super.execute(param1, param2); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc004/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc004; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.core.api.config.view.controller.InitView; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.HashSet; /** * Tests for view-configs */ public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithViewControllerCallback() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(2, node.getMetaData().size()); Iterator metaDataIterator = node.getMetaData().iterator(); List> possibleMetaDataTypes = new ArrayList>(); possibleMetaDataTypes.add(ViewControllerRef.class); possibleMetaDataTypes.add(TestSecured.class); Class foundMetaData = metaDataIterator.next().annotationType(); possibleMetaDataTypes.remove(foundMetaData); foundMetaData = metaDataIterator.next().annotationType(); possibleMetaDataTypes.remove(foundMetaData); Assert.assertTrue(possibleMetaDataTypes.isEmpty()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); //TODO related to the discussion about #getInheritedMetaData (see TODOs in other use-cases) Assert.assertEquals(0, node.getCallbackDescriptors().size()); //get added directly before adding the meta-data } @Test public void testSimpleViewConfigWithCallbacks() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, InitView.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class)); } @Test public void testCallbackExecution() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); final SimpleTestAccessDecisionVoter testInstance = new SimpleTestAccessDecisionVoter(); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); //add it to avoid in-container test for this simple constellation - usually not needed! node.getCallbackDescriptors().put(TestSecured.class, new ArrayList() {{ add(new TestSecured.Descriptor(new Class[] {SimpleTestAccessDecisionVoter.class}, DefaultCallback.class) { @Override protected Object getTargetObject(Class targetType) { return testInstance; } }); }}); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class)); List /*return type of one callback*/> callbackResult = viewConfigDescriptor.getExecutableCallbackDescriptor(TestSecured.class, TestSecured.Descriptor.class) .execute("param1", "param2"); Assert.assertNotNull(callbackResult); Assert.assertEquals(1, callbackResult.size()); Assert.assertEquals(2, callbackResult.iterator().next().size()); Iterator resultIterator = callbackResult.iterator().next().iterator(); //the order in the result isn't guaranteed Set expectedValues = new HashSet(); expectedValues.add("param1"); expectedValues.add("param2"); while (resultIterator.hasNext()) { String currentValue = resultIterator.next(); if (!expectedValues.remove(currentValue)) { Assert.fail("value '" + currentValue + "' not found in the result"); } } Assert.assertTrue(expectedValues.isEmpty()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/PageBean005.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import jakarta.enterprise.inject.Model; @Model public class PageBean005 { @PreRenderView protected void preRenderViewCallbackMethod() { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; public interface Pages extends ViewConfig { @SecuredStereotype1 interface Secure extends Pages { @SecuredStereotype2 @ViewControllerRef(PageBean005.class) class Settings implements Secure { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/SecuredStereotype1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(TYPE) @ViewMetaData @Stereotype @TestSecured(SimpleTestAccessDecisionVoter1.class) public @interface SecuredStereotype1 { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/SecuredStereotype2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(TYPE) @ViewMetaData @Stereotype @TestSecured(SimpleTestAccessDecisionVoter2.class) public @interface SecuredStereotype2 { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/SimpleTestAccessDecisionVoter1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import java.util.HashSet; import java.util.Set; public class SimpleTestAccessDecisionVoter1 implements TestAccessDecisionVoter { @Override public Set checkPermission(String param1, String param2) { Set result = new HashSet(); result.add(param1); result.add(param2); result.add(getClass().getName()); return result; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/SimpleTestAccessDecisionVoter2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import java.util.HashSet; import java.util.Set; public class SimpleTestAccessDecisionVoter2 implements TestAccessDecisionVoter { @Override public Set checkPermission(String param1, String param2) { Set result = new HashSet(); result.add(param1); result.add(param2); result.add(getClass().getName()); return result; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/TestAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import java.util.Set; public interface TestAccessDecisionVoter { @DefaultCallback Set checkPermission(String param1, String param2); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/TestSecured.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.metadata.CallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import org.apache.deltaspike.core.api.config.view.metadata.ExecutableCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.List; import java.util.Set; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target( TYPE ) @Retention(RUNTIME) @Documented @ViewMetaData(preProcessor = TestSecured.AnnotationPreProcessor.class) public @interface TestSecured { Class[] value(); class AnnotationPreProcessor implements ConfigPreProcessor { //for a real implementation see e.g.: //org.apache.deltaspike.security.api.authorization.Secured //org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef @Override public TestSecured beforeAddToConfig(TestSecured metaData, ViewConfigNode viewConfigNode) { List descriptors = viewConfigNode.getCallbackDescriptors(TestSecured.class); if (descriptors.isEmpty()) //just for testing different constellations - usually not needed! { descriptors.add(new Descriptor(metaData.value(), DefaultCallback.class)); } return metaData; //no change needed } } //can be used from outside to get a typed result static class Descriptor extends ExecutableCallbackDescriptor> { public Descriptor(Class[] beanClasses, Class callbackMarker) { super(beanClasses, callbackMarker); } public List> execute(String param1, String param2) { return super.execute(param1, param2); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/controller/uc005/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.controller.uc005; import org.apache.deltaspike.core.api.config.view.controller.InitView; import org.apache.deltaspike.core.api.config.view.controller.PreRenderView; import org.apache.deltaspike.core.api.config.view.controller.ViewControllerRef; import org.apache.deltaspike.core.api.config.view.metadata.*; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; /** * Tests for view-configs */ public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTreeWithStereotypeViewMetaData() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.Settings.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Secure.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Iterator metaDataIterator = node.getMetaData().iterator(); List> possibleMetaDataTypes = new ArrayList>(); possibleMetaDataTypes.add(SecuredStereotype1.class); Class foundMetaData = metaDataIterator.next().annotationType(); possibleMetaDataTypes.remove(foundMetaData); Assert.assertTrue(possibleMetaDataTypes.isEmpty()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Secure.Settings.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNotNull(node.getParent().getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(2, node.getMetaData().size()); metaDataIterator = node.getMetaData().iterator(); possibleMetaDataTypes = new ArrayList>(); possibleMetaDataTypes.add(ViewControllerRef.class); possibleMetaDataTypes.add(SecuredStereotype2.class); foundMetaData = metaDataIterator.next().annotationType(); possibleMetaDataTypes.remove(foundMetaData); foundMetaData = metaDataIterator.next().annotationType(); possibleMetaDataTypes.remove(foundMetaData); Assert.assertTrue(possibleMetaDataTypes.isEmpty()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testBaseViewConfigWithStereotypeViewMetaData() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Secure.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getCallbackDescriptor(TestSecured.class)); Assert.assertNotNull(configDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods()); Assert.assertFalse(configDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods().isEmpty()); Assert.assertNotNull(configDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods().get(SimpleTestAccessDecisionVoter1.class)); } @Test public void testViewConfigWithStereotypeViewMetaData() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.Settings.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Secure.Settings.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, InitView.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(ViewControllerRef.class, PreRenderView.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class)); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods()); Assert.assertFalse(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods().isEmpty()); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class).getCallbackMethods().get(SimpleTestAccessDecisionVoter2.class)); } @Test public void testCallbackExecutionFolder() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.class); final SimpleTestAccessDecisionVoter1 testInstance1 = new SimpleTestAccessDecisionVoter1(); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Secure.class); //add it to avoid in-container test for this simple constellation - usually not needed! node.getCallbackDescriptors().put(TestSecured.class, new ArrayList() {{ add(new TestSecured.Descriptor(new Class[] {SimpleTestAccessDecisionVoter1.class}, DefaultCallback.class) { @Override protected Object getTargetObject(Class targetType) { return testInstance1; } }); }}); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Secure.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getCallbackDescriptor(TestSecured.class)); List /*return type of one callback*/> callbackResult = ((TestSecured.Descriptor)configDescriptor.getExecutableCallbackDescriptor(TestSecured.class, TestSecured.Descriptor.class)) .execute("param1", "param2"); Assert.assertNotNull(callbackResult); Assert.assertEquals(1, callbackResult.size()); Assert.assertEquals(3, callbackResult.iterator().next().size()); Iterator resultIterator = callbackResult.iterator().next().iterator(); //the order in the result isn't guaranteed Set expectedValues = new CopyOnWriteArraySet(); expectedValues.add("param1"); expectedValues.add("param2"); expectedValues.add(SimpleTestAccessDecisionVoter1.class.getName()); while (resultIterator.hasNext()) { String currentValue = resultIterator.next(); if (!expectedValues.remove(currentValue)) { Assert.fail("value '" + currentValue + "' not found in the result"); } } Assert.assertTrue(expectedValues.isEmpty()); } @Test public void testCallbackExecutionPage() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.class); this.viewConfigExtension.addPageDefinition(Pages.Secure.Settings.class); final SimpleTestAccessDecisionVoter2 testInstance2 = new SimpleTestAccessDecisionVoter2(); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Secure.Settings.class); //add it to avoid in-container test for this simple constellation - usually not needed! node.getCallbackDescriptors().put(TestSecured.class, new ArrayList() {{ add(new TestSecured.Descriptor(new Class[] {SimpleTestAccessDecisionVoter2.class}, DefaultCallback.class) { @Override protected Object getTargetObject(Class targetType) { return testInstance2; } }); }}); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Secure.Settings.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getCallbackDescriptor(TestSecured.class)); List /*return type of one callback*/> callbackResult = viewConfigDescriptor.getExecutableCallbackDescriptor(TestSecured.class, TestSecured.Descriptor.class) .execute("param1", "param2"); Assert.assertNotNull(callbackResult); Assert.assertEquals(1, callbackResult.size()); Assert.assertEquals(3, callbackResult.iterator().next().size()); Iterator resultIterator = callbackResult.iterator().next().iterator(); //the order in the result isn't guaranteed Set expectedValues = new HashSet(); expectedValues.add("param1"); expectedValues.add("param2"); expectedValues.add(SimpleTestAccessDecisionVoter2.class.getName()); while (resultIterator.hasNext()) { String currentValue = resultIterator.next(); if (!expectedValues.remove(currentValue)) { Assert.fail("value '" + currentValue + "' not found in the result"); } } Assert.assertTrue(expectedValues.isEmpty()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc001/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; @TestEntryPoint class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc001/TestEntryPoint.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc001; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ TYPE }) @Retention(RUNTIME) @Documented @ViewMetaData @interface TestEntryPoint { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc001/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc001; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithCustomMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(TestEntryPoint.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testSimpleViewConfigWithCustomMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(2, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(TestEntryPoint.class).size()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc002/CustomMetaData.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc002; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Custom meta-data */ //don't use @Inherited @Target(TYPE) @Retention(RUNTIME) @Documented @ViewMetaData @interface CustomMetaData { int value1(); //TODO discuss value aggregation for arrays int[] value2(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc002/PageBean002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model class PageBean002 { public Class actionMethod() { return Pages.Index.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc002/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; //TODO add test @CustomMetaData(value1 = 5, value2 = 10) interface Pages extends ViewConfig { //value1 will be overruled and value2 aggregated @CustomMetaData(value1 = 7, value2 = 14) class Index implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc003/CustomStaticQuota.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc003; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Custom meta-data */ //don't use @Inherited @Target({TYPE}) @Retention(RUNTIME) @Documented @ViewMetaData @interface CustomStaticQuota { int perDay(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc003/CustomUrlMapping.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc003; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Custom meta-data */ //don't use @Inherited @Target({TYPE}) @Retention(RUNTIME) @Documented @ViewMetaData @interface CustomUrlMapping { String value(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc003/PageBean003.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model class PageBean003 { public Class item() { return Pages.Public.Item.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc003/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; //TODO add tests @CustomStaticQuota(perDay = 10000) //only gets picked up via meta-data-inheritance interface Pages { interface Public extends ViewConfig, ViewQuota.PDF, ViewQuota.XML, ZIP { @CustomUrlMapping("/item/#{item}/") class Item implements Public { } } //folder - because it's of type ViewConfig interface Private extends ViewConfig { } //TODO discuss inheritance approach - currently meta-data from 'Pages' wouldn't get picked up interface ViewQuota //technically not(!) needed (see ZIP) - just for better grouping { //TODO @Matches(pattern = "*.xml") interface XML { } //TODO @Matches(pattern = "*.pdf") @CustomStaticQuota(perDay = 100) //overrule quota interface PDF { } } //TODO discuss inheritance approach - currently meta-data from 'Pages' wouldn't get picked up //TODO @Matches(pattern = "*.zip") interface ZIP { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc004/PageBean004.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model class PageBean004 { public Class item() { return Pages.Public.Index.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc004/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; //TODO add tests interface Pages { @TestFacesRedirect interface Public extends ViewConfig { class Index implements Public { } } @TestFacesRedirect @View(viewParams = INCLUDE) class Home implements ViewConfig { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc004/TestFacesRedirect.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc004; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; /** * Custom meta-data */ //don't use @Inherited @Target({TYPE}) @Retention(RUNTIME) @Documented @Stereotype @View(navigation = REDIRECT) @interface TestFacesRedirect { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc005/InvalidPageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.spi.config.view.ViewConfigRoot; @ViewConfigRoot(configDescriptorValidators = TestInvalidConfigDescriptorValidator.class) class InvalidPageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc005/TestInvalidConfigDescriptorValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc005; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.spi.config.view.ConfigDescriptorValidator; public class TestInvalidConfigDescriptorValidator implements ConfigDescriptorValidator { static boolean called; @Override public boolean isValid(ConfigDescriptor configDescriptor) { called = true; return false; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc005/TestValidConfigDescriptorValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc005; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.spi.config.view.ConfigDescriptorValidator; public class TestValidConfigDescriptorValidator implements ConfigDescriptorValidator { static boolean called; @Override public boolean isValid(ConfigDescriptor configDescriptor) { called = true; return true; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc005/ValidPageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.spi.config.view.ViewConfigRoot; @ViewConfigRoot(configDescriptorValidators = TestValidConfigDescriptorValidator.class) class ValidPageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc005/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc005; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testCustomConfigDescriptorValidatorInvalid() { this.viewConfigExtension.addPageDefinition(InvalidPageConfig.class); try { this.viewConfigResolverProducer.createViewConfigResolver(); } catch (IllegalStateException e) { Assert.assertTrue(TestInvalidConfigDescriptorValidator.called); Assert.assertTrue(e.getMessage().contains(InvalidPageConfig.class.getName())); return; } Assert.fail(); } @Test public void testCustomConfigDescriptorValidatorValid() { this.viewConfigExtension.addPageDefinition(ValidPageConfig.class); this.viewConfigResolverProducer.createViewConfigResolver(); Assert.assertTrue(TestValidConfigDescriptorValidator.called); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc006/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc006; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; interface Pages { interface Public extends ViewConfig { @View(viewParams = INCLUDE) class Index implements Public { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc006/TestConfigPreProcessor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc006; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.literal.ViewLiteral; public class TestConfigPreProcessor implements ConfigPreProcessor { @Override public View beforeAddToConfig(View metaData, ViewConfigNode viewConfigNode) { return new ViewLiteral("/test/", "view", "custom", View.NavigationMode.DEFAULT, View.ViewParameterMode.DEFAULT, View.DefaultBasePathBuilder.class, View.DefaultFileNameBuilder.class, View.DefaultExtensionBuilder.class); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc006/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc006; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.*; import java.util.ArrayList; import java.util.Collections; import java.util.Map; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; private static boolean active; @BeforeClass public static void init() { active = true; ConfigResolver.addConfigSources(new ArrayList() { { add(new ConfigSource() { @Override public int getOrdinal() { return Integer.MAX_VALUE; } @Override public Map getProperties() { return Collections.emptyMap(); } @Override public String getPropertyValue(String key) { if (active && View.ViewConfigPreProcessor.class.getName().equals(key)) { return TestConfigPreProcessor.class.getName(); } return null; } @Override public String getConfigName() { return "test-view-config"; } @Override public boolean isScannable() { return false; } }); } private static final long serialVersionUID = 3247551986947387154L; }); } @AfterClass public static void cleanup() { active = false; } @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTreeCustomViewConfigPreProcessor() { this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Public.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNotNull(node.getParent().getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.class, node.getMetaData().iterator().next().annotationType()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, ((View)node.getMetaData().iterator().next()).viewParams()); } @Test public void testViewConfigCustomViewConfigPreProcessor() { this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Public.Index.class); //changed by TestConfigPreProcessor Assert.assertEquals("/test/view.custom", viewConfigDescriptor.getViewId()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc007/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc007; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.spi.config.view.ViewConfigRoot; import org.apache.deltaspike.jsf.impl.config.view.DefaultViewConfigInheritanceStrategy; //just for testing root-node replacement in combination with a view-config @ViewConfigRoot(viewConfigInheritanceStrategy = DefaultViewConfigInheritanceStrategy.class) interface Pages extends ViewConfig { class Index implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc007/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc007; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTreeWithRandomOrder() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.class); //simulates random processing-order ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); } @Test public void testViewConfigWithRandomOrder() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.class); //simulates random processing-order ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertEquals("/pages/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc008/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc008; import org.apache.deltaspike.core.api.config.view.ViewConfig; interface Pages extends ViewConfig { class Index implements Pages { } @TestMenuEntry(pos = 1) interface Section1 extends Pages { @TestMenuEntry(pos = 1) class Content1 implements Section1 { } @TestMenuEntry(pos =2) class Content2 implements Section1 { } } @TestMenuEntry(pos = 2) interface Section2 extends Pages { @TestMenuEntry(pos = 1) class Content1 implements Section2 { } @TestMenuEntry(pos =2) class Content2 implements Section2 { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc008/TestMenuEntry.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc008; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @ViewMetaData @Target(TYPE) @Retention(RUNTIME) public @interface TestMenuEntry { int pos(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/custom/uc008/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.custom.uc008; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTree() { List> menuViewConfigClasses = new ArrayList<>(); menuViewConfigClasses.add(Pages.Section1.Content1.class); menuViewConfigClasses.add(Pages.Section1.Content2.class); menuViewConfigClasses.add(Pages.Section2.Content1.class); menuViewConfigClasses.add(Pages.Section2.Content2.class); this.viewConfigExtension.addPageDefinition(Pages.Index.class); for (Class menuViewConfigClass : menuViewConfigClasses) { this.viewConfigExtension.addPageDefinition(menuViewConfigClass); } ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); for (Class menuViewConfigClass : menuViewConfigClasses) { node = this.viewConfigExtension.findNode(menuViewConfigClass); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(TestMenuEntry.class, node.getMetaData().iterator().next().annotationType()); } } @Test public void testViewConfig() { List> menuViewConfigClasses = new ArrayList<>(); menuViewConfigClasses.add(Pages.Section1.Content1.class); menuViewConfigClasses.add(Pages.Section1.Content2.class); menuViewConfigClasses.add(Pages.Section2.Content1.class); menuViewConfigClasses.add(Pages.Section2.Content2.class); this.viewConfigExtension.addPageDefinition(Pages.Index.class); for (Class menuViewConfigClass : menuViewConfigClasses) { this.viewConfigExtension.addPageDefinition(menuViewConfigClass); } ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertTrue(viewConfigDescriptor.getMetaData(TestMenuEntry.class).isEmpty()); for (Class menuViewConfigClass : menuViewConfigClasses) { viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(menuViewConfigClass); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(TestMenuEntry.class).size()); Assert.assertTrue(viewConfigDescriptor.getMetaData(TestMenuEntry.class).iterator().next().pos() > 0); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/folder/uc001/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.folder.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; interface Pages { //folder (-only) meta-data would be here or at an interface interface AdminArea extends ViewConfig { //empty (intentionally) } @Folder interface VipArea { //empty (intentionally) } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/folder/uc001/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.folder.uc001; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testFolderOnlyMetaData() { this.viewConfigExtension.addPageDefinition(Pages.AdminArea.class); this.viewConfigExtension.addFolderDefinition(Pages.VipArea.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.AdminArea.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.VipArea.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(Folder.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc001/PageBean001.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model public class PageBean001 { public Class actionMethod() { return Pages.Index.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc001/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; //nesting only leads to the final path - in this case /pages/index.xhtml interface Pages { class Index implements ViewConfig { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc001/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc001; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-destination-uc001.war") .addPackage(Pages.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/home.xhtml", "/pages/home.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigationActionMethod() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb001ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("indexPage")), "You arrived at index page").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc002/PageBean002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc002; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model public class PageBean002 { public Class actionWithoutError() { return Pages.Overview.class; } public Class restrictedToPages() { return Pages.Home.class; } //navigates to /pages/customErrorPage.xhtml public Class actionWithError() { return DefaultErrorView.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc002/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc002; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; @View(navigation = REDIRECT) interface Pages extends ViewConfig { class Index implements Pages { } @View(viewParams = INCLUDE) class Overview implements Pages { } //'navigation' overruled @View(navigation = FORWARD) class Home implements Pages { } class CustomErrorPage extends DefaultErrorView { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc002/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc002; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-destination-uc002.war") .addPackage(Pages.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/home.xhtml", "/pages/home.xhtml") .addAsWebResource("navigation/pages/overview.xhtml", "/pages/overview.xhtml") .addAsWebResource("navigation/pages/customErrorPage.xhtml", "/pages/customErrorPage.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigationActionWithoutError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb002ActionWithoutError")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("overviewPage")), "You arrived at overview page").apply(driver)); // Was redirected ? Assert.assertTrue(driver.getCurrentUrl().contains("overview.xhtml")); } @Test @RunAsClient public void testNavigationActionWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb002ActionWithError")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("customErrorPage")), "This is a custom error page").apply(driver)); } @Test @RunAsClient public void testNavigationRestrictedToPages() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb002RestrictedToPages")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("homePage")), "You arrived at home page") .apply(driver)); // Was fowarded ? Assert.assertTrue(driver.getCurrentUrl().contains("origin.xhtml")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc003/PageBean003.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc003; import jakarta.enterprise.inject.Model; import org.apache.deltaspike.core.api.config.view.ViewConfig; @Model public class PageBean003 { public Class actionMethod() { return Pages.Index.class; } public Class actionMethod2() { return Pages.Overview.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc003/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; interface Pages extends ViewConfig { class Index implements Pages { } @View(name = "home") class Overview implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc003/PagesViolation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; interface PagesViolation extends ViewConfig { class Index implements PagesViolation { } @View(name = "index") class Overview implements PagesViolation { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc003/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc003; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testDuplicatedNavigationTargetsInMetaDataTree() { this.viewConfigExtension.addPageDefinition(PagesViolation.Index.class); this.viewConfigExtension.addPageDefinition(PagesViolation.Overview.class); ViewConfigNode node = this.viewConfigExtension.findNode(PagesViolation.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(PagesViolation.Overview.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test(expected = IllegalStateException.class) public void testDuplicatedNavigationTargetsDuringPageMetaDataTransformation() { this.viewConfigExtension.addPageDefinition(PagesViolation.Index.class); this.viewConfigExtension.addPageDefinition(PagesViolation.Overview.class); this.viewConfigResolverProducer.createViewConfigResolver(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc003/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc003; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-destination-uc003.war") .addClass(Pages.class) .addClass(ViewConfigTestDrone.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/home.xhtml", "/pages/home.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigationActionMethod() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb003ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("indexPage")), "You arrived at index page").apply(driver)); } @Test @RunAsClient public void testNavigationActionMethod2() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb003ActionMethod2")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("homePage")), "You arrived at home page").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc004/PageBean004.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc004; import jakarta.enterprise.inject.Model; import org.apache.deltaspike.core.api.config.view.ViewConfig; @Model public class PageBean004 { public Class actionMethod() { return Pages.Index.class; } public Class actionMethod2() { return Pages.Overview.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc004/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc004; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; interface Pages { class Index extends DefaultErrorView { } class Overview extends DefaultErrorView { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc004/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc004; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testDuplicatedDefaultErrorViewInMetaDataTree() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Overview.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Overview.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test(expected = IllegalStateException.class) public void testDuplicatedDefaultErrorViewDuringPageMetaDataTransformation() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Overview.class); this.viewConfigResolverProducer.createViewConfigResolver(); } @Test public void testDefaultErrorViewInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); Assert.assertNotNull(viewConfigResolver.getDefaultErrorViewConfigDescriptor()); Assert.assertEquals(Pages.Index.class, viewConfigResolver.getDefaultErrorViewConfigDescriptor().getConfigClass()); Assert.assertEquals(Pages.Index.class, viewConfigResolver.getViewConfigDescriptor(DefaultErrorView.class).getConfigClass()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc004/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc004; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-destination-uc004.war") .addPackage(Pages.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/overview.xhtml", "/pages/overview.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigationActionMethod() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb004ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("indexPage")), "You arrived at index page").apply(driver)); } @Test @RunAsClient public void testNavigationActionMethod2() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb004ActionMethod2")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("overviewPage")), "You arrived at overview page").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc005/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; interface Pages { interface Wizard1 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") class Step3 implements ViewConfig { } @View(basePath = "w1/") class Step4 implements ViewConfig { } @View(basePath = "/w1/") class Step5 implements ViewConfig { } @View(basePath = "./w1b/") class Step6 implements ViewConfig { } @View(basePath = "w1b") class Step7 implements ViewConfig { } } @View(basePath = "w2") //gets ignored because @Folder should be used instead interface Wizard2 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") class Step3 implements ViewConfig { } @View(basePath = "w2/") class Step4 implements ViewConfig { } @View(basePath = "/w2/") class Step5 implements ViewConfig { } @View(basePath = "./w2b/") class Step6 implements ViewConfig { } @View(basePath = "w2b") class Step7 implements ViewConfig { } } @View(basePath = "/w3") //gets ignored because @Folder should be used instead interface Wizard3 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } } @View(basePath = "./w4b") //gets ignored because @Folder should be used instead interface Wizard4 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } } @View(basePath = "w5/") //gets ignored because @Folder should be used instead interface Wizard5 { class Step1 implements ViewConfig { } } @View(basePath = "/w6/") //gets ignored because @Folder should be used instead interface Wizard6 { class Step1 implements ViewConfig { } } @View(basePath = "./w7b/") //gets ignored because @Folder should be used instead interface Wizard7 { class Step1 implements ViewConfig { } } @Folder(name = "w8/") interface Wizard8 { class Step1 implements ViewConfig { } } @Folder(name = "/w9/") interface Wizard9 { class Step1 implements ViewConfig { } } @Folder(name = "./w10a/") interface Wizard10 { class Step1 implements ViewConfig { } } @Folder(name = "w11/") interface Wizard11 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") class Step3 implements ViewConfig { } @View(basePath = "w11b/") class Step4 implements ViewConfig { } @View(basePath = "/w11b/") class Step5 implements ViewConfig { } @View(basePath = "./w11b/") class Step6 implements ViewConfig { } @View(basePath = "w11b") class Step7 implements ViewConfig { } } @Folder(name = "/w12/") interface Wizard12 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") class Step3 implements ViewConfig { } @View(basePath = "w12b/") class Step4 implements ViewConfig { } @View(basePath = "/w12b/") class Step5 implements ViewConfig { } @View(basePath = "./w12b/") class Step6 implements ViewConfig { } @View(basePath = "w12b") class Step7 implements ViewConfig { } } @Folder(name = "./w13a/") interface Wizard13 { @View(basePath = "") class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") class Step3 implements ViewConfig { } @View(basePath = "w13b/") class Step4 implements ViewConfig { } @View(basePath = "/w13b/") class Step5 implements ViewConfig { } @View(basePath = "./w13b/") class Step6 implements ViewConfig { } @View(basePath = "w13b") class Step7 implements ViewConfig { } } @Folder(name = "./") interface Wizard14 { @View(basePath = "") class Step1 implements ViewConfig { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc005/ViewConfigPathTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc005; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.Map; public class ViewConfigPathTest { private static boolean active; private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @BeforeClass public static void init() { active = true; ConfigResolver.addConfigSources(new ArrayList() { { add(new ConfigSource() { @Override public int getOrdinal() { return Integer.MAX_VALUE; } @Override public Map getProperties() { return Collections.emptyMap(); } @Override public String getPropertyValue(String key) { if (active && View.ViewConfigPreProcessor.class.getName().equals(key)) { return ViewConfigPreProcessorWithoutValidation.class.getName(); } return null; } @Override public String getConfigName() { return "test-view-config"; } @Override public boolean isScannable() { return false; } }); } private static final long serialVersionUID = 3247551986947387154L; }); } @AfterClass public static void cleanup() { active = false; } @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testNamesWizard1() { this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step2.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step3.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step4.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step5.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step6.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard1.Step7.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard1/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step3.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard1/step3.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step4.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard1/w1/step4.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step5.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w1/step5.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step6.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard1/w1b/step6.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard1.Step7.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard1/w1b/step7.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard2() { this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step2.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step3.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step4.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step5.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step6.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard2.Step7.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard2/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step3.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard2/step3.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step4.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard2/w2/step4.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step5.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w2/step5.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step6.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard2/w2b/step6.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard2.Step7.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard2/w2b/step7.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard3() { this.viewConfigExtension.addPageDefinition(Pages.Wizard3.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard3.Step2.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard3.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard3/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard3.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard4() { this.viewConfigExtension.addPageDefinition(Pages.Wizard4.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard4.Step2.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard4.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard4/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard4.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard5() { this.viewConfigExtension.addPageDefinition(Pages.Wizard5.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard5.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard5/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard6() { this.viewConfigExtension.addPageDefinition(Pages.Wizard6.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard6.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard6/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard7() { this.viewConfigExtension.addPageDefinition(Pages.Wizard7.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard7.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/wizard7/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard8() { this.viewConfigExtension.addPageDefinition(Pages.Wizard8.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard8.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w8/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard9() { this.viewConfigExtension.addPageDefinition(Pages.Wizard9.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard9.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w9/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard10() { this.viewConfigExtension.addPageDefinition(Pages.Wizard10.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard10.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w10a/step1.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard11() { this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step2.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step3.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step4.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step5.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step6.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard11.Step7.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w11/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step3.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w11/step3.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step4.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w11/w11b/step4.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step5.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w11b/step5.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step6.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w11/w11b/step6.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard11.Step7.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w11/w11b/step7.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard12() { this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step2.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step3.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step4.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step5.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step6.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard12.Step7.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step3.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12/step3.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step4.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12/w12b/step4.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step5.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12b/step5.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step6.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12/w12b/step6.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard12.Step7.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w12/w12b/step7.xhtml", viewConfigDescriptor.getViewId()); } @Test public void testNamesWizard13() { this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step1.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step2.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step3.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step4.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step5.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step6.class); this.viewConfigExtension.addPageDefinition(Pages.Wizard13.Step7.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor; viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step1.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w13a/step1.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step2.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/step2.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step3.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w13a/step3.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step4.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w13a/w13b/step4.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step5.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/w13b/step5.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step6.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w13a/w13b/step6.xhtml", viewConfigDescriptor.getViewId()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Wizard13.Step7.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/w13a/w13b/step7.xhtml", viewConfigDescriptor.getViewId()); } @Test(expected = IllegalStateException.class) public void testNamesWizard14() { this.viewConfigExtension.addPageDefinition(Pages.Wizard14.Step1.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); viewConfigResolver.getViewConfigDescriptor(Pages.Wizard14.Step1.class); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc005/ViewConfigPreProcessorWithoutValidation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc005; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; public class ViewConfigPreProcessorWithoutValidation extends View.ViewConfigPreProcessor { @Override protected void validateViewMetaData(View view, ViewConfigNode viewConfigNode) { //do nothing to check intentionally ignored basePath usages at folder-nodes } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc006/PageBean006.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc006; import jakarta.enterprise.inject.Model; import org.apache.deltaspike.core.api.config.view.ViewConfig; @Model public class PageBean006 { public Class actionMethod() { return Pages.Wizard1.Step1.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc006/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc006; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; interface Pages { @Folder(name = "wizard1") //valid usage interface Wizard1 { @View(basePath = "") class Step1 implements ViewConfig { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc006/PagesViolation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc006; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; interface PagesViolation { @View(basePath = "w1") //causes a violation because @Folder should be used instead interface Wizard1 { @View(basePath = "") class Start implements ViewConfig { } } @Folder(name = "w2") //valid usage interface Wizard2 { @View(basePath = "") class Start implements ViewConfig { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc006/ViewConfigBasePathValidationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc006; import junit.framework.Assert; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Before; import org.junit.Test; public class ViewConfigBasePathValidationTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testInvalidBasePathUsage() { this.viewConfigExtension.addPageDefinition(PagesViolation.Wizard1.Start.class); try { this.viewConfigResolverProducer.createViewConfigResolver(); } catch (IllegalStateException e) { if (!(e.getMessage().contains(View.class.getName()) && e.getMessage().contains(Folder.class.getName())&& e.getMessage().contains("#basePath"))) { Assert.fail("unexpected violation message found"); } return; } Assert.fail("violation not found"); } @Test public void testValidBasePathUsage() { this.viewConfigExtension.addPageDefinition(PagesViolation.Wizard2.Start.class); Assert.assertNotNull(this.viewConfigResolverProducer.createViewConfigResolver()); //won't cause an exception } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/destination/uc006/ViewConfigTestDrone.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.destination.uc006; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewConfigTestDrone { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "nav-destination-uc006.war") .addClass(Pages.class) .addClass(ViewConfigTestDrone.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/wizard1/step1.xhtml", "/wizard1/step1.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testNavigationActionMethod() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("destination:pb006ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("step1")), "You arrived at step1 page").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/event/uc001/PageBean002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.event.uc001; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Model; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.event.PreViewConfigNavigateEvent; import org.apache.deltaspike.test.jsf.impl.config.view.navigation.event.uc001.Pages.CustomErrorPage; @Model public class PageBean002 { public Class actionWithoutError() { return Pages.Overview.class; } public Class actionWithError() { return DefaultErrorView.class; } protected void onNavigation(@Observes PreViewConfigNavigateEvent navigateEvent) { //change the target dynamically instead of a static config of the DefaultErrorView if (navigateEvent.getToView().equals(CustomErrorPage.class)) { navigateEvent.navigateTo(Pages.Index.class); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/event/uc001/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.event.uc001; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; @View(navigation = REDIRECT) public interface Pages extends ViewConfig { class Index implements Pages { } @View(viewParams = INCLUDE) class Overview implements Pages { } //'navigation' overruled @View(navigation = FORWARD) class Home implements Pages { } class CustomErrorPage extends DefaultErrorView { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/event/uc001/PreViewConfigNavigateEventTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.event.uc001; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class PreViewConfigNavigateEventTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "nav-event-uc001.war") .addPackage(Pages.class.getPackage()) .addClass(PageBean002.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/home.xhtml", "/pages/home.xhtml") .addAsWebResource("navigation/pages/overview.xhtml", "/pages/overview.xhtml") .addAsWebResource("navigation/pages/customErrorPage.xhtml", "/pages/customErrorPage.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } @Test @RunAsClient public void testNavigationActionWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("event:pb002ActionWithError")); Assert.assertNotNull(button); button.click(); // Index Page is shown instead of DefaultErrorView because PreViewConfigNavigateEvent changed the navigation Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("indexPage")), "You arrived at index page") .apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/shared/TestClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.shared; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigPathValidator; public class TestClassDeactivator implements ClassDeactivator { private static final long serialVersionUID = -3403907272881821406L; @Override public Boolean isActivated(Class targetClass) { if (targetClass.equals(ViewConfigPathValidator.class)) { return Boolean.FALSE; } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc001/NoNavigationParameterWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc001; import junit.framework.Assert; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.shared.TestClassDeactivator; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.jsf.impl.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.net.URL; @RunWith(Arquillian.class) public class NoNavigationParameterWarFileTest { @Deployment public static WebArchive deploy() { String simpleName = NoNavigationParameterWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); URL fileUrl = NoNavigationParameterWarFileTest.class.getClassLoader() .getResource("navigationParameterTest/apache-deltaspike.properties"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addClass(TestClassDeactivator.class) .addPackage(NoNavigationParameterWarFileTest.class.getPackage()) .addAsResource(FileUtils.getFileForURL(fileUrl.toString()), DeltaSpikeTest.DELTASPIKE_PROPERTIES) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Inject private PageBean001 pageBean; @Inject private NavigationParameterContext navigationParameterContext; @Test public void noParameters() { Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); this.pageBean.actionMethod(); Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc001/PageBean001.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model public class PageBean001 { //no params public Class actionMethod() { return SimplePageConfig.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc001/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; public class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc002/PageBean002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import jakarta.enterprise.inject.Model; @Model public class PageBean002 { @NavigationParameter(key = "param1", value = "staticMarker") public Class actionMethod1() { return SimplePageConfig.class; } @NavigationParameter.List({ @NavigationParameter(key = "param1", value = "staticMarker1"), @NavigationParameter(key = "param2", value = "staticMarker2") }) public Class actionMethod2() { return SimplePageConfig.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc002/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; public class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc002/StaticNavigationParameterWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc002; import java.net.URL; import jakarta.inject.Inject; import junit.framework.Assert; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.shared.TestClassDeactivator; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.jsf.impl.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class StaticNavigationParameterWarFileTest { @Deployment public static WebArchive deploy() { String simpleName = StaticNavigationParameterWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); URL fileUrl = StaticNavigationParameterWarFileTest.class.getClassLoader() .getResource("navigationParameterTest/apache-deltaspike.properties"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addClass(TestClassDeactivator.class) .addPackage(StaticNavigationParameterWarFileTest.class.getPackage()) .addAsResource(FileUtils.getFileForURL(fileUrl.toString()), DeltaSpikeTest.DELTASPIKE_PROPERTIES) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Inject private PageBean002 pageBean; @Inject private NavigationParameterContext navigationParameterContext; @Test public void oneParameter() { Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); this.pageBean.actionMethod1(); Assert.assertEquals(1, this.navigationParameterContext.getPageParameters().size()); Assert.assertEquals("staticMarker", this.navigationParameterContext.getPageParameters().get("param1")); } @Test public void multipleParameters() { Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); this.pageBean.actionMethod2(); Assert.assertEquals(2, this.navigationParameterContext.getPageParameters().size()); Assert.assertEquals("staticMarker1", this.navigationParameterContext.getPageParameters().get("param1")); Assert.assertEquals("staticMarker2", this.navigationParameterContext.getPageParameters().get("param2")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc003/NavigationParameterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc003; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class NavigationParameterTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "nav-parameter-uc003.war") .addPackage(SimplePageConfig.class.getPackage()) .addClass(PageBean003.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/simplePageConfig.xhtml", "/simplePageConfig.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); return archive; } @Test @RunAsClient public void testNavigationActionWithParameter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("parameter:pb003ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("simplePageConfig")), "You arrived at simplePageConfig page") .apply(driver)); System.out.println(driver.getCurrentUrl()); Assert.assertTrue(driver.getCurrentUrl().contains("param1=0")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc003/PageBean003.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc003; import jakarta.enterprise.inject.Model; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; @Model public class PageBean003 { private int nextValue = 0; @NavigationParameter(key = "param1", value = "#{pageBean003.nextValue}") public Class actionMethod() { this.nextValue++; return SimplePageConfig.class; } public int getNextValue() { return nextValue; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc003/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.config.view.View.NavigationMode; import org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode; @View(navigation = NavigationMode.REDIRECT, viewParams = ViewParameterMode.INCLUDE) public class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc004/DynamicNavigationParameterWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc004; import junit.framework.Assert; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.shared.TestClassDeactivator; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.jsf.impl.util.FileUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import java.net.URL; @RunWith(Arquillian.class) public class DynamicNavigationParameterWarFileTest { @Deployment public static WebArchive deploy() { String simpleName = DynamicNavigationParameterWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); URL fileUrl = DynamicNavigationParameterWarFileTest.class.getClassLoader() .getResource("navigationParameterTest/apache-deltaspike.properties"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addClass(TestClassDeactivator.class) .addPackage(DynamicNavigationParameterWarFileTest.class.getPackage()) .addAsResource(FileUtils.getFileForURL(fileUrl.toString()), DeltaSpikeTest.DELTASPIKE_PROPERTIES) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Inject private PageBean004 pageBean; @Inject private NavigationParameterContext navigationParameterContext; @Test public void dynamicParameters() { Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); this.pageBean.actionMethod(); Assert.assertTrue(this.navigationParameterContext.getPageParameters().isEmpty()); this.pageBean.actionMethod(); Assert.assertEquals(1, this.navigationParameterContext.getPageParameters().size()); Assert.assertEquals("0", this.navigationParameterContext.getPageParameters().get("cv")); this.pageBean.actionMethod(); Assert.assertEquals(1, this.navigationParameterContext.getPageParameters().size()); Assert.assertEquals("1", this.navigationParameterContext.getPageParameters().get("cv")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc004/NavigationParameterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc004; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class NavigationParameterTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "nav-parameter-uc004-drone.war") .addPackage(SimplePageConfig.class.getPackage()) .addClass(PageBean004.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/simplePageConfig.xhtml", "/simplePageConfig.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } @Test @RunAsClient public void testNavigationActionWithParameter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); //first click driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("parameter:pb004ActionMethod")); button.click(); //second click driver.get(new URL(contextPath, "origin.xhtml").toString()); button = driver.findElement(By.id("parameter:pb004ActionMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("simplePageConfig")), "You arrived at simplePageConfig page") .apply(driver)); Assert.assertTrue(driver.getCurrentUrl().contains("cv=")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc004/PageBean004.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameterContext; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import java.io.Serializable; @Named @SessionScoped public class PageBean004 implements Serializable { private static final long serialVersionUID = -436742087379474804L; private int currentValue = -2; @Inject private NavigationParameterContext navigationParameterContext; public Class actionMethod() { currentValue++; if (currentValue >= 0) { this.navigationParameterContext.addPageParameter("cv", this.currentValue); } return SimplePageConfig.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc004/SimplePageConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.config.view.View.NavigationMode; import org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode; @View(navigation = NavigationMode.REDIRECT, viewParams = ViewParameterMode.INCLUDE) public class SimplePageConfig implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc005/NavigationParameterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc005; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class NavigationParameterTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "nav-parameter-uc005.war") .addPackage(Pages.class.getPackage()) .addClass(PageBean005.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/pages/index.xhtml", "/pages/index.xhtml") .addAsWebResource("navigation/pages/overview.xhtml", "/pages/overview.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } @Test @RunAsClient public void testNavigationActionOverview() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("parameter:pb005Overview")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("overviewPage")), "You arrived at overview page") .apply(driver)); System.out.println(driver.getCurrentUrl()); Assert.assertTrue(driver.getCurrentUrl().contains("param1=staticValue2")); Assert.assertTrue(driver.getCurrentUrl().contains("param2=aValue")); } @Test @RunAsClient public void testNavigationActionIndex() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("parameter:pb005Index")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("indexPage")), "You arrived at index page") .apply(driver)); System.out.println(driver.getCurrentUrl()); Assert.assertTrue(driver.getCurrentUrl().contains("param1=staticValue2")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc005/PageBean005.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model public class PageBean005 { private String currentValue = "aValue"; public Class index() { return Pages.Index.class; } public Class overview() { return Pages.Overview.class; } public String getCurrentValue() { return currentValue; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc005/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.navigation.NavigationParameter; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.api.config.view.View.NavigationMode; import org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode; @View(navigation = NavigationMode.REDIRECT, viewParams = ViewParameterMode.INCLUDE) public interface Pages extends ViewConfig { @NavigationParameter(key = "param1", value = "staticValue2") class Index implements Pages { } @NavigationParameter.List({ @NavigationParameter(key = "param1", value = "staticValue2"), @NavigationParameter(key = "param2", value = "#{pageBean005.currentValue}") }) class Overview implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc006/NavigationParameterTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc006; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class NavigationParameterTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "nav-parameter-uc006.war") .addPackage(PageBean006.class.getPackage()) .addClass(Pages.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("navigation/origin.xhtml", "/origin.xhtml") .addAsWebResource("navigation/pages/customErrorPage.xhtml", "/pages/customErrorPage.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } @Test @RunAsClient public void testNavigationActionWithParameter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "origin.xhtml").toString()); WebElement button = driver.findElement(By.id("parameter:pb006AnyMethod")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("customErrorPage")), "This is a custom error page") .apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc006/PageBean006.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc006; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.navigation.ViewNavigationHandler; import jakarta.enterprise.inject.Model; import jakarta.inject.Inject; @Model public class PageBean006 { @Inject private ViewNavigationHandler viewNavigationHandler; //faces-redirect=true will be added by the navigation handler public void anyMethod() { //navigates to the view which is configured as default error-view //(in this example via a redirect, because it's configured for PageConfigForRedirect) this.viewNavigationHandler.navigateTo(DefaultErrorView.class); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc006/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc006; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; @View(navigation = REDIRECT) public interface Pages extends ViewConfig { public class CustomErrorPage extends DefaultErrorView implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc007/PageBean007.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc007; import org.apache.deltaspike.core.api.config.view.ViewConfig; import jakarta.enterprise.inject.Model; @Model public class PageBean007 { //includeViewParams=true will be added by the navigation handler //TODO add test public Class actionMethod() { return ViewConfigForIncludeViewParams.class; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/parameter/uc007/ViewConfigForIncludeViewParams.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.uc007; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; @View(viewParams = INCLUDE) public class ViewConfigForIncludeViewParams implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc001/SimplePageConfig001.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc001; import org.apache.deltaspike.core.api.config.view.ViewConfig; class SimplePageConfig001 implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc001/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc001; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithoutMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig001.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig001.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testSimpleViewConfigWithOptionalPageMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig001.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig001.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/simplePageConfig001.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(SimplePageConfig001.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); //@View gets added autom. if it isn't provided in-/directly Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc002/SimplePageConfig002.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc002; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; @View class SimplePageConfig002 implements ViewConfig { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc002/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc002; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testSimpleMetaDataTreeWithMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig002.class); ViewConfigNode node = this.viewConfigExtension.findNode(SimplePageConfig002.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testSimpleViewConfigWithExplicitPageMetaData() { this.viewConfigExtension.addPageDefinition(SimplePageConfig002.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(SimplePageConfig002.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/simplePageConfig002.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(SimplePageConfig002.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc003/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc003; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; interface Pages { class Index implements ViewConfig { } @View class Home implements ViewConfig { } interface Admin extends ViewConfig { class Index implements Admin { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc003/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc003; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testNestedMetaDataTree() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View)node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testNestedViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals("/pages/", ((Folder)configDescriptor.getMetaData().iterator().next()).name()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals("/pages/admin/", ((Folder)configDescriptor.getMetaData().iterator().next()).name()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) viewConfigDescriptor.getMetaData().iterator().next()) .navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, (viewConfigDescriptor.getMetaData(View.class).iterator() .next()).viewParams()); Assert.assertEquals("index", (viewConfigDescriptor.getMetaData(View.class).iterator().next()).name()); Assert.assertEquals(View.Extension.XHTML, (viewConfigDescriptor.getMetaData(View.class).iterator().next()).extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/home.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) viewConfigDescriptor.getMetaData().iterator().next()) .navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, (viewConfigDescriptor.getMetaData(View.class).iterator().next()).viewParams()); Assert.assertEquals("home", (viewConfigDescriptor.getMetaData(View.class).iterator().next()).name()); Assert.assertEquals(View.Extension.XHTML, (viewConfigDescriptor.getMetaData(View.class).iterator().next()).extension()); ConfigDescriptor folderDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(folderDescriptor); Assert.assertEquals("/pages/admin/", folderDescriptor.getPath()); Assert.assertEquals(Pages.Admin.class, folderDescriptor.getConfigClass()); Assert.assertNotNull(folderDescriptor.getMetaData()); Assert.assertEquals(1, folderDescriptor.getMetaData().size()); Assert.assertEquals("/pages/admin/", ((Folder)folderDescriptor.getMetaData().iterator().next()).name()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) viewConfigDescriptor.getMetaData().iterator().next()) .navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, (viewConfigDescriptor.getMetaData(View.class).iterator().next()).viewParams()); Assert.assertEquals("index", (viewConfigDescriptor.getMetaData(View.class).iterator().next()).name()); Assert.assertEquals(View.Extension.XHTML, (viewConfigDescriptor.getMetaData(View.class).iterator().next()).extension()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc004/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc004; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.Extension.JSP; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; interface Pages { @View(name = "home", extension = JSP) class Index implements ViewConfig { } @View(navigation = REDIRECT, viewParams = INCLUDE) interface Admin extends ViewConfig { interface Statistics { @View class Index implements ViewConfig { } class Home implements Admin //inherit navigation = REDIRECT and viewParams = INCLUDE { } } class Index implements Admin //inherit navigation = REDIRECT and viewParams = INCLUDE { } @View(navigation = FORWARD) class Home implements Admin //inherit navigation = REDIRECT - but overruled and viewParams = INCLUDE { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc004/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc004; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test //only (all) real annotations are available here -> e.g. #getInheritedMetaData never returns a result here //currently #getInheritedMetaData doesn't get tested explicitly //the (merged) result gets exposed via the ViewConfigResolver //TODO discuss if #getInheritedMetaData should be tested as well by exposing the transformed tree for tests public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.class, node.getMetaData().iterator().next().annotationType()); Assert.assertEquals(View.NavigationMode.REDIRECT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("home", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals("jsp", ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); //not processed at this point - node was just added node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); //not processed at this point - node was just added node = this.viewConfigExtension.findNode(Pages.Admin.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); //not processed at this point - node was just added } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(1, configDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); //the following is correct because it's @View at the folder level: Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(View.class).iterator().next().basePath()); Assert.assertEquals("xhtml", configDescriptor.getMetaData(View.class).iterator().next().extension()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.Statistics.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.Statistics.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/statistics/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/home.jsp", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("jsp", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/home.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/home.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc005/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc005; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; @View(navigation = REDIRECT) interface Pages extends ViewConfig { //inherits navigation = REDIRECT class Index implements Pages { } interface Admin extends Pages { //inherits navigation = REDIRECT @View(viewParams = INCLUDE) interface Statistics extends Admin { //inherits navigation = REDIRECT and viewParams = INCLUDE @View class Index implements Statistics { } //inherits navigation = REDIRECT class Home implements Admin { } } //inherits navigation = REDIRECT @View class Index implements Admin { } //inherits but overrules navigation @View(navigation = FORWARD) class Home implements Admin { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc005/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc005; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test //only (all) real annotations are available here -> e.g. #getInheritedMetaData never returns a result here //currently #getInheritedMetaData doesn't get tested explicitly //the (merged) result gets exposed via the ViewConfigResolver //TODO discuss if #getInheritedMetaData should be tested as well by exposing the transformed tree for tests public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); //not processed at this point - node was just added } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals(View.Extension.XHTML, configDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(1, configDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); //the following is correct because it's @View at the folder level: Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(View.class).iterator().next().basePath()); Assert.assertEquals("xhtml", configDescriptor.getMetaData(View.class).iterator().next().extension()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.Statistics.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.Statistics.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/statistics/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(1, configDescriptor.getMetaData(View.class).size()); //TODO update uc004 with these lines Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); //the following is correct because it's @View at the folder level: Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(View.class).iterator().next().basePath()); Assert.assertEquals("xhtml", configDescriptor.getMetaData(View.class).iterator().next().extension()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/home.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/home.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc006/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc006; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.Extension.FACES; import static org.apache.deltaspike.jsf.api.config.view.View.Extension.JSF; import static org.apache.deltaspike.jsf.api.config.view.View.Extension.XHTML; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.FORWARD; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; @View(navigation = REDIRECT, extension = JSF) interface Pages extends ViewConfig { //inherits navigation = REDIRECT and extension = JSF class Index implements Pages { } //inherits navigation = REDIRECT and extension = JSF interface Admin extends Pages { //inherits navigation = REDIRECT @View(viewParams = INCLUDE, extension = FACES) interface Statistics extends Admin { //inherits navigation = REDIRECT and viewParams = INCLUDE and extension = FACES @View class Index implements Statistics { } //inherits navigation = REDIRECT and extension = JSF class Home implements Admin { } } //inherits navigation = REDIRECT @View(extension = XHTML) class Index implements Admin { } //inherits but overrules navigation and extension = JSF @View(navigation = FORWARD) class Home implements Admin { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc006/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc006; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test //only (all) real annotations are available here -> e.g. #getInheritedMetaData never returns a result here //currently #getInheritedMetaData doesn't get tested explicitly //the (merged) result gets exposed via the ViewConfigResolver //TODO discuss if #getInheritedMetaData should be tested as well by exposing the transformed tree for tests public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.JSF, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(2, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.FACES, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Statistics Assert.assertNotNull(node.getParent().getParent()); //Admin Assert.assertNotNull(node.getParent().getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.XHTML, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); //not processed at this point - node was just added } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Statistics.Home.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next() .navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals(View.Extension.JSF, configDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(1, configDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); //the following is correct because it's @View at the folder level: Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(View.class).iterator().next().basePath()); Assert.assertEquals("jsf", configDescriptor.getMetaData(View.class).iterator().next().extension()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.Statistics.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.Statistics.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(2, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/statistics/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); Assert.assertEquals(1, configDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, configDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, configDescriptor.getMetaData(View.class).iterator().next().viewParams()); //the following is correct because it's @View at the folder level: Assert.assertEquals("", configDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(View.class).iterator().next().basePath()); Assert.assertEquals("faces", configDescriptor.getMetaData(View.class).iterator().next().extension()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/index.jsf", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("jsf", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/index.faces", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("faces", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Statistics.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/statistics/home.jsf", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Statistics.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("jsf", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/home.jsf", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Home.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("home", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("jsf", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc007/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc007; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; interface Pages { @TestFacesRedirect interface Public extends ViewConfig { class Index implements Public { } } @TestFacesRedirect @View(viewParams = INCLUDE) class Home implements ViewConfig { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc007/TestFacesRedirect.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc007; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; /** * Custom meta-data */ //don't use @Inherited @Target({TYPE}) @Retention(RUNTIME) @Documented @Stereotype @View(navigation = REDIRECT) @interface TestFacesRedirect { } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc007/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc007; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.annotation.Annotation; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTreeWithStereotypeMetaData() { this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(2, node.getMetaData().size()); Assert.assertEquals(2, node.getMetaData().size()); boolean facesRedirectAnnotationFound = false; boolean viewAnnotationFound = false; for (Annotation metaData : node.getMetaData()) { if (TestFacesRedirect.class.isAssignableFrom(metaData.annotationType())) { facesRedirectAnnotationFound = true; } else if (View.class.isAssignableFrom(metaData.annotationType())) { viewAnnotationFound = true; } } Assert.assertTrue(facesRedirectAnnotationFound); Assert.assertTrue(viewAnnotationFound); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Public.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(TestFacesRedirect.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Public.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNotNull(node.getParent().getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testViewConfigWithStereotypeMetaData() { this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Public.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc008/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc008; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; @Folder interface Pages extends ViewConfig { @Folder interface Admin extends Pages { @View class Index implements Admin { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc008/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc008; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(".", ((Folder) node.getMetaData().iterator().next()).name()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(Folder.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/pages/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/pages/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/pages/admin/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc009/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc009; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; @Folder(name = "/") //there are multiple folders which should be grouped by the outermost interface interface Pages extends ViewConfig { //result: /index.xhtml class Index implements Pages { } //result: /admin interface Admin extends Pages { @View class Index implements Admin { } } //result: /public @Folder interface Public extends Pages { @View class Index implements Public { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc009/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc009; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Public.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Public.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Public Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(Folder.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Public.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Public Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.class); this.viewConfigExtension.addPageDefinition(Pages.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.class); this.viewConfigExtension.addPageDefinition(Pages.Admin.Index.class); this.viewConfigExtension.addPageDefinition(Pages.Public.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/admin/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Public.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Public.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/public/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Public.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/public/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Public.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/public/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc010/MyView.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc010; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.apache.deltaspike.jsf.api.config.view.View.NavigationMode.REDIRECT; /** * Custom meta-data */ @ViewMetaData //don't use @Inherited @Target({TYPE}) @Retention(RUNTIME) @Documented @Stereotype @View(navigation = REDIRECT) @interface MyView { String description(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc010/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc010; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.jsf.api.config.view.View; import static org.apache.deltaspike.jsf.api.config.view.View.ViewParameterMode.INCLUDE; interface Pages { @MyView(description = "public content") interface Public extends ViewConfig { class Index implements Public { } } @MyView(description = "landing page") @View(viewParams = INCLUDE) class Home implements ViewConfig { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc010/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc010; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.lang.annotation.Annotation; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataTreeWithStereotypeMetaData() { this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.Home.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(2, node.getMetaData().size()); Assert.assertEquals(2, node.getMetaData().size()); boolean facesRedirectAnnotationFound = false; boolean viewAnnotationFound = false; for (Annotation metaData : node.getMetaData()) { if (MyView.class.isAssignableFrom(metaData.annotationType())) { facesRedirectAnnotationFound = true; } else if (View.class.isAssignableFrom(metaData.annotationType())) { viewAnnotationFound = true; } } Assert.assertTrue(facesRedirectAnnotationFound); Assert.assertTrue(viewAnnotationFound); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Public.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(MyView.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); node = this.viewConfigExtension.findNode(Pages.Public.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); Assert.assertNotNull(node.getParent().getParent()); Assert.assertNotNull(node.getParent().getParent().getParent()); Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getCallbackDescriptors()); Assert.assertEquals(0, node.getCallbackDescriptors().size()); } @Test public void testViewConfigWithStereotypeMetaData() { this.viewConfigExtension.addPageDefinition(Pages.Home.class); this.viewConfigExtension.addPageDefinition(Pages.Public.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Home.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(2, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(MyView.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.INCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("landing page", viewConfigDescriptor.getMetaData(MyView.class).iterator().next().description()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Public.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(2, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(View.class).size()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData(MyView.class).size()); Assert.assertEquals(View.NavigationMode.REDIRECT, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("public content", viewConfigDescriptor.getMetaData(MyView.class).iterator().next().description()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc011/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc011; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.spi.config.view.ViewConfigRoot; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @ViewConfigRoot @Folder(name = "/") //there are multiple folders which should be grouped by the outermost interface interface Pages extends ViewConfig { //result: /index.xhtml class Index implements Pages { } //result: /admin interface Admin extends Pages { @View class Index implements Admin { } } //result: /public @Folder interface Public extends Pages { @View class Index implements Public { } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/navigation/syntax/uc011/ViewConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.navigation.syntax.uc011; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class ViewConfigTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testMetaDataInheritanceInTree() { this.viewConfigExtension.addPageDefinition(Pages.class); ViewConfigNode node = this.viewConfigExtension.findNode(Pages.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Root Assert.assertNull(node.getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(3, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(3, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Pages Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(0, node.getMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Admin.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Admin Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Public.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Public Assert.assertNotNull(node.getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(1, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(Folder.class, node.getMetaData().iterator().next().annotationType()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); node = this.viewConfigExtension.findNode(Pages.Public.Index.class); Assert.assertNotNull(node); Assert.assertNotNull(node.getParent()); //Public Assert.assertNotNull(node.getParent().getParent()); //Pages Assert.assertNotNull(node.getParent().getParent().getParent()); //Root Assert.assertNull(node.getParent().getParent().getParent().getParent()); Assert.assertNotNull(node.getChildren()); Assert.assertEquals(0, node.getChildren().size()); Assert.assertNotNull(node.getMetaData()); Assert.assertEquals(1, node.getMetaData().size()); Assert.assertEquals(View.NavigationMode.DEFAULT, ((View) node.getMetaData().iterator().next()).navigation()); Assert.assertEquals(View.ViewParameterMode.DEFAULT, ((View) node.getMetaData().iterator().next()).viewParams()); Assert.assertEquals("", ((View) node.getMetaData().iterator().next()).name()); Assert.assertEquals(View.Extension.DEFAULT, ((View) node.getMetaData().iterator().next()).extension()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); Assert.assertNotNull(node.getInheritedMetaData()); Assert.assertEquals(0, node.getInheritedMetaData().size()); } @Test public void testMetaDataInheritanceInViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); ConfigDescriptor configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Admin.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Admin.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/admin/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Admin.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/admin/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Admin.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/admin/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); configDescriptor = viewConfigResolver.getConfigDescriptor(Pages.Public.class); Assert.assertNotNull(configDescriptor); Assert.assertNotNull(configDescriptor.getConfigClass()); Assert.assertEquals(Pages.Public.class, configDescriptor.getConfigClass()); Assert.assertNotNull(configDescriptor.getMetaData()); Assert.assertEquals(1, configDescriptor.getMetaData().size()); Assert.assertEquals(1, configDescriptor.getMetaData(Folder.class).size()); Assert.assertEquals("/public/", configDescriptor.getMetaData(Folder.class).iterator().next().name()); viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Public.Index.class); Assert.assertNotNull(viewConfigDescriptor); Assert.assertEquals("/public/index.xhtml", viewConfigDescriptor.getViewId()); Assert.assertEquals(Pages.Public.Index.class, viewConfigDescriptor.getConfigClass()); Assert.assertNotNull(viewConfigDescriptor.getMetaData()); Assert.assertEquals(1, viewConfigDescriptor.getMetaData().size()); Assert.assertEquals(View.NavigationMode.FORWARD, viewConfigDescriptor.getMetaData(View.class).iterator().next().navigation()); Assert.assertEquals(View.ViewParameterMode.EXCLUDE, viewConfigDescriptor.getMetaData(View.class).iterator().next().viewParams()); Assert.assertEquals("index", viewConfigDescriptor.getMetaData(View.class).iterator().next().name()); Assert.assertEquals("xhtml", viewConfigDescriptor.getMetaData(View.class).iterator().next().extension()); Assert.assertEquals("/public/", viewConfigDescriptor.getMetaData(View.class).iterator().next().basePath()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/validation/Pages.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.validation; import org.apache.deltaspike.core.api.config.view.ViewConfig; interface Pages extends ViewConfig { class Index implements Pages { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/config/view/validation/ViewConfigPathValidatorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.config.view.validation; import junit.framework.Assert; import org.apache.deltaspike.core.api.config.view.metadata.ConfigDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.ViewConfigResolver; import org.apache.deltaspike.jsf.api.config.view.Folder; import org.apache.deltaspike.jsf.api.config.view.View; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigExtension; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigPathValidator; import org.apache.deltaspike.jsf.impl.config.view.ViewConfigResolverProducer; import org.junit.After; import org.junit.Before; import org.junit.Test; import jakarta.servlet.ServletContextEvent; import java.util.ArrayList; import java.util.List; public class ViewConfigPathValidatorTest { private ViewConfigExtension viewConfigExtension; private ViewConfigResolverProducer viewConfigResolverProducer; @Before public void before() { this.viewConfigExtension = new ViewConfigExtension(); this.viewConfigResolverProducer = new ViewConfigResolverProducer(this.viewConfigExtension); } @After public void after() { this.viewConfigExtension.freeViewConfigCache(null); } @Test public void testValidViewConfig() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); List supportedExtensions = new ArrayList(); supportedExtensions.add(View.Extension.XHTML); try { new MockedViewConfigPathValidator(true).validateViewConfigPaths(null, viewConfigResolver, supportedExtensions); } catch (Exception e) { Assert.fail("valid view-config was reported as invalid"); } } @Test(expected = IllegalStateException.class) public void testMissingPath() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); List supportedExtensions = new ArrayList(); supportedExtensions.add(View.Extension.XHTML); new MockedViewConfigPathValidator(false).validateViewConfigPaths(null, viewConfigResolver, supportedExtensions); } @Test public void testMissingPathButUnsupportedExtension() { this.viewConfigExtension.addPageDefinition(Pages.Index.class); ViewConfigResolver viewConfigResolver = this.viewConfigResolverProducer.createViewConfigResolver(); List supportedExtensions = new ArrayList(); supportedExtensions.add(View.Extension.JSF); try { new MockedViewConfigPathValidator(false).validateViewConfigPaths(null, viewConfigResolver, supportedExtensions); } catch (Exception e) { Assert.fail("unsupported extension wasn't ignored"); } } private class MockedViewConfigPathValidator extends ViewConfigPathValidator { private final boolean validatePathAsValid; private MockedViewConfigPathValidator(boolean validatePathAsValid) { this.validatePathAsValid = validatePathAsValid; } @Override public void validateViewConfigPaths(ServletContextEvent sce, ViewConfigResolver viewConfigResolver, List supportedExtensions) { super.validateViewConfigPaths(sce, viewConfigResolver, supportedExtensions); } @Override protected boolean isValidPath(ServletContextEvent sce, ConfigDescriptor configDescriptor) { //in our tests we just validate views -> skip folders return !configDescriptor.getMetaData(Folder.class).isEmpty() || this.validatePathAsValid; } @Override protected void printException(Exception e) { //do nothing } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc001/AnotherBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc001; public class AnotherBean { private String value; public AnotherBean() { } public AnotherBean(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Object getAsObject(String value) { if (value != null && !value.isEmpty()) { return new AnotherBean(value); } else { return null; } } public String getAsString(Object object) { if (object instanceof AnotherBean) { AnotherBean myValue = (AnotherBean) object; return myValue.getValue(); } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc001/AnotherBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc001; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.convert.Converter; import jakarta.faces.convert.ConverterException; import jakarta.faces.convert.FacesConverter; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesConverter(value = "myValueConverter", managed = true) public class AnotherBeanConverter implements Converter { @Inject private AnotherBean myValue; @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { try { if (value == null || value.isEmpty()) { return null; } Integer.parseInt(value); return myValue.getAsObject(value); } catch (NumberFormatException e) { throw new ConverterException(new FacesMessage("Value is not an Integer")); } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { return myValue.getAsString(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc001/InjectionDroneTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc001; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class InjectionDroneTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "injection-uc001.war") .addPackage(MyBean.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("injection/testValidatorConverter.xhtml", "/testValidatorConverter.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testConverter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("123"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testConverterWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("String Value"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("converter:errorMessage")), "Value is not an Integer").apply(driver)); } @Test @RunAsClient public void testValidator() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("DeltaSpike"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testValidatorWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("Wrong Value"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("validator:errorMessage")), "Not a valid value").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc001/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc001; import jakarta.enterprise.inject.Model; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; @Model public class MyBean { private String stringValue; private AnotherBean convertedValue; public String getStringValue() { return stringValue; } public void setStringValue(String stringValue) { this.stringValue = stringValue; } public AnotherBean getConvertedValue() { return convertedValue; } public void setConvertedValue(AnotherBean convertedValue) { this.convertedValue = convertedValue; } public void testAction() { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Worked")); } public boolean isValid(String value) { return "DeltaSpike".equals(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc001/MyBeanValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc001; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.validator.FacesValidator; import jakarta.faces.validator.Validator; import jakarta.faces.validator.ValidatorException; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesValidator(value = "myBeanValidator", managed = true) public class MyBeanValidator implements Validator { @Inject private MyBean myBean; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value instanceof String) { String valueAString = (String) value; if (!myBean.isValid(valueAString)) { throw new ValidatorException(new FacesMessage("Not a valid value")); } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc002/AnotherBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc002; public class AnotherBean { private String value; public AnotherBean() { } public AnotherBean(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Object getAsObject(String value) { if (value != null && !value.isEmpty()) { return new AnotherBean(value); } else { return null; } } public String getAsString(Object object) { if (object instanceof AnotherBean) { AnotherBean myValue = (AnotherBean) object; return myValue.getValue(); } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc002/AnotherBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc002; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Model; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.convert.Converter; import jakarta.faces.convert.ConverterException; import jakarta.faces.convert.FacesConverter; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @RequestScoped @FacesConverter(value = "myValueConverter", managed = true) public class AnotherBeanConverter implements Converter { @Inject private AnotherBean myValue; @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { try { if (value == null || value.isEmpty()) { return null; } Integer.parseInt(value); return myValue.getAsObject(value); } catch (NumberFormatException e) { throw new ConverterException(new FacesMessage("Value is not an Integer")); } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { return myValue.getAsString(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc002/InjectionDroneTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc002; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class InjectionDroneTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "injection-uc002.war") .addPackage(MyBean.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("injection/testValidatorConverter.xhtml", "/testValidatorConverter.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testConverter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("123"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testConverterWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("String Value"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("converter:errorMessage")), "Value is not an Integer").apply(driver)); } @Test @RunAsClient public void testValidator() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("DeltaSpike"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testValidatorWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("Wrong Value"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("validator:errorMessage")), "Not a valid value").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc002/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc002; import jakarta.enterprise.inject.Model; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; @Model public class MyBean { private String stringValue; private AnotherBean convertedValue; public String getStringValue() { return stringValue; } public void setStringValue(String stringValue) { this.stringValue = stringValue; } public AnotherBean getConvertedValue() { return convertedValue; } public void setConvertedValue(AnotherBean convertedValue) { this.convertedValue = convertedValue; } public void testAction() { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Worked")); } public boolean isValid(String value) { return "DeltaSpike".equals(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc002/MyBeanValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc002; import jakarta.enterprise.context.RequestScoped; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.validator.FacesValidator; import jakarta.faces.validator.Validator; import jakarta.faces.validator.ValidatorException; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @RequestScoped @FacesValidator(value = "myBeanValidator", managed = true) public class MyBeanValidator implements Validator { @Inject private MyBean myBean; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value instanceof String) { String valueAString = (String) value; if (!myBean.isValid(valueAString)) { throw new ValidatorException(new FacesMessage("Not a valid value")); } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/AbstractStateHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; import jakarta.faces.component.StateHolder; import jakarta.faces.context.FacesContext; public abstract class AbstractStateHolder implements StateHolder { private boolean isTransient; @Override public Object saveState(FacesContext context) { // no need to really save the state return null; } @Override public void restoreState(FacesContext context, Object state) { // no need to really restore the state } @Override public boolean isTransient() { return isTransient; } @Override public void setTransient(boolean newTransientValue) { this.isTransient = newTransientValue; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/AnotherBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; public class AnotherBean { private String value; public AnotherBean() { } public AnotherBean(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Object getAsObject(String value) { if (value != null && !value.isEmpty()) { return new AnotherBean(value); } else { return null; } } public String getAsString(Object object) { if (object instanceof AnotherBean) { AnotherBean myValue = (AnotherBean) object; return myValue.getValue(); } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/AnotherBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.convert.Converter; import jakarta.faces.convert.ConverterException; import jakarta.faces.convert.FacesConverter; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesConverter(value = "myValueConverter", managed = true) public class AnotherBeanConverter extends AbstractStateHolder implements Converter { @Inject private AnotherBean myValue; @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { try { if (value == null || value.isEmpty()) { return null; } Integer.parseInt(value); return myValue.getAsObject(value); } catch (NumberFormatException e) { throw new ConverterException(new FacesMessage("Value is not an Integer")); } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { return myValue.getAsString(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/InjectionDroneTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class InjectionDroneTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "injection-uc003.war") .addPackage(MyBean.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("injection/testValidatorConverterTag.xhtml", "/testValidatorConverter.xhtml") .addAsWebInfResource("META-INF/test.taglib.xml", "classes/META-INF/test.taglib.xml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource("default/WEB-INF/faces-config.xml", "faces-config.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testConverter() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("123"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testConverterWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("converter:convertedValue")); convertedValue.sendKeys("String Value"); WebElement testConverterButton = driver.findElement(By.id("converter:testConverterButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("converter:errorMessage")), "Value is not an Integer").apply(driver)); } @Test @RunAsClient public void testValidator() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("DeltaSpike"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testValidatorWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("Wrong Value"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("validator:errorMessage")), "Not a valid value").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; import jakarta.enterprise.inject.Model; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; @Model public class MyBean { private String stringValue; private AnotherBean convertedValue; public String getStringValue() { return stringValue; } public void setStringValue(String stringValue) { this.stringValue = stringValue; } public AnotherBean getConvertedValue() { return convertedValue; } public void setConvertedValue(AnotherBean convertedValue) { this.convertedValue = convertedValue; } public void testAction() { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Worked")); } public boolean isValid(String value) { return "DeltaSpike".equals(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc003/MyBeanValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc003; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.validator.FacesValidator; import jakarta.faces.validator.Validator; import jakarta.faces.validator.ValidatorException; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesValidator(value = "myBeanValidator", managed = true) public class MyBeanValidator extends AbstractStateHolder implements Validator { @Inject private MyBean myBean; @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value instanceof String) { String valueAString = (String) value; if (!myBean.isValid(valueAString)) { throw new ValidatorException(new FacesMessage("Not a valid value")); } } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc004/AnotherBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc004; public class AnotherBean { private String value; public AnotherBean() { } public AnotherBean(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public Object getAsObject(String value) { if (value != null && !value.isEmpty()) { return new AnotherBean(value); } else { return null; } } public String getAsString(Object object) { if (object instanceof AnotherBean) { AnotherBean myValue = (AnotherBean) object; return myValue.getValue(); } return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc004/AnotherBeanConverter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc004; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.convert.Converter; import jakarta.faces.convert.ConverterException; import jakarta.faces.convert.FacesConverter; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesConverter(value = "myValueConverter", managed = true) public class AnotherBeanConverter implements Converter { @Inject private AnotherBean myValue; @Override public Object getAsObject(FacesContext context, UIComponent component, String value) { try { if (value == null || value.isEmpty()) { return null; } Integer.parseInt(value); return myValue.getAsObject(value); } catch (NumberFormatException e) { throw new ConverterException(new FacesMessage("Value is not an Integer")); } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { return myValue.getAsString(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc004/InjectionDroneTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc004; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class InjectionDroneTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "injection-uc004.war") .addPackage(MyBean.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("injection/testValidatorTagParameter.xhtml", "/testValidatorConverter.xhtml") .addAsWebInfResource("META-INF/test.taglib.xml", "classes/META-INF/test.taglib.xml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource("default/WEB-INF/faces-config.xml", "faces-config.xml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testValidator() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("DeltaSpike"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("messages")), "Worked").apply(driver)); } @Test @RunAsClient public void testValidatorWithError() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "testValidatorConverter.xhtml").toString()); WebElement convertedValue = driver.findElement(By.id("validator:stringValue")); convertedValue.sendKeys("Wrong Value"); WebElement testConverterButton = driver.findElement(By.id("validator:testValidatorButton")); testConverterButton.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement(driver.findElement(By.id("validator:errorMessage")), "The valid value should be DeltaSpike").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc004/MyBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc004; import jakarta.enterprise.inject.Model; import jakarta.faces.application.FacesMessage; import jakarta.faces.context.FacesContext; @Model public class MyBean { private String stringValue; private AnotherBean convertedValue; public String getStringValue() { return stringValue; } public void setStringValue(String stringValue) { this.stringValue = stringValue; } public AnotherBean getConvertedValue() { return convertedValue; } public void setConvertedValue(AnotherBean convertedValue) { this.convertedValue = convertedValue; } public void testAction() { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Worked")); } public boolean isValid(String value, String validValue) { return validValue.equals(value); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/injection/uc004/MyBeanValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.injection.uc004; import jakarta.faces.application.FacesMessage; import jakarta.faces.component.StateHolder; import jakarta.faces.component.UIComponent; import jakarta.faces.context.FacesContext; import jakarta.faces.validator.FacesValidator; import jakarta.faces.validator.Validator; import jakarta.faces.validator.ValidatorException; import jakarta.inject.Inject; import jakarta.inject.Named; @Named @FacesValidator(value = "myBeanValidator", managed = true) public class MyBeanValidator implements Validator, StateHolder { @Inject private MyBean myBean; private String validValue = "DeltaSpike"; private boolean isTransient; public void setValidValue(String validValue) { this.validValue = validValue; } public String getValidValue() { return validValue; } @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if (value instanceof String) { String valueAString = (String) value; if (!myBean.isValid(valueAString, validValue)) { throw new ValidatorException(new FacesMessage("The valid value should be " + validValue)); } } } @Override public Object saveState(FacesContext context) { return this.validValue; } @Override public void restoreState(FacesContext context, Object state) { this.validValue = (String) state; } @Override public boolean isTransient() { return isTransient; } @Override public void setTransient(boolean newTransientValue) { this.isTransient = newTransientValue; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/message/JsfMessageTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.message; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.config.TestJsfModuleConfig; import org.apache.deltaspike.test.jsf.impl.message.beans.JsfMessageBackingBean; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Test for the DeltaSpike JsfMessage Producer */ @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class JsfMessageTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "jsfMessageTest.war") .addPackage(JsfMessageBackingBean.class.getPackage()) .addClass(TestJsfModuleConfig.class) .addAsResource("jsfMessageTest/UserMessage_en.properties") .addAsResource("jsfMessageTest/UserMessage_de.properties") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebResource("jsfMessageTest/page.xhtml", "page.xhtml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testEnglishMessages() throws Exception { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "page.xhtml").toString()); //X comment this in if you like to debug the server //X I've already reported ARQGRA-213 for it //X System.out.println("contextpath= " + contextPath); //X Thread.sleep(600000L); // check the JSF FacesMessages Assert.assertNotNull(ExpectedConditions.presenceOfElementLocated(By.xpath("id('messages')")).apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[1]")), "message with details warnInfo!").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[2]")), "message without detail but parameter errorInfo.").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[3]")), "a simple message without a param.").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[4]")), "simple message with a string param fatalInfo.").apply(driver)); // check the free message usage Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("test:valueOutput")), "a simple message without a param.").apply(driver)); // and also the usage via direct EL invocation Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("test:elOutput")), "a simple message without a param.").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("test:elOutputWithParam")), "simple message with a string param hiho.").apply(driver)); } @Test @RunAsClient public void testGermanMessages() throws Exception { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "page.xhtml?lang=de").toString()); // check the JSF FacesMessages Assert.assertNotNull(ExpectedConditions.presenceOfElementLocated(By.xpath("id('messages')")).apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[1]")), "Nachricht mit Details warnInfo!").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[2]")), "Nachricht ohne Details aber mit Parameter errorInfo.").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[3]")), "Einfache Nachricht ohne Parameter.").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.xpath("id('messages')/ul/li[4]")), "Einfache Nachricht mit String Parameter fatalInfo.").apply(driver)); // check the free message usage Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("test:valueOutput")), "Einfache Nachricht ohne Parameter.").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/message/beans/JsfMessageBackingBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.message.beans; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import jakarta.inject.Named; import org.apache.deltaspike.jsf.api.message.JsfMessage; /** * sample backing bean for JsfMessage. */ @RequestScoped @Named public class JsfMessageBackingBean { @Inject private JsfMessage msg; private String locale = "en"; public void init() { msg.addWarn().messageWithDetail("warnInfo"); msg.addError().messageWithoutDetail("errorInfo"); msg.addInfo().simpleMessageNoParam(); msg.addFatal().simpleMessageWithParam("fatalInfo"); } public String getSomeMessage() { return msg.get().simpleMessageNoParam(); } public String getLocale() { return locale; } public void setLocale(String locale) { this.locale = locale; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/message/beans/UserMessage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.message.beans; import org.apache.deltaspike.core.api.message.Message; import org.apache.deltaspike.core.api.message.MessageBundle; import org.apache.deltaspike.core.api.message.MessageContextConfig; import jakarta.inject.Named; @MessageBundle @Named @MessageContextConfig(messageSource = "jsfMessageTest.UserMessage") public interface UserMessage { Message messageWithDetail(String param); Message messageWithoutDetail(String param); String simpleMessageWithParam(String param); String simpleMessageNoParam(); } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/view/beans/ViewScopedBackingBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.view.beans; import jakarta.faces.view.ViewScoped; import jakarta.inject.Named; import java.io.Serializable; /** * ViewScoped sample backing bean. */ @ViewScoped @Named("viewScopedBean") public class ViewScopedBackingBean implements Serializable { private int i = 0; public int getI() { return i; } public void setI(int i) { this.i = i; } public String someAction() { // stay on the page. return null; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/viewaccess/ViewAccessScopedWebAppTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.viewaccess; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.control.LockedImplementation; import org.apache.deltaspike.test.control.VersionControlRule; import org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans.ViewAccessScopedBeanX; import org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans.ViewAccessScopedBeanY; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.utils.Implementation; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class ViewAccessScopedWebAppTest { @ArquillianResource private URL contextPath; @Rule public VersionControlRule versionControlRule = new VersionControlRule(); @Deployment public static WebArchive deploy() { String simpleName = ViewAccessScopedWebAppTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap .create(WebArchive.class, archiveName + ".war") .addClass(ViewAccessScopedBeanX.class) .addClass(ViewAccessScopedBeanY.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebResource("viewAccessScopedContextTest/page1.xhtml", "page1.xhtml") .addAsWebResource("viewAccessScopedContextTest/page2.xhtml", "page2.xhtml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient // Actually not a MyFaces bug but html-unit uses Rhino which cannot handle EcmaScript spread operator syntax yet // See https://github.com/mozilla/rhino/issues/968 @LockedImplementation(excludedImplementations = {Implementation.MYFACES40}) public void testForward() throws Exception { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "page1.xhtml").toString()); WebElement inputFieldX = driver.findElement(By.id("testForm1:valueInputX")); inputFieldX.sendKeys("abc"); WebElement inputFieldY = driver.findElement(By.id("testForm1:valueInputY")); inputFieldY.sendKeys("xyz"); WebElement button = driver.findElement(By.id("testForm1:next")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("valueX")), "abc").apply(driver)); button = driver.findElement(By.id("testForm2:back")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("valueOutputX")), "abc").apply(driver)); Assert.assertFalse(ExpectedConditions.textToBePresentInElement( driver.findElement( By.id("valueOutputY")), "xyz").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/viewaccess/ViewAccessScopedWithFViewActionWebAppTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.viewaccess; import org.apache.deltaspike.test.category.WebEEProfileCategory; import org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans.ViewAccessScopedBeanX; import org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans.ViewAccessScopedBeanY; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebEEProfileCategory.class) public class ViewAccessScopedWithFViewActionWebAppTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { String simpleName = ViewAccessScopedWithFViewActionWebAppTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap .create(WebArchive.class, archiveName + ".war") .addClass(ViewAccessScopedBeanX.class) .addClass(ViewAccessScopedBeanY.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebResource("viewAccessScopedContextTest/index.xhtml", "index.xhtml") .addAsWebResource("viewAccessScopedContextTest/next.xhtml", "next.xhtml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient public void testForward() throws Exception { WebDriver driver = new HtmlUnitDriver(true); driver.get(new URL(contextPath, "index.xhtml").toString()); WebElement inputFieldX = driver.findElement(By.id("form:firstValue")); inputFieldX.sendKeys("abc"); WebElement inputFieldY = driver.findElement(By.id("form:secondValue")); inputFieldY.sendKeys("xyz"); WebElement button = driver.findElement(By.id("form:next")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("firstValue")), "abc").apply(driver)); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("secondValue")), "xyz").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/viewaccess/beans/ViewAccessScopedBeanX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans; import java.io.Serializable; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; @Named @ViewAccessScoped public class ViewAccessScopedBeanX implements Serializable { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void viewAction() { } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/viewaccess/beans/ViewAccessScopedBeanY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.viewaccess.beans; import java.io.Serializable; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.ViewAccessScoped; @Named @ViewAccessScoped public class ViewAccessScopedBeanY implements Serializable { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/MyWindowScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window; import java.io.Serializable; import jakarta.inject.Named; import org.apache.deltaspike.core.api.scope.WindowScoped; @Named @WindowScoped public class MyWindowScopedBean implements Serializable { private static final long serialVersionUID = 1L; private int value = 0; public int getValue() { return value; } public void count() { value++; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/WindowMaxCountTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import java.net.MalformedURLException; import java.net.URL; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class WindowMaxCountTest { @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { WebArchive archive = ShrinkWrap .create(WebArchive.class, "windowMaxCountTest.war") .addPackage(WindowMaxCountTest.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebResource("windowScopedContextTest/windowcount.xhtml", "/windowcount.xhtml") .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebInfResource("META-INF/apache-deltaspike.properties", "classes/META-INF/apache-deltaspike.properties") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return archive; } @Test @RunAsClient public void maxWindowPerSessionTest() throws MalformedURLException { WebDriver driver = new HtmlUnitDriver(true); // PAGE 1 - REQUEST 1 driver.get(new URL(contextPath, "windowcount.xhtml").toString()); // click once WebElement button = driver.findElement(By.id("form:count")); button.click(); WebElement value = driver.findElement(By.id("form:value")); Assert.assertEquals("1", value.getText()); driver.get(driver.getCurrentUrl()); // click twice button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); Assert.assertEquals("2", value.getText()); String page1 = driver.getCurrentUrl(); // PAGE 2 - REQUEST 2 driver.get(new URL(contextPath, "windowcount.xhtml").toString()); // click once button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); Assert.assertEquals("1", value.getText()); driver.get(driver.getCurrentUrl()); // click twice button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); Assert.assertEquals("2", value.getText()); // PAGE 3 - REQUEST 3 to force the oldest (page 1) WindowScope to drop driver.get(new URL(contextPath, "windowcount.xhtml").toString()); // click once button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); Assert.assertEquals("1", value.getText()); driver.get(driver.getCurrentUrl()); // click twice button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); Assert.assertEquals("2", value.getText()); String page3 = driver.getCurrentUrl(); // PAGE 1 - REQUEST 4 on previous PAGE 1 page (value should get dropped to 0) driver.get(new URL(page1).toString()); // click once button = driver.findElement(By.id("form:count")); button.click(); value = driver.findElement(By.id("form:value")); // Value should return to 1 Assert.assertEquals("1", value.getText()); // PAGE 3 - REQUEST 5 on previous PAGE 3 page (page 1 and page 3 should be the two active pages) driver.get(new URL(page3).toString()); button = driver.findElement(By.id("form:count")); // click once button.click(); value = driver.findElement(By.id("form:value")); // Value should continue to 3 Assert.assertEquals("3", value.getText()); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/WindowScopedContextFrameTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.control.LockedImplementation; import org.apache.deltaspike.test.control.VersionControlRule; import org.apache.deltaspike.test.jsf.impl.config.TestJsfModuleConfig; import org.apache.deltaspike.test.jsf.impl.scope.window.beans.WindowScopedBackingBean; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.utils.Implementation; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import java.net.URL; import java.util.logging.Logger; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Test for the DeltaSpike JsfMessage Producer */ @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class WindowScopedContextFrameTest { private static final Logger log = Logger.getLogger(WindowScopedContextFrameTest.class.getName()); @ArquillianResource private URL contextPath; @Rule public VersionControlRule versionControlRule = new VersionControlRule(); @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "windowScopedContextFrameTest.war") .addPackage(WindowScopedBackingBean.class.getPackage()) .addClass(TestJsfModuleConfig.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebResource("META-INF/resources/deltaspike/windowhandler.js", "resources/deltaspike/windowhandler.js") .addAsWebResource("windowScopedContextTest/framecontainer.xhtml", "framecontainer.xhtml") .addAsWebResource("windowScopedContextTest/frame.xhtml", "frame.xhtml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient // Actually not a MyFaces bug but html-unit uses Rhino which cannot handle EcmaScript spread operator syntax yet // See https://github.com/mozilla/rhino/issues/968 @LockedImplementation(excludedImplementations = {Implementation.MYFACES40}) public void testWindowId() throws Exception { WebDriver driver = new HtmlUnitDriver(true); System.out.println("contextpath= " + contextPath); //X comment this in if you like to debug the server //X I've already reported ARQGRA-213 for it //X Thread.sleep(600000L); driver.get(new URL(contextPath, "framecontainer.xhtml").toString()); String outerId = driver.findElement(By.id("window-id")).getText(); String innerId = ((HtmlUnitDriver) driver).executeScript("return document.getElementById('iframe').contentWindow.document.getElementById('window-id').innerHTML").toString().trim(); Assert.assertEquals(outerId, innerId); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/WindowScopedContextTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window; import org.apache.deltaspike.test.category.WebProfileCategory; import org.apache.deltaspike.test.control.LockedImplementation; import org.apache.deltaspike.test.control.LockedVersionRange; import org.apache.deltaspike.test.control.VersionControlRule; import org.apache.deltaspike.test.jsf.impl.config.TestJsfModuleConfig; import org.apache.deltaspike.test.jsf.impl.scope.window.beans.WindowScopedBackingBean; import org.apache.deltaspike.test.jsf.impl.util.ArchiveUtils; import org.apache.deltaspike.test.utils.Implementation; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.htmlunit.HtmlUnitDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import java.net.URL; import java.util.logging.Logger; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; /** * Test for the DeltaSpike JsfMessage Producer */ @RunWith(Arquillian.class) @Category(WebProfileCategory.class) public class WindowScopedContextTest { private static final Logger log = Logger.getLogger(WindowScopedContextTest.class.getName()); @Rule public VersionControlRule versionControlRule = new VersionControlRule(); @ArquillianResource private URL contextPath; @Deployment public static WebArchive deploy() { return ShrinkWrap .create(WebArchive.class, "windowScopedContextTest.war") .addPackage(WindowScopedBackingBean.class.getPackage()) .addClass(TestJsfModuleConfig.class) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndJsfArchive()) .addAsLibraries(ArchiveUtils.getDeltaSpikeSecurityArchive()) .addAsWebInfResource("default/WEB-INF/web.xml", "web.xml") .addAsWebResource("META-INF/resources/deltaspike/windowhandler.js", "resources/deltaspike/windowhandler.js") .addAsWebResource("windowScopedContextTest/page.xhtml", "page.xhtml") .addAsWebResource("windowScopedContextTest/page2.xhtml", "page2.xhtml") .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } @Test @RunAsClient // Actually not a MyFaces bug but html-unit uses Rhino which cannot handle EcmaScript spread operator syntax yet // See https://github.com/mozilla/rhino/issues/968 @LockedImplementation(excludedImplementations = {Implementation.MYFACES40}) public void testWindowId() throws Exception { WebDriver driver = new HtmlUnitDriver(true); System.out.println("contextpath= " + contextPath); //X comment this in if you like to debug the server //X I've already reported ARQGRA-213 for it //X Thread.sleep(600000L); driver.get(new URL(contextPath, "page.xhtml").toString()); WebElement inputField = driver.findElement(By.id("test:valueInput")); inputField.sendKeys("23"); WebElement button = driver.findElement(By.id("test:saveButton")); button.click(); Assert.assertTrue(ExpectedConditions.textToBePresentInElement( driver.findElement(By.id("valueOutput")), "23").apply(driver)); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/beans/WindowAccessBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window.beans; import org.apache.deltaspike.core.api.scope.WindowScoped; import org.apache.deltaspike.core.spi.scope.window.WindowContext; import jakarta.inject.Inject; import jakarta.inject.Named; import java.io.Serializable; @Named @WindowScoped public class WindowAccessBean implements Serializable { private static final long serialVersionUID = 1L; @Inject WindowContext windowContext; public String getId() { return windowContext.getCurrentWindowId(); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/scope/window/beans/WindowScopedBackingBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.scope.window.beans; import jakarta.inject.Named; import java.io.Serializable; import org.apache.deltaspike.core.api.scope.WindowScoped; /** * WindowScoped sample backing bean. */ @WindowScoped @Named("windowScopedBean") public class WindowScopedBackingBean implements Serializable { private int i = 0; public int getI() { return i; } public void setI(int i) { this.i = i; } public String someAction() { return "page2?faces-redirect=true"; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.util; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * This class contains helpers for building frequently used archives */ public class ArchiveUtils { private ArchiveUtils() { // private ct } public static JavaArchive[] getDeltaSpikeCoreAndJsfArchive() { String[] excludedFiles; excludedFiles = new String[]{"META-INF.apache-deltaspike.properties"}; JavaArchive[] coreArchives = ShrinkWrapArchiveUtil.getArchives(null , "META-INF/beans.xml" , new String[]{ "org.apache.deltaspike.core", "org.apache.deltaspike.proxy", "org.apache.deltaspike.jsf" } , excludedFiles, "ds-core_proxy_jsf"); return coreArchives; } public static JavaArchive[] getDeltaSpikeSecurityArchive() { String[] excludedFiles; excludedFiles = new String[]{"META-INF.apache-deltaspike.properties"}; return ShrinkWrapArchiveUtil.getArchives(null, "META-INF/beans.xml", new String[]{"org.apache.deltaspike.security"}, excludedFiles, "ds-security"); } public static Asset getBeansXml() { Asset beansXml = new StringAsset( "" + "" + "org.apache.deltaspike.jsf.impl.config.view.navigation.NavigationParameterInterceptor" + "org.apache.deltaspike.jsf.impl.config.view.navigation.NavigationParameterListInterceptor" + "" + "" ); return beansXml; } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/FileUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.util; import java.io.File; import java.net.MalformedURLException; import java.net.URL; /** * Some basic utils */ //TODO merge test-util classes public class FileUtils { private FileUtils() { // prevent instantiation } /** * @param url the target URL * @return a file created based on the given URL */ public static File getFileForURL(String url) { //fix for wls if(!url.startsWith("file:/")) { url = "file:/" + url; } url = url.replaceAll("%20", " "); try { return new File( (new URL(url)).getFile()); } catch (MalformedURLException e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/java/org/apache/deltaspike/test/jsf/impl/util/JsfUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.jsf.impl.util; import org.apache.deltaspike.jsf.impl.util.JsfUtils; import org.junit.Assert; import org.junit.Test; import jakarta.faces.application.FacesMessage; import java.util.ArrayList; import java.util.List; //several tests are only needed to check that there won't be a NullPointerException public class JsfUtilsTest { @Test public void testNewMessageWithoutExistingMessages() { List existingFacesMessage = new ArrayList(); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, new FacesMessage("test"))); } @Test public void testExistingSimpleMessage() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("test")); FacesMessage messageToCheck = new FacesMessage("test"); Assert.assertEquals(Boolean.FALSE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testExistingMessageWithoutSummary() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage(null, "test")); FacesMessage messageToCheck = new FacesMessage(null, "test"); Assert.assertEquals(Boolean.FALSE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testExistingMessageWithoutDetails() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("test", null)); FacesMessage messageToCheck = new FacesMessage("test", null); Assert.assertEquals(Boolean.FALSE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithExistingMessageWithoutText() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage(null, null)); FacesMessage messageToCheck = new FacesMessage("test"); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithoutText() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("existing", "message")); FacesMessage messageToCheck = new FacesMessage(null, null); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithoutSummary() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("existing", "message")); FacesMessage messageToCheck = new FacesMessage(null, "test"); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithoutDetails() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("existing", "message")); FacesMessage messageToCheck = new FacesMessage("test", null); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testMessagesWithoutText() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage(null, null)); FacesMessage messageToCheck = new FacesMessage(null, null); Assert.assertEquals(Boolean.FALSE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithExistingMessageWithoutSummary() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage(null, "message")); FacesMessage messageToCheck = new FacesMessage("new", "message"); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testNewMessageWithExistingMessageWithoutDetails() { List existingFacesMessage = new ArrayList(); existingFacesMessage.add(new FacesMessage("existing", null)); FacesMessage messageToCheck = new FacesMessage("new", "message"); Assert.assertEquals(Boolean.TRUE, JsfUtils.isNewMessage(existingFacesMessage, messageToCheck)); } @Test public void testRemoveUrlParameter() { Assert.assertEquals("http://localhost:58481/windowScopedContextTest/page.xhtml", JsfUtils.removeUrlParameter("http://localhost:58481/windowScopedContextTest/page.xhtml?jfwid=-1281", "jfwid")); Assert.assertEquals("http://localhost:58481/windowScopedContextTest/page.xhtml", JsfUtils.removeUrlParameter("http://localhost:58481/windowScopedContextTest/page.xhtml?jfwid=", "jfwid")); } } ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # deltaspike.scope.window.max-count=2 ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/META-INF/test.taglib.xml ================================================ http://deltaspike.apache.org/tags myBeanValidator myBeanValidator myValueConverter myValueConverter ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/controller/simplePageConfig.xhtml ================================================ Test
You arrived at simplePageConfig page
#{pageBean001.called}
#{pageBean002.called}
#{pageBean003.called}
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/default/WEB-INF/faces-config.xml ================================================ ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/default/WEB-INF/web.xml ================================================ Faces Servlet jakarta.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/injection/testValidatorConverter.xhtml ================================================
Converterd Value :
Value String:
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/injection/testValidatorConverterTag.xhtml ================================================
Converterd Value :
Value String:
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/injection/testValidatorTagParameter.xhtml ================================================
Value String:
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/jsfMessageTest/UserMessage_de.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # messageWithDetail = Nachricht mit Details %s! messageWithDetail.detail = Nachricht mit sehr langen und genauen Details %s! messageWithoutDetail = Nachricht ohne Details aber mit Parameter %s. simpleMessageWithParam = Einfache Nachricht mit String Parameter %s. simpleMessageNoParam = Einfache Nachricht ohne Parameter. ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/jsfMessageTest/UserMessage_en.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # messageWithDetail = message with details %s! messageWithDetail.detail = message with loooong and very specific details %s! messageWithoutDetail = message without detail but parameter %s. simpleMessageWithParam = simple message with a string param %s. simpleMessageNoParam = a simple message without a param. ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/jsfMessageTest/page.xhtml ================================================






================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/mappedJsfContextTest/page.xhtml ================================================



================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/origin.xhtml ================================================ Test ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/pages/customErrorPage.xhtml ================================================ Test
This is a custom error page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/pages/home.xhtml ================================================ Test
You arrived at home page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/pages/index.xhtml ================================================ Test
You arrived at index page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/pages/overview.xhtml ================================================ Test
You arrived at overview page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/simplePageConfig.xhtml ================================================ Test
You arrived at simplePageConfig page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigation/wizard1/step1.xhtml ================================================ Test
You arrived at step1 page
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/navigationParameterTest/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.test.jsf.impl.config.view.navigation.parameter.shared.TestClassDeactivator ================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/viewAccessScopedContextTest/index.xhtml ================================================

================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/viewAccessScopedContextTest/next.xhtml ================================================

================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/viewAccessScopedContextTest/page1.xhtml ================================================



================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/viewAccessScopedContextTest/page2.xhtml ================================================

================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/windowScopedContextTest/frame.xhtml ================================================
#{windowAccessBean.id}
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/windowScopedContextTest/framecontainer.xhtml ================================================
#{windowAccessBean.id}
================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/windowScopedContextTest/page.xhtml ================================================



================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/windowScopedContextTest/page2.xhtml ================================================

================================================ FILE: deltaspike/modules/jsf/impl/src/test/resources/windowScopedContextTest/windowcount.xhtml ================================================ Value:
================================================ FILE: deltaspike/modules/jsf/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules jsf-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike JSF-Module api impl org.apache.myfaces.core myfaces-api ${myfaces.version} provided ================================================ FILE: deltaspike/modules/partial-bean/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules partial-bean-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-partial-bean-module-api jar Apache DeltaSpike Partial-Bean-Module API org.apache.deltaspike.partialbean.* !org.apache.deltaspike.partialbean.*, * META-INF/beans.xml org.apache.deltaspike.core deltaspike-core-api ${project.version} ================================================ FILE: deltaspike/modules/partial-bean/api/src/main/java/org/apache/deltaspike/partialbean/api/PartialBeanBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.partialbean.api; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface PartialBeanBinding { } ================================================ FILE: deltaspike/modules/partial-bean/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/partial-bean/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules partial-bean-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-partial-bean-module-impl jar Apache DeltaSpike Partial-Bean-Module Impl org.apache.deltaspike.partialbean.impl.* !org.apache.deltaspike.partialbean.impl.*, * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.ops4j.pax.cdi.extension; extension=deltaspike-partial-bean-module-impl org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${project.version} org.apache.deltaspike.modules deltaspike-proxy-module-api ${project.version} org.apache.deltaspike.modules deltaspike-proxy-module-impl-asm ${project.version} org.ow2.asm asm ${asm.version} test org.ow2.asm asm-commons ${asm.version} test org.ow2.asm asm-tree ${asm.version} test ================================================ FILE: deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanBindingExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.partialbean.impl; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import java.util.Set; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; import jakarta.enterprise.inject.spi.configurator.BeanConfigurator; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.Annotateds; import org.apache.deltaspike.core.util.AnnotationUtils; import org.apache.deltaspike.core.util.BeanConfiguratorUtils; import org.apache.deltaspike.core.util.BeanUtils; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ReflectionUtils; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import org.apache.deltaspike.proxy.api.DeltaSpikeProxyBeanConfigurator; public class PartialBeanBindingExtension implements Extension, Deactivatable { private final Map, PartialBeanDescriptor> descriptors = new HashMap, PartialBeanDescriptor>(); private Boolean isActivated = true; private IllegalStateException definitionError; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { this.isActivated = ClassDeactivationUtils.isActivated(getClass()); } public void findInvocationHandlerBindings(@Observes ProcessAnnotatedType pat) { if (!this.isActivated || this.definitionError != null) { return; } Class beanClass = pat.getAnnotatedType().getJavaClass(); // skip classes without a partial bean binding Class bindingClass = extractBindingClass(pat); if (bindingClass == null) { return; } if (beanClass.isInterface() || Modifier.isAbstract(beanClass.getModifiers())) { pat.veto(); PartialBeanDescriptor descriptor = descriptors.get(bindingClass); if (descriptor == null) { descriptor = new PartialBeanDescriptor(bindingClass, null, beanClass); descriptors.put(bindingClass, descriptor); } else if (!descriptor.getClasses().contains(beanClass)) { descriptor.getClasses().add(beanClass); } } else if (InvocationHandler.class.isAssignableFrom(beanClass)) { PartialBeanDescriptor descriptor = descriptors.get(bindingClass); if (descriptor == null) { descriptor = new PartialBeanDescriptor(bindingClass, (Class) beanClass); descriptors.put(bindingClass, descriptor); } else { if (descriptor.getHandler() == null) { descriptor.setHandler((Class) beanClass); } else if (!descriptor.getHandler().equals(beanClass)) { this.definitionError = new IllegalStateException("Multiple handlers found for " + bindingClass.getName() + " (" + descriptor.getHandler().getName() + " and " + beanClass.getName() + ")"); } } } else { this.definitionError = new IllegalStateException(beanClass.getName() + " is annotated with @" + bindingClass.getName() + " and therefore has to be " + "an abstract class, an interface or an implementation of " + InvocationHandler.class.getName()); } } public void createBeans(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { if (!this.isActivated) { return; } if (this.definitionError != null) { afterBeanDiscovery.addDefinitionError(this.definitionError); return; } for (Map.Entry, PartialBeanDescriptor> entry : this.descriptors.entrySet()) { PartialBeanDescriptor descriptor = entry.getValue(); if (descriptor.getClasses() != null) { for (Class partialBeanClass : descriptor.getClasses()) { boolean added = createPartialBean(partialBeanClass, descriptor, afterBeanDiscovery, beanManager); if (added) { createPartialProducersDefinedIn(afterBeanDiscovery, beanManager, partialBeanClass); } } } } this.descriptors.clear(); } protected boolean createPartialBean(Class beanClass, PartialBeanDescriptor descriptor, AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { if (descriptor.getHandler() == null) { afterBeanDiscovery.addDefinitionError(new IllegalStateException("A class which implements " + InvocationHandler.class.getName() + " and is annotated with @" + descriptor.getBinding().getName() + " is needed as a handler for " + beanClass.getName() + ". See the documentation about @" + PartialBeanBinding.class.getName() + ".")); return false; } AnnotatedType annotatedType = beanManager.createAnnotatedType(beanClass); BeanConfigurator beanConfigurator = afterBeanDiscovery.addBean(); BeanConfiguratorUtils.read(beanManager, beanConfigurator, annotatedType) .beanClass(beanClass); beanConfigurator.id(PartialBeanBinding.class.getName() + ":" + Annotateds.createTypeId(annotatedType)); new DeltaSpikeProxyBeanConfigurator(beanClass, descriptor.getHandler(), PartialBeanProxyFactory.getInstance(), beanManager, beanConfigurator) .delegateCreateWith() .delegateDestroyWith(); return true; } protected Class extractBindingClass(ProcessAnnotatedType pat) { for (Annotation annotation : pat.getAnnotatedType().getAnnotations()) { if (annotation.annotationType().isAnnotationPresent(PartialBeanBinding.class)) { return annotation.annotationType(); } } return null; } /* * logic for partial-producers */ private void createPartialProducersDefinedIn( AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager, Class currentClass) { while (currentClass != null && !Object.class.getName().equals(currentClass.getName())) { for (Class interfaceClass : currentClass.getInterfaces()) { if (interfaceClass.getName().startsWith("java.") || interfaceClass.getName().startsWith("javax.") || interfaceClass.getName().startsWith("jakarta.")) { continue; } createPartialProducersDefinedIn(afterBeanDiscovery, beanManager, interfaceClass); } for (Method currentMethod : currentClass.getDeclaredMethods()) { if (currentMethod.isAnnotationPresent(Produces.class)) { if (currentMethod.getParameterTypes().length > 0) { afterBeanDiscovery.addDefinitionError( new IllegalStateException( "Producer-methods in partial-beans currently don't support injection-points. " + "Please remove the parameters from " + currentMethod.toString() + " in " + currentClass.getName())); } Class scopeClass = extractScope(currentMethod.getDeclaredAnnotations(), beanManager); Class producerResultType = currentMethod.getReturnType(); Set qualifiers = extractQualifiers(currentMethod.getDeclaredAnnotations(), beanManager); final Class partialBeanClass = currentClass; afterBeanDiscovery.addBean() .beanClass(producerResultType) .types(Object.class, producerResultType) .qualifiers(qualifiers) .scope(scopeClass) .id(createPartialProducerId(currentClass, currentMethod, qualifiers)) .produceWith(e -> { Object instance = BeanProvider.getContextualReference(partialBeanClass); return ReflectionUtils.invokeMethod(instance, currentMethod, Object.class, false); }); } } currentClass = currentClass.getSuperclass(); } } private Set extractQualifiers(Annotation[] annotations, BeanManager beanManager) { Set result = BeanUtils.getQualifiers(beanManager, annotations); if (result.isEmpty()) { result.add(Default.Literal.INSTANCE); } return result; } private Class extractScope(Annotation[] annotations, BeanManager beanManager) { for (Annotation annotation : annotations) { if (beanManager.isScope(annotation.annotationType())) { return annotation.annotationType(); } } return Dependent.class; } private String createPartialProducerId(Class currentClass, Method currentMethod, Set qualifiers) { int qualifierHashCode = 0; for (Annotation qualifier : qualifiers) { qualifierHashCode += AnnotationUtils.getQualifierHashCode(qualifier); } return "PartialProducer#" + currentClass.getName() + "#" + currentMethod.getName() + "#" + qualifierHashCode; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanDescriptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.partialbean.impl; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.util.HashSet; import java.util.Set; public class PartialBeanDescriptor { private Class binding; private Class handler; private Set> classes; public PartialBeanDescriptor(Class binding) { this.binding = binding; this.classes = new HashSet<>(); } public PartialBeanDescriptor(Class binding, Class handler) { this(binding); this.handler = handler; } public PartialBeanDescriptor(Class binding, Class handler, Class clazz) { this(binding, handler); this.classes.add(clazz); } public Class getBinding() { return binding; } public void setBinding(Class binding) { this.binding = binding; } public Class getHandler() { return handler; } public void setHandler(Class handler) { this.handler = handler; } public Set> getClasses() { return classes; } public void setClasses(Set> classes) { this.classes = classes; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/main/java/org/apache/deltaspike/partialbean/impl/PartialBeanProxyFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.partialbean.impl; import org.apache.deltaspike.proxy.api.DeltaSpikeProxyFactory; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Iterator; import jakarta.enterprise.inject.Vetoed; /** * {@link DeltaSpikeProxyFactory} which delegates all abstract methods to the * partial bean binding {@link java.lang.reflect.InvocationHandler}. */ @Vetoed public class PartialBeanProxyFactory extends DeltaSpikeProxyFactory { private static final PartialBeanProxyFactory INSTANCE = new PartialBeanProxyFactory(); public static PartialBeanProxyFactory getInstance() { return INSTANCE; } @Override protected String getProxyClassSuffix() { return "$$DSPartialBeanProxy"; } @Override protected ArrayList getDelegateMethods(Class targetClass, ArrayList allMethods) { ArrayList methods = new ArrayList<>(); Iterator it = allMethods.iterator(); while (it.hasNext()) { Method method = it.next(); if (Modifier.isAbstract(method.getModifiers())) { methods.add(method); } } return methods; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/partial-bean/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.partialbean.impl.PartialBeanBindingExtension ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/CustomInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target({ TYPE, METHOD }) @InterceptorBinding public @interface CustomInterceptor { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/CustomInterceptorImpl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import java.io.Serializable; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; @Interceptor @CustomInterceptor public class CustomInterceptorImpl implements Serializable { @Inject private CustomInterceptorState interceptionStateHolder; @AroundInvoke public Object interceptIt(InvocationContext invocationContext) throws Exception { interceptionStateHolder.setIntercepted(true); return invocationContext.proceed(); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/CustomInterceptorState.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class CustomInterceptorState { private boolean intercepted; public boolean isIntercepted() { return intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/TestBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class TestBean { public String getValue() { return "test"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/TestInterceptorAware.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; /** * Just needed for testing interceptors */ public interface TestInterceptorAware { void setIntercepted(boolean intercepted); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/TestPartialBeanBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @PartialBeanBinding @Retention(RUNTIME) @Target(TYPE) public @interface TestPartialBeanBinding { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/ThrowExceptionPartialBeanBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @PartialBeanBinding @Retention(RUNTIME) @Target(TYPE) public @interface ThrowExceptionPartialBeanBinding { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/shared/ThrowExceptionPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.shared; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import jakarta.enterprise.context.ApplicationScoped; @ThrowExceptionPartialBeanBinding @ApplicationScoped public class ThrowExceptionPartialBeanHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw new ClassNotFoundException(); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc001/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc001; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.RequestScoped; @TestPartialBeanBinding @RequestScoped public interface PartialBean { String getResult(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc001/PartialBeanAsInterfaceEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc001; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class PartialBeanAsInterfaceEarFileTest extends PartialBeanAsInterfaceTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = PartialBeanAsInterfaceWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(PartialBeanAsInterfaceWarFileTest.deploy()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc001/PartialBeanAsInterfaceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc001; import org.junit.Assert; import org.junit.Test; import jakarta.inject.Inject; public abstract class PartialBeanAsInterfaceTest { @Inject private PartialBean partialBean; @Test public void testPartialBeanAsInterface() throws Exception { String result = this.partialBean.getResult(); Assert.assertEquals("partial-test-false", result); //TODO test pre-destroy callback } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc001/PartialBeanAsInterfaceWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc001; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class PartialBeanAsInterfaceWarFileTest extends PartialBeanAsInterfaceTest { @Deployment public static WebArchive deploy() { String simpleName = PartialBeanAsInterfaceWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(PartialBeanAsInterfaceWarFileTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc001/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc001; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } @Override public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc002/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc002; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; @TestPartialBeanBinding @RequestScoped public abstract class PartialBean { @Inject private TestBean testBean; private String value; public abstract String getResult(String value); @PostConstruct protected void onCreate() { this.value = "manual"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public String getManualResult() { return this.value + "-" + this.testBean.getValue(); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc002/PartialBeanAsAbstractClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc002; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; @RunWith(Arquillian.class) public class PartialBeanAsAbstractClassTest { @Inject private PartialBean partialBean; @Deployment public static WebArchive war() { String simpleName = PartialBeanAsAbstractClassTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(PartialBeanAsAbstractClassTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test public void testPartialBeanAsAbstractClass() throws Exception { String result = this.partialBean.getResult("test"); Assert.assertEquals("partial-test-false", result); result = this.partialBean.getManualResult(); Assert.assertEquals("manual-test", result); //TODO test pre-destroy callback } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc002/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc002; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc003/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc003; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; @TestPartialBeanBinding @ApplicationScoped public interface PartialBean extends SuperInterface, SuperInterface2 { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc003/PartialBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc003; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class PartialBeanTest { private static final String CONTAINER_OWB_1_2_x_BEFORE_1_2_8 = "owb-1\\.2\\.[0-7]"; private static final String CONTAINER_TOMEE_1_7_x = "tomee-1\\.7\\..*"; @Deployment public static WebArchive war() { String simpleName = PartialBeanTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(PartialBeanTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test public void testPartialBeanWithApplicationScope() throws Exception { // this test is known to not work under OWB 1.2.0 till 1.2.7 - see OWB #1036 Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_OWB_1_2_x_BEFORE_1_2_8) && !CdiContainerUnderTest.is(CONTAINER_TOMEE_1_7_x)); PartialBean bean = BeanProvider.getContextualReference(PartialBean.class); bean.test(this); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc003/SuperInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc003; public interface SuperInterface { E test(E entity); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc003/SuperInterface2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc003; public interface SuperInterface2 { E test(E entity); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc003/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc003; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/AbstractSuper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; public abstract class AbstractSuper implements SuperInterface { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/ApplicationScopedPartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.ApplicationScoped; @TestPartialBeanBinding @ApplicationScoped public abstract class ApplicationScopedPartialBean extends AbstractSuper { private int count; public abstract String getResult(); public int getManualResult() { return count++; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/DependentScopedPartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; @TestPartialBeanBinding public abstract class DependentScopedPartialBean { private int count; public abstract String getResult(); public int getManualResult() { return count++; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/ScopedPartialBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.BeansXmlUtil; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ScopedPartialBeanTest { @Deployment public static WebArchive war() { String simpleName = ScopedPartialBeanTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ScopedPartialBeanTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return webArchive; } @Test public void testPartialBeanWithApplicationScope() throws Exception { ApplicationScopedPartialBean bean = BeanProvider.getContextualReference(ApplicationScopedPartialBean.class); String result = bean.getResult(); Assert.assertEquals("partial-test-false", result); int count = bean.getManualResult(); Assert.assertEquals(0, count); count = bean.getManualResult(); Assert.assertEquals(1, count); } @Test public void testPartialBeanWithDependentScope() throws Exception { String result = BeanProvider.getContextualReference(DependentScopedPartialBean.class).getResult(); Assert.assertEquals("partial-test-false", result); int count = BeanProvider.getContextualReference(DependentScopedPartialBean.class).getManualResult(); Assert.assertEquals(0, count); count = BeanProvider.getContextualReference(DependentScopedPartialBean.class).getManualResult(); Assert.assertEquals(0, count); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/SuperInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; public interface SuperInterface { String willFail(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc004/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc004; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc005/AbstractSuper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc005; public abstract class AbstractSuper { public abstract String willFail2(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc005/ApplicationScopedPartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc005; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; @TestPartialBeanBinding @ApplicationScoped public abstract class ApplicationScopedPartialBean extends AbstractSuper implements SuperInterface { private int count; public abstract String getResult(); public int getManualResult() { return count++; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc005/ScopedPartialBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc005; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class ScopedPartialBeanTest { private static final String CONTAINER_OWB_1_2_x_BEFORE_1_2_8 = "owb-1\\.2\\.[0-7]"; private static final String CONTAINER_TOMEE_1_7_x = "tomee-1\\.7\\..*"; @Deployment public static WebArchive war() { String simpleName = ScopedPartialBeanTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ScopedPartialBeanTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test public void testPartialBeanWithApplicationScope() throws Exception { // this test is known to not work under OWB 1.2.0 till 1.2.7 - see OWB #1036 Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_OWB_1_2_x_BEFORE_1_2_8) && !CdiContainerUnderTest.is(CONTAINER_TOMEE_1_7_x)); ApplicationScopedPartialBean bean = BeanProvider.getContextualReference(ApplicationScopedPartialBean.class); String result = bean.willFail(); Assert.assertEquals("partial-test-false", result); String result2 = bean.willFail2(); Assert.assertEquals("partial-test-false", result2); int count = bean.getManualResult(); Assert.assertEquals(0, count); count = bean.getManualResult(); Assert.assertEquals(1, count); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc005/SuperInterface.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc005; public interface SuperInterface { String willFail(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc005/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc005; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc006/AbstractSuper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc006; public abstract class AbstractSuper extends AbstractSuperSuper { public abstract T willFail2() throws Throwable; @Override public String willFail3() throws RuntimeException, ClassNotFoundException, NoSuchMethodException, NoSuchFieldException { return "willFail3"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc006/AbstractSuperSuper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc006; public abstract class AbstractSuperSuper { public abstract String willFail3() throws Throwable; } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc006/ApplicationScopedPartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc006; import org.apache.deltaspike.test.core.api.partialbean.shared.ThrowExceptionPartialBeanBinding; import jakarta.enterprise.context.ApplicationScoped; @ThrowExceptionPartialBeanBinding @ApplicationScoped public abstract class ApplicationScopedPartialBean extends AbstractSuper { private int count; public abstract String getResult(); public int getManualResult() { return count++; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc006/ScopedPartialBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc006; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class ScopedPartialBeanTest { @Deployment public static WebArchive war() { final String simpleName = ScopedPartialBeanTest.class.getSimpleName(); final String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); final JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ScopedPartialBeanTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test public void testPartialBeanWithApplicationScope() throws Throwable { ApplicationScopedPartialBean bean = BeanProvider.getContextualReference(ApplicationScopedPartialBean.class); bean.getManualResult(); Assert.assertEquals("willFail3", bean.willFail3()); try { bean.willFail2(); Assert.fail("#willFail2 should actually throw a ClassNotFoundException"); } catch (Exception e) { Assert.assertEquals(e.getClass(), ClassNotFoundException.class); } } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc006/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc006; import org.apache.deltaspike.test.core.api.partialbean.shared.TestBean; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import org.apache.deltaspike.test.core.api.partialbean.shared.TestInterceptorAware; @TestPartialBeanBinding @Dependent //normal-scopes are possible as well public class TestPartialBeanHandler implements InvocationHandler, /*just needed for testing interceptors: */TestInterceptorAware { @Inject private TestBean testBean; private String value; private boolean intercepted; @PostConstruct protected void onCreate() { this.value = "partial"; } @PreDestroy protected void onDestroy() { //TODO check in a test } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return this.value + "-" + this.testBean.getValue() + "-" + this.intercepted; } public void setIntercepted(boolean intercepted) { this.intercepted = intercepted; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc007/CustomInterceptorStereotype.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc007; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import jakarta.enterprise.inject.Stereotype; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptor; @Inherited @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) @Stereotype @CustomInterceptor public @interface CustomInterceptorStereotype { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc007/MethodLevelInterceptorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc007; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptorImpl; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptorState; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class MethodLevelInterceptorTest { public static final String CONTAINER_WELD_5_0 = "weld-5\\.0\\..*"; @Deployment public static WebArchive war() { Asset beansXml = new StringAsset( "" + CustomInterceptorImpl.class.getName() + "" ); String simpleName = MethodLevelInterceptorTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); //don't create a completely empty web-archive if (CdiContainerUnderTest.is(CONTAINER_WELD_5_0)) { return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()); } JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(MethodLevelInterceptorTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(beansXml, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(beansXml, "beans.xml"); } @Test public void testMethodLevelInterceptor() throws Exception { // this test is known to not work under weld-5.0.x Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD_5_0)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc007.PartialBean") == null) { return; } PartialBean partialBean = BeanProvider.getContextualReference(PartialBean.class); CustomInterceptorState state = BeanProvider.getContextualReference(CustomInterceptorState.class); Assert.assertNotNull(partialBean); partialBean.doSomething(); Assert.assertEquals(true, state.isIntercepted()); } @Test public void testMethodLevelInterceptorStereotype() throws Exception { // this test is known to not work under weld-5.0.x Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD_5_0)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc007.PartialBean") == null) { return; } PartialBean partialBean = BeanProvider.getContextualReference(PartialBean.class); CustomInterceptorState state = BeanProvider.getContextualReference(CustomInterceptorState.class); Assert.assertNotNull(partialBean); partialBean.doSomething2(); Assert.assertEquals(true, state.isIntercepted()); } @Test public void testMethodLevelInterceptorOnAbstractMethod() throws Exception { // this test is known to not work under weld-5.0.x Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD_5_0)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc007.PartialBean") == null) { return; } PartialBean partialBean = BeanProvider.getContextualReference(PartialBean.class); CustomInterceptorState state = BeanProvider.getContextualReference(CustomInterceptorState.class); Assert.assertNotNull(partialBean); Assert.assertEquals("partial", partialBean.getResult()); Assert.assertEquals(true, state.isIntercepted()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc007/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc007; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.RequestScoped; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptor; @TestPartialBeanBinding @RequestScoped public abstract class PartialBean { @CustomInterceptor public abstract String getResult(); @CustomInterceptor public void doSomething() { String a = "test"; } @CustomInterceptorStereotype public void doSomething2() { String a = "test2"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc007/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc007; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import jakarta.enterprise.context.ApplicationScoped; @TestPartialBeanBinding @ApplicationScoped public class TestPartialBeanHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return "partial"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc008/ClassLevelInterceptorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc008; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptorImpl; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptorState; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class ClassLevelInterceptorTest { public static final String CONTAINER_WELD_5_0 = "weld-5\\.0\\..*"; @Deployment public static WebArchive war() { Asset beansXml = new StringAsset( "" + CustomInterceptorImpl.class.getName() + "" ); String simpleName = ClassLevelInterceptorTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); //don't create a completely empty web-archive if (CdiContainerUnderTest.is(CONTAINER_WELD_5_0)) { return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()); } JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ClassLevelInterceptorTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(beansXml, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(beansXml, "beans.xml"); } @Test public void testClassLevelInterceptor() throws Exception { // this test is known to not work under weld-5.0.x Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD_5_0)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc008.PartialBean") == null) { return; } PartialBean partialBean = BeanProvider.getContextualReference(PartialBean.class); CustomInterceptorState state = BeanProvider.getContextualReference(CustomInterceptorState.class); Assert.assertNotNull(partialBean); Assert.assertEquals("manual", partialBean.getManualResult()); Assert.assertTrue(state.isIntercepted()); } @Test public void testClassLevelInterceptorOnAbstractMethod() throws Exception { // this test is known to not work under weld-5.0.x Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD_5_0)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc008.PartialBean") == null) { return; } PartialBean partialBean = BeanProvider.getContextualReference(PartialBean.class, true); CustomInterceptorState state = BeanProvider.getContextualReference(CustomInterceptorState.class); Assert.assertNotNull(partialBean); Assert.assertEquals("partial", partialBean.getResult()); Assert.assertTrue(state.isIntercepted()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc008/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc008; import org.apache.deltaspike.test.core.api.partialbean.shared.CustomInterceptor; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.RequestScoped; @CustomInterceptor @TestPartialBeanBinding @RequestScoped public abstract class PartialBean { public abstract String getResult(); public String getManualResult() { return "manual"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc008/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc008; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import jakarta.enterprise.context.ApplicationScoped; @TestPartialBeanBinding @ApplicationScoped public class TestPartialBeanHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return "partial"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class PartialBeanWithProducerEarFileTest extends PartialBeanWithProducerTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = PartialBeanWithProducerWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(PartialBeanWithProducerWarFileTest.deploy()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import org.junit.Assert; import org.junit.Test; import jakarta.inject.Inject; public abstract class PartialBeanWithProducerTest { @Inject private TestConfig testConfig; @Inject @TestValue private String value2; @Inject private TestCustomType value4; @Test public void testPartialBeanWithProducerManualAccess() throws Exception { Assert.assertEquals(new Integer(1), testConfig.value1()); Assert.assertEquals("2", testConfig.value2()); Assert.assertEquals(new Integer(3), testConfig.value3()); Assert.assertEquals(new Integer(4), testConfig.value4().getTestValue()); } @Test public void testProducedResultOfPartialBeanWithProducer() throws Exception { Assert.assertEquals("2", value2); Assert.assertEquals(new Integer(4), value4.getTestValue()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/PartialBeanWithProducerWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.BeansXmlUtil; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class PartialBeanWithProducerWarFileTest extends PartialBeanWithProducerTest { @Deployment public static WebArchive deploy() { String simpleName = PartialBeanWithProducerWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(PartialBeanWithProducerWarFileTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import jakarta.enterprise.inject.Produces; public interface TestBaseConfig { Integer value1(); @Produces @TestValue String value2(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.inject.Produces; @TestTypeSafeConfig public interface TestConfig extends TestBaseConfig { Integer value3(); @Produces @SessionScoped TestCustomType value4(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestCustomType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import jakarta.enterprise.inject.Vetoed; import java.io.Serializable; @Vetoed public class TestCustomType implements Serializable { private Integer testValue; public static TestCustomType parse(String value) { TestCustomType result = new TestCustomType(); result.testValue = Integer.parseInt(value); return result; } public Integer getTestValue() { return testValue; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @PartialBeanBinding @Retention(RUNTIME) @Target(TYPE) public @interface TestTypeSafeConfig { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestTypeSafeConfigHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestTypeSafeConfig @SuppressWarnings("unused") public class TestTypeSafeConfigHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String stringValue = getTestValue(method.getName()); Object parsedValue = null; final Class configType = method.getReturnType(); if (configType.equals(Integer.class)) { parsedValue = Integer.parseInt(stringValue); } else if (configType.equals(String.class)) { parsedValue = stringValue; } else if (configType.equals(TestCustomType.class)) { parsedValue = TestCustomType.parse(stringValue); } return parsedValue; } private String getTestValue(String methodName) { return methodName.replace("value", ""); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc009/TestValue.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc009; import jakarta.inject.Qualifier; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({METHOD, FIELD}) @Retention(RUNTIME) @Qualifier public @interface TestValue { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc010/PartialBeanAsAbstractClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc010; import jakarta.enterprise.inject.spi.BeanManager; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import org.apache.deltaspike.partialbean.impl.PartialBeanProxyFactory; import org.apache.deltaspike.test.core.api.partialbean.uc010.PartialBeanWrapper.PartialBean; @RunWith(Arquillian.class) public class PartialBeanAsAbstractClassTest { @Inject private PartialBean partialBean; @Inject private BeanManager beanManager; @Deployment public static WebArchive war() { String simpleName = PartialBeanAsAbstractClassTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(PartialBeanAsAbstractClassTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test public void testDuplicateProxyGeneration() throws Exception { this.partialBean.getResult("test"); PartialBeanProxyFactory.getInstance().getProxyClass( beanManager, PartialBean.class); PartialBeanProxyFactory.getInstance().getProxyClass( beanManager, PartialBean.class); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc010/PartialBeanWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc010; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; @ApplicationScoped public class PartialBeanWrapper { @TestPartialBeanBinding @RequestScoped public interface PartialBean { String getResult(String value); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc010/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc010; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import jakarta.enterprise.context.ApplicationScoped; @TestPartialBeanBinding @ApplicationScoped public class TestPartialBeanHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc011/BaseRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc011; import java.io.Serializable; public abstract class BaseRepository implements EntityRepository, Serializable { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc011/CustomerRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc011; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; @TestPartialBeanBinding @ApplicationScoped public abstract class CustomerRepository extends BaseRepository { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc011/EntityRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc011; import java.io.Serializable; public interface EntityRepository { E save(E entity); E findBy(PK primaryKey); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc011/ScopedPartialBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc011; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class ScopedPartialBeanTest { @Deployment public static WebArchive war() { final String simpleName = ScopedPartialBeanTest.class.getSimpleName(); final String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); final JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ScopedPartialBeanTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); return webArchive; } @Test @Ignore("Test to demonstrate WELD-2084") public void testPartialBeanWithApplicationScope() throws Throwable { CustomerRepository repository = BeanProvider.getContextualReference(CustomerRepository.class); repository.save(null); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc011/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc011; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import jakarta.enterprise.context.Dependent; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @TestPartialBeanBinding @Dependent public class TestPartialBeanHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/BlockPolicy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc012; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; public class BlockPolicy implements RejectedExecutionHandler { @Override public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) { try { executor.getQueue().put(runnable); } catch (InterruptedException interruptedException) { Thread.currentThread().interrupt(); } } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/ConcurrencyBugTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc012; import jakarta.inject.Inject; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.SECONDS; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ConcurrencyBugTest { @Deployment public static WebArchive war() { final String simpleName = ConcurrencyBugTest.class.getSimpleName(); final String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); final JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(ConcurrencyBugTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); final WebArchive webArchive = ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsWebInfResource(BEANS_XML_ALL, "beans.xml"); return webArchive; } @Inject private PartialBean bean; @Test public void testWithConcurrency() throws Exception { ThreadFactory threadFactory = Executors.defaultThreadFactory(); ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, SECONDS, new SynchronousQueue(), threadFactory, new BlockPolicy()); int iterations = 100; List> results = new ArrayList>(iterations); for (int i = 0; i < iterations; i++) { results.add(executor.submit(new BeanCaller(bean))); } executor.shutdown(); executor.awaitTermination(60, SECONDS); for (int i = 0; i < iterations; i++) { results.get(i).get(); } } private class BeanCaller implements Callable { private final PartialBean partialBean; private BeanCaller(PartialBean partialBean) { this.partialBean = partialBean; } @Override public String call() { try { return partialBean.getValue(); } catch (NullPointerException e) { e.printStackTrace(); throw e; } } } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc012; import org.apache.deltaspike.partialbean.api.PartialBeanBinding; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; @PartialBeanBinding @Retention(RUNTIME) public @interface MyPartialBeanBinding { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/MyPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc012; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @MyPartialBeanBinding public class MyPartialBeanHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.getName(); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc012/PartialBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc012; import jakarta.enterprise.context.ApplicationScoped; @MyPartialBeanBinding @ApplicationScoped public interface PartialBean { String getValue(); } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/MethodLevelInterceptorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import jakarta.enterprise.inject.spi.Extension; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import org.apache.deltaspike.test.core.api.partialbean.util.ArchiveUtils; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; @RunWith(Arquillian.class) public class MethodLevelInterceptorTest { public static final String CONTAINER_WELD = "weld-.*"; @Deployment public static WebArchive war() { Asset beansXml = new StringAsset( "" + SimpleCacheInterceptor.class.getName() + "" ); String simpleName = MethodLevelInterceptorTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); //don't create a completely empty web-archive if (CdiContainerUnderTest.is(CONTAINER_WELD)) { return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()); } JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar") .addPackage(MethodLevelInterceptorTest.class.getPackage()) .addPackage(TestPartialBeanBinding.class.getPackage()) .addAsManifestResource(beansXml, "beans.xml"); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndPartialBeanArchive()) .addAsLibraries(testJar) .addAsServiceProvider(Extension.class, SimpleCacheExtension.class) .addAsWebInfResource(beansXml, "beans.xml"); } @Test public void testMethodLevelInterceptor() throws Exception { // this test is known to not work under weld Assume.assumeTrue(!CdiContainerUnderTest.is(CONTAINER_WELD)); // workaround as payara doesnt pass cdicontainer.version to the arquillian process if (ClassUtils.tryToLoadClassForName("org.apache.deltaspike.test.core.api.partialbean.uc013.MyRepository") == null) { return; } MyRepository myRepository = BeanProvider.getContextualReference(MyRepository.class); List users = myRepository.getAllUsers(); Assert.assertNotNull(users); Assert.assertEquals(3, users.size()); Assert.assertSame(users, myRepository.getAllUsers()); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/MyRepository.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import java.util.ArrayList; import java.util.List; import jakarta.enterprise.context.ApplicationScoped; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; @TestPartialBeanBinding @ApplicationScoped public abstract class MyRepository { @SimpleCache public List getAllUsers() { ArrayList users = new ArrayList<>(); users.add("Me"); users.add("You"); users.add("Anyone"); return users; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/SimpleCache.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) public @interface SimpleCache { } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/SimpleCacheExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; public class SimpleCacheExtension implements Extension { void discoverInterceptorBindings(@Observes BeforeBeanDiscovery beforeBeanDiscoveryEvent) { beforeBeanDiscoveryEvent.addInterceptorBinding(SimpleCache.class); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/SimpleCacheInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import java.io.Serializable; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; @Interceptor @SimpleCache public class SimpleCacheInterceptor implements Serializable { @Inject private SimpleCacheManager scm; @AroundInvoke public Object wrapBeanCandidate(InvocationContext invocationContext) throws Exception { if (scm.getSingletonCache().containsKey(invocationContext.getMethod())) { return scm.getSingletonCache().get(invocationContext.getMethod()); } Object result = invocationContext.proceed(); scm.getSingletonCache().put(invocationContext.getMethod(), result); return result; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/SimpleCacheManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class SimpleCacheManager { private Map singletonCache; @PostConstruct public void init() { singletonCache = new HashMap<>(); } public Map getSingletonCache() { return singletonCache; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/uc013/TestPartialBeanHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.uc013; import org.apache.deltaspike.test.core.api.partialbean.shared.TestPartialBeanBinding; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import jakarta.enterprise.context.ApplicationScoped; @TestPartialBeanBinding @ApplicationScoped public class TestPartialBeanHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return "partial"; } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/java/org/apache/deltaspike/test/core/api/partialbean/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.core.api.partialbean.util; import java.util.ArrayList; import java.util.Arrays; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.spec.JavaArchive; public abstract class ArchiveUtils { private ArchiveUtils() { } public static JavaArchive[] getDeltaSpikeCoreAndPartialBeanArchive() { ArrayList result = new ArrayList(); JavaArchive[] temp; temp = ShrinkWrapArchiveUtil.getArchives(null, "META-INF/beans.xml", new String[] { "org.apache.deltaspike.core", "org.apache.deltaspike.proxy", "org.apache.deltaspike.test.category", "org.apache.deltaspike.partialbean" }, new String[] { "META-INF.apache-deltaspike.properties" }, "ds-core_proxy_and_partial-bean"); result.addAll(Arrays.asList(temp)); return result.toArray(new JavaArchive[result.size()]); } } ================================================ FILE: deltaspike/modules/partial-bean/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/partial-bean/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules partial-bean-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Partial-Bean-Module api impl ================================================ FILE: deltaspike/modules/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent-code 2.0.2-SNAPSHOT ../parent/code/pom.xml org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Modules proxy security jsf partial-bean jpa data scheduler test-control test-control5 ================================================ FILE: deltaspike/modules/proxy/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules proxy-module-project 2.0.2-SNAPSHOT deltaspike-proxy-module-api jar Apache DeltaSpike Proxy-Module API org.apache.deltaspike.proxy.* * org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.felix maven-bundle-plugin OSGI-INF/* ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyBeanConfigurator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.api; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Set; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionTarget; import jakarta.enterprise.inject.spi.PassivationCapable; import jakarta.enterprise.inject.spi.configurator.BeanConfigurator; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; import org.apache.deltaspike.proxy.spi.invocation.DeltaSpikeProxyInvocationHandler; /** * {@link ContextualLifecycle} which handles a complete lifecycle of a proxy: * - creates a proxy via a {@link DeltaSpikeProxyFactory} * - handles the instantiation and injection of the proxy * - handles the instantiation via CDI of the delegate {@link InvocationHandler} and assign it to the proxy * - handles the release/destruction of both proxy and delegate {@link InvocationHandler} * * @param The class of the original class. * @param The class of the delegate {@link InvocationHandler}. */ public class DeltaSpikeProxyBeanConfigurator { private final Class proxyClass; private final Class delegateInvocationHandlerClass; private final Method[] delegateMethods; private final Class targetClass; private final BeanManager beanManager; private final BeanConfigurator beanConfigurator; private volatile DeltaSpikeProxyInvocationHandler deltaSpikeProxyInvocationHandler; private volatile InjectionTarget injectionTarget; private volatile Bean handlerBean; private volatile CreationalContext creationalContextOfDependentHandler; public DeltaSpikeProxyBeanConfigurator(Class targetClass, Class delegateInvocationHandlerClass, DeltaSpikeProxyFactory proxyFactory, BeanManager beanManager, BeanConfigurator beanConfigurator) { this.targetClass = targetClass; this.delegateInvocationHandlerClass = delegateInvocationHandlerClass; this.proxyClass = proxyFactory.getProxyClass(beanManager, targetClass); this.delegateMethods = proxyFactory.getDelegateMethods(targetClass); this.beanManager = beanManager; if (!targetClass.isInterface()) { AnnotatedType annotatedType = beanManager.createAnnotatedType(this.targetClass); this.injectionTarget = beanManager.getInjectionTargetFactory(annotatedType).createInjectionTarget(null); } this.beanConfigurator = beanConfigurator; } public DeltaSpikeProxyBeanConfigurator delegateCreateWith() { beanConfigurator.createWith((c) -> create(c)); return this; } public DeltaSpikeProxyBeanConfigurator delegateDestroyWith() { beanConfigurator.destroyWith((i, c) -> destroy(i, c)); return this; } protected T create(CreationalContext creationalContext) { try { lazyInit(); T instance = proxyClass.newInstance(); DeltaSpikeProxy deltaSpikeProxy = ((DeltaSpikeProxy) instance); deltaSpikeProxy.setInvocationHandler(deltaSpikeProxyInvocationHandler); // optional if (delegateInvocationHandlerClass != null) { H delegateInvocationHandler = instantiateDelegateInvocationHandler(); deltaSpikeProxy.setDelegateInvocationHandler(delegateInvocationHandler); deltaSpikeProxy.setDelegateMethods(delegateMethods); } if (this.injectionTarget != null) { this.injectionTarget.inject(instance, creationalContext); this.injectionTarget.postConstruct(instance); } return instance; } catch (Exception e) { ExceptionUtils.throwAsRuntimeException(e); } // can't happen return null; } protected void destroy(T instance, CreationalContext creationalContext) { if (this.injectionTarget != null) { this.injectionTarget.preDestroy(instance); } if (this.creationalContextOfDependentHandler != null) { this.creationalContextOfDependentHandler.release(); } creationalContext.release(); } private void lazyInit() { if (this.deltaSpikeProxyInvocationHandler == null) { init(); } } private synchronized void init() { if (this.deltaSpikeProxyInvocationHandler == null) { Set> handlerBeans = BeanProvider.getBeanDefinitions( delegateInvocationHandlerClass, false, true, beanManager); if (handlerBeans.size() != 1) { StringBuilder beanInfo = new StringBuilder(); for (Bean bean : handlerBeans) { if (beanInfo.length() != 0) { beanInfo.append(", "); } beanInfo.append(bean); if (bean instanceof PassivationCapable) { beanInfo.append(" bean-id: ").append(((PassivationCapable) bean).getId()); } } throw new IllegalStateException(handlerBeans.size() + " beans found for " + delegateInvocationHandlerClass + " found beans: " + beanInfo.toString()); } this.handlerBean = handlerBeans.iterator().next(); this.deltaSpikeProxyInvocationHandler = BeanProvider.getContextualReference( beanManager, DeltaSpikeProxyInvocationHandler.class, false); } } protected H instantiateDelegateInvocationHandler() { CreationalContext creationalContext = beanManager.createCreationalContext(handlerBean); H handlerInstance = (H) beanManager.getReference(handlerBean, this.delegateInvocationHandlerClass, creationalContext); if (handlerBean.getScope().equals(Dependent.class)) { this.creationalContextOfDependentHandler = creationalContext; } return handlerInstance; } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.api; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import jakarta.enterprise.inject.spi.BeanManager; import java.util.Set; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ReflectionUtils; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGeneratorHolder; public abstract class DeltaSpikeProxyFactory { private static final String SUPER_ACCESSOR_METHOD_SUFFIX = "$super"; private Class resolveAlreadyDefinedProxyClass(Class targetClass) { Class proxyClass = ClassUtils.tryToLoadClassForName(constructProxyClassName(targetClass), targetClass, targetClass.getClassLoader()); return proxyClass; } public Class getProxyClass(BeanManager beanManager, Class targetClass) { // check if a proxy is already defined for this class Class proxyClass = resolveAlreadyDefinedProxyClass(targetClass); if (proxyClass == null) { proxyClass = createProxyClass(beanManager, targetClass.getClassLoader(), targetClass); } return proxyClass; } private synchronized Class createProxyClass(BeanManager beanManager, ClassLoader classLoader, Class targetClass) { Class proxyClass = resolveAlreadyDefinedProxyClass(targetClass); if (proxyClass == null) { ArrayList allMethods = collectAllMethods(targetClass); ArrayList interceptMethods = filterInterceptMethods(targetClass, allMethods); Method[] delegateMethods = getDelegateMethods(targetClass); // check if a interceptor is defined on class level. if not, skip interceptor methods if (interceptMethods != null && !interceptMethods.isEmpty() && !containsInterceptorBinding(beanManager, targetClass.getDeclaredAnnotations())) { // loop every method and check if a interceptor is defined on the method -> otherwise don't overwrite // interceptMethods Iterator iterator = interceptMethods.iterator(); while (iterator.hasNext()) { Method method = iterator.next(); if (!containsInterceptorBinding(beanManager, method.getDeclaredAnnotations())) { iterator.remove(); } } } DeltaSpikeProxyClassGenerator proxyClassGenerator = DeltaSpikeProxyClassGeneratorHolder.lookup(); proxyClass = proxyClassGenerator.generateProxyClass(classLoader, targetClass, getProxyClassSuffix(), SUPER_ACCESSOR_METHOD_SUFFIX, getAdditionalInterfacesToImplement(targetClass), delegateMethods, interceptMethods == null ? new Method[0] : interceptMethods.toArray(new Method[interceptMethods.size()])); } return proxyClass; } private boolean containsInterceptorBinding(BeanManager beanManager, Annotation[] annotations) { for (Annotation annotation : annotations) { Class annotationType = annotation.annotationType(); if (beanManager.isInterceptorBinding(annotationType)) { return true; } if (beanManager.isStereotype(annotationType)) { boolean containsInterceptorBinding = containsInterceptorBinding( beanManager, annotationType.getDeclaredAnnotations()); if (containsInterceptorBinding) { return true; } } } return false; } private String constructProxyClassName(Class clazz) { return clazz.getName() + getProxyClassSuffix(); } private static String constructSuperAccessorMethodName(Method method) { return method.getName() + SUPER_ACCESSOR_METHOD_SUFFIX; } public static Method getSuperAccessorMethod(Object proxy, Method method) throws NoSuchMethodException { return proxy.getClass().getMethod( constructSuperAccessorMethodName(method), method.getParameterTypes()); } /** * Checks if the given class is DS proxy class. * * @param clazz * @return */ public boolean isProxyClass(Class clazz) { return clazz.getName().endsWith(getProxyClassSuffix()); } private boolean ignoreMethod(Method method, List methods) { // we have no interest in generics bridge methods if (method.isBridge()) { return true; } // we do not proxy finalize() if ("finalize".equals(method.getName())) { return true; } // same method... if (methods.contains(method)) { return true; } // check if a method with the same signature is already available for (Method currentMethod : methods) { if (ReflectionUtils.hasSameSignature(currentMethod, method)) { return true; } } return false; } protected ArrayList collectAllMethods(Class clazz) { ArrayList methods = new ArrayList<>(); Set abstractMethodLeaves = new HashSet<>(); for (Method method : clazz.getMethods()) { if (!ignoreMethod(method, methods)) { methods.add(method); if (Modifier.isAbstract(method.getModifiers())) { abstractMethodLeaves.add(method); } } } for (Method method : clazz.getDeclaredMethods()) { if (!ignoreMethod(method, methods)) { methods.add(method); } } // collect methods from abstract super classes... Class currentSuperClass = clazz.getSuperclass(); while (currentSuperClass != null) { if (Modifier.isAbstract(currentSuperClass.getModifiers())) { for (Method method : currentSuperClass.getDeclaredMethods()) { if (!ignoreMethod(method, methods)) { methods.add(method); } } for (Method method : currentSuperClass.getMethods()) { if (!ignoreMethod(method, methods)) { methods.add(method); } } } currentSuperClass = currentSuperClass.getSuperclass(); } // sort out somewhere implemented abstract methods Class currentClass = clazz; while (currentClass != null) { Iterator methodIterator = methods.iterator(); while (methodIterator.hasNext()) { Method method = methodIterator.next(); if (Modifier.isAbstract(method.getModifiers()) && !abstractMethodLeaves.contains(method)) { try { Method foundMethod = currentClass.getMethod(method.getName(), method.getParameterTypes()); // if method is implementent in the current class -> remove it if (foundMethod != null && !Modifier.isAbstract(foundMethod.getModifiers())) { methodIterator.remove(); } } catch (Exception e) { // ignore... } } } currentClass = currentClass.getSuperclass(); } return methods; } protected ArrayList filterInterceptMethods(Class targetClass, ArrayList allMethods) { ArrayList methods = new ArrayList<>(); Iterator it = allMethods.iterator(); while (it.hasNext()) { Method method = it.next(); if (Modifier.isPublic(method.getModifiers()) && !Modifier.isFinal(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers())) { methods.add(method); } } return methods; } protected Class[] getAdditionalInterfacesToImplement(Class targetClass) { return null; } protected abstract ArrayList getDelegateMethods(Class targetClass, ArrayList allMethods); protected abstract String getProxyClassSuffix(); public Method[] getDelegateMethods(Class targetClass) { ArrayList allMethods = collectAllMethods(targetClass); ArrayList delegateMethods = getDelegateMethods(targetClass, allMethods); if (delegateMethods == null) { return new Method[0]; } return delegateMethods.toArray(new Method[delegateMethods.size()]); } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import org.apache.deltaspike.proxy.spi.invocation.DeltaSpikeProxyInvocationHandler; /** * Interface which will automatically be implemented by the proxy instance. */ public interface DeltaSpikeProxy { void setInvocationHandler(DeltaSpikeProxyInvocationHandler invocationHandler); DeltaSpikeProxyInvocationHandler getInvocationHandler(); void setDelegateInvocationHandler(InvocationHandler delegateInvocationHandler); InvocationHandler getDelegateInvocationHandler(); void setDelegateMethods(Method[] methods); Method[] getDelegateMethods(); } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxyClassGenerator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi; public interface DeltaSpikeProxyClassGenerator { /** * Generates a proxy class from the given source class, which also implements {@link DeltaSpikeProxy}. * The proxy class will be generated in the same package as the original class * and the suffix will be appended to the name of the class. * * @param The target class. * @param classLoader The {@link ClassLoader} to be used to define the proxy class. * @param targetClass The class to proxy. * @param suffix The classname suffix. * @param superAccessorMethodSuffix It's required to generate methods which just invokes the original method. * We generate them with the same name as the original method * and append the suffix. * @param additionalInterfaces Additional interfaces which should be implemented. * Please note that you must also pass new methods via delegateMethods. * @param delegateMethods Methods which should be delegated to the * {@link DeltaSpikeProxy#getDelegateInvocationHandler()} * instead of invoking the original method. * @param interceptMethods Methods which should be intercepted (to call interceptors or decorators) * before invoking the original method. * @return The generated proxy class. */ Class generateProxyClass(ClassLoader classLoader, Class targetClass, String suffix, String superAccessorMethodSuffix, Class[] additionalInterfaces, java.lang.reflect.Method[] delegateMethods, java.lang.reflect.Method[] interceptMethods); } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/DeltaSpikeProxyClassGeneratorHolder.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi; import java.util.List; import org.apache.deltaspike.core.util.ServiceUtils; // TODO it would be great if we could just rewrite it to an AppScoped bean public class DeltaSpikeProxyClassGeneratorHolder { private static DeltaSpikeProxyClassGenerator generator; /** * Setter invoked by OSGi Service Component Runtime. * * @param generator generator service */ public void setGenerator(DeltaSpikeProxyClassGenerator generator) { this.generator = generator; } /** * Looks up a unique service implementation. * * @return ProxyClassGenerator service */ public static DeltaSpikeProxyClassGenerator lookup() { if (generator == null) { List proxyClassGeneratorList = ServiceUtils.loadServiceImplementations(DeltaSpikeProxyClassGenerator.class); if (proxyClassGeneratorList.size() != 1) { throw new IllegalStateException(proxyClassGeneratorList.size() + " implementations of " + DeltaSpikeProxyClassGenerator.class.getName() + " found. Expected exactly one implementation."); } generator = proxyClassGeneratorList.get(0); } return generator; } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/invocation/DeltaSpikeProxyInterceptorLookup.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi.invocation; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InterceptionType; import jakarta.enterprise.inject.spi.Interceptor; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; /** * Utility which stores the information about configured interceptors for each method. */ @ApplicationScoped public class DeltaSpikeProxyInterceptorLookup { private final Map>> cache = new HashMap<>(); public List> lookup(Object instance, Method method) { List> interceptors = cache.get(method); if (interceptors == null) { interceptors = resolveInterceptors(instance, method); cache.put(method, interceptors); } return interceptors; } private List> resolveInterceptors(Object instance, Method method) { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Annotation[] interceptorBindings = extractInterceptorBindings(beanManager, instance, method); if (interceptorBindings.length > 0) { return beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE, interceptorBindings); } return new ArrayList<>(); } private Annotation[] extractInterceptorBindings(BeanManager beanManager, Object instance, Method method) { ArrayList bindings = new ArrayList<>(); addInterceptorBindings(beanManager, bindings, instance.getClass().getDeclaredAnnotations()); addInterceptorBindings(beanManager, bindings, method.getDeclaredAnnotations()); return bindings.toArray(new Annotation[bindings.size()]); } private void addInterceptorBindings(BeanManager beanManager, ArrayList bindings, Annotation[] declaredAnnotations) { for (Annotation annotation : declaredAnnotations) { if (bindings.contains(annotation)) { continue; } Class annotationType = annotation.annotationType(); if (beanManager.isInterceptorBinding(annotationType)) { bindings.add(annotation); } if (beanManager.isStereotype(annotationType)) { for (Annotation subAnnotation : annotationType.getDeclaredAnnotations()) { if (bindings.contains(subAnnotation)) { continue; } if (beanManager.isInterceptorBinding(subAnnotation.annotationType())) { bindings.add(subAnnotation); } } } } } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/invocation/DeltaSpikeProxyInvocationContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi.invocation; import java.lang.reflect.Method; import java.util.List; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InterceptionType; import jakarta.enterprise.inject.spi.Interceptor; import org.apache.deltaspike.core.util.interceptor.AbstractInvocationContext; /** * {@link jakarta.interceptor.InvocationContext} implementation to support interceptor invocation * before proceed with the original method or delegation. */ @Vetoed public class DeltaSpikeProxyInvocationContext extends AbstractInvocationContext { protected List> interceptors; protected int interceptorIndex; protected DeltaSpikeProxyInvocationHandler invocationHandler; protected BeanManager beanManager; protected boolean proceedOriginal; protected Object proceedOriginalReturnValue; public DeltaSpikeProxyInvocationContext(DeltaSpikeProxyInvocationHandler invocationHandler, BeanManager beanManager, List> interceptors, T target, Method method, Object[] parameters, Object timer) { super(target, method, parameters, timer); this.invocationHandler = invocationHandler; this.interceptors = interceptors; this.beanManager = beanManager; this.interceptorIndex = 0; } @Override public Object proceed() throws Exception { if (proceedOriginal) { return null; } if (interceptors.size() > interceptorIndex) { Interceptor interceptor = null; CreationalContext creationalContext = null; H interceptorInstance = null; try { interceptor = interceptors.get(interceptorIndex++); creationalContext = beanManager.createCreationalContext(interceptor); interceptorInstance = interceptor.create(creationalContext); return interceptor.intercept(InterceptionType.AROUND_INVOKE, interceptorInstance, this); } finally { if (creationalContext != null) { if (interceptorInstance != null && interceptor != null) { interceptor.destroy(interceptorInstance, creationalContext); } creationalContext.release(); } } } // workaround for OWB 1.1, otherwise we could just return the proceedOriginalReturnValue here try { proceedOriginal = true; proceedOriginalReturnValue = invocationHandler.proceed(target, method, parameters); } catch (Exception e) { throw e; } catch (Throwable e) { // wrap the Throwable here as interceptors declared only "throws Exception" throw new DeltaSpikeProxyInvocationWrapperException(e); } return proceedOriginalReturnValue; } public boolean isProceedOriginal() { return proceedOriginal; } public Object getProceedOriginalReturnValue() { return proceedOriginalReturnValue; } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/invocation/DeltaSpikeProxyInvocationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi.invocation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.Interceptor; import jakarta.inject.Inject; import org.apache.deltaspike.core.util.ReflectionUtils; import org.apache.deltaspike.proxy.api.DeltaSpikeProxyFactory; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; /** * The {@link InvocationHandler} which will be called directly by the proxy methods. * For both delegateMethods and interceptMethods * (See: {@link org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator}). * * This {@link InvocationHandler} first executes CDI interceptors (if defined on method or class level) and * after that the original method or the {@link DeltaSpikeProxy#getDelegateInvocationHandler()} will be executed, * depending if the invoked method is a intercept or delegate method. */ @ApplicationScoped public class DeltaSpikeProxyInvocationHandler implements InvocationHandler { @Inject private BeanManager beanManager; @Inject private DeltaSpikeProxyInterceptorLookup interceptorLookup; @Override public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable { // check if interceptors are defined, otherwise just call the original logik List> interceptors = interceptorLookup.lookup(proxy, method); if (interceptors != null && !interceptors.isEmpty()) { try { DeltaSpikeProxyInvocationContext invocationContext = new DeltaSpikeProxyInvocationContext( this, beanManager, interceptors, proxy, method, parameters, null); Object returnValue = invocationContext.proceed(); if (invocationContext.isProceedOriginal()) { return invocationContext.getProceedOriginalReturnValue(); } return returnValue; } catch (DeltaSpikeProxyInvocationWrapperException e) { throw e.getCause(); } } return proceed(proxy, method, parameters); } /** * Calls the original method or delegates to {@link DeltaSpikeProxy#getDelegateInvocationHandler()} * after invoking the interceptor chain. * * @param proxy The current proxy instance. * @param method The current invoked method. * @param parameters The method parameter. * @return The original value from the original method. * @throws Throwable */ protected Object proceed(Object proxy, Method method, Object[] parameters) throws Throwable { DeltaSpikeProxy deltaSpikeProxy = (DeltaSpikeProxy) proxy; if (contains(deltaSpikeProxy.getDelegateMethods(), method)) { return deltaSpikeProxy.getDelegateInvocationHandler().invoke(proxy, method, parameters); } else { try { Method superAccessorMethod = DeltaSpikeProxyFactory.getSuperAccessorMethod(proxy, method); return superAccessorMethod.invoke(proxy, parameters); } catch (InvocationTargetException e) { // rethrow original exception throw e.getCause(); } } } protected boolean contains(Method[] methods, Method method) { if (methods == null || methods.length == 0) { return false; } for (Method current : methods) { if (ReflectionUtils.hasSameSignature(method, current)) { return true; } } return false; } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/spi/invocation/DeltaSpikeProxyInvocationWrapperException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.spi.invocation; /** * Wrapper exception to wrap and pass trough the original {@link Throwable} because * the {@link jakarta.interceptor.InvocationContext#proceed()} method only declares "throws Exception". */ public class DeltaSpikeProxyInvocationWrapperException extends Exception { public DeltaSpikeProxyInvocationWrapperException(Throwable e) { super(e); } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/java/org/apache/deltaspike/proxy/util/EnableInterceptorsProxyFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.util; import java.io.Serializable; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.ArrayList; import jakarta.enterprise.inject.spi.BeanManager; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.proxy.api.DeltaSpikeProxyFactory; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; import org.apache.deltaspike.proxy.spi.invocation.DeltaSpikeProxyInvocationHandler; public class EnableInterceptorsProxyFactory extends DeltaSpikeProxyFactory { private static final EnableInterceptorsProxyFactory INSTANCE = new EnableInterceptorsProxyFactory(); private EnableInterceptorsProxyFactory() { } public static T wrap(T obj, BeanManager beanManager) { if (obj == null) { throw new IllegalArgumentException("obj must not be null!"); } // generate proxy Class proxyClass = INSTANCE.getProxyClass(beanManager, obj.getClass()); // delegate method calls to our original instance from the wrapped producer method EnableInterceptorsDelegate delegate = new EnableInterceptorsDelegate(obj); try { // instantiate proxy T proxy = (T) proxyClass.newInstance(); DeltaSpikeProxy deltaSpikeProxy = (DeltaSpikeProxy) proxy; // TODO this can be optimized by caching this in a appscoped bean deltaSpikeProxy.setInvocationHandler( BeanProvider.getContextualReference(DeltaSpikeProxyInvocationHandler.class)); deltaSpikeProxy.setDelegateInvocationHandler(delegate); deltaSpikeProxy.setDelegateMethods(INSTANCE.getDelegateMethods(obj.getClass())); return proxy; } catch (Exception e) { throw new RuntimeException("Could not create proxy instance by class " + obj.getClass(), e); } } @Override protected ArrayList getDelegateMethods(Class targetClass, ArrayList allMethods) { // the default #filterInterceptMethods filters all non-public, final and abstract methods // which means actually every publich proxyable method // as we need to delegate method call to the original object instance -> proxy all public methods ArrayList delegateMethods = super.filterInterceptMethods(targetClass, allMethods); return delegateMethods; } @Override protected ArrayList filterInterceptMethods(Class targetClass, ArrayList allMethods) { // we don't need to overwrite methods to just execute interceptors // all method call are delegated to our EnableInterceptorsDelegate, to delegate to the original object instance return null; } @Override protected String getProxyClassSuffix() { return "$$DSInterceptorProxy"; } /** * {@link InvocationHandler} to delegate every method call to an provided object instance. */ private static class EnableInterceptorsDelegate implements InvocationHandler, Serializable { private final Object instance; public EnableInterceptorsDelegate(Object instance) { this.instance = instance; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(instance, args); } } } ================================================ FILE: deltaspike/modules/proxy/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/proxy/api/src/main/resources/OSGI-INF/DeltaSpikeProxyClassGeneratorHolder.xml ================================================ ================================================ FILE: deltaspike/modules/proxy/api/src/test/java/org/apache/deltaspike/proxy/api/DeltaSpikeProxyFactoryTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.api; import static org.junit.Assert.assertTrue; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Test; public class DeltaSpikeProxyFactoryTest { public static class DeltaSpikeProxyFactoryForCollectTest extends DeltaSpikeProxyFactory { @Override protected ArrayList getDelegateMethods(Class targetClass, ArrayList allMethods) { return null; } @Override protected String getProxyClassSuffix() { return null; } public ArrayList collectAllMethodsDelegate(Class clazz) { return collectAllMethods(clazz); } } private DeltaSpikeProxyFactoryForCollectTest proxyFactory; @Before public void setUp() throws Exception { proxyFactory = new DeltaSpikeProxyFactoryForCollectTest(); } public class Class_NonAbstract { public void test() { } } public abstract class Class_NonAbstractToAbstract extends Class_NonAbstract { public abstract void test(); } public abstract static class Class_C1 { protected abstract void protectedAbstract_C1_C2(); // will be overridden in Class_C2 protected abstract void protectedAbstract_C1_C3(); // will be overridden in Class_C3 protected abstract void protectedAbstract_C1_C2_C3(); // will be overridden in Class_C2, Class_C3 protected abstract void protectedAbstract_C1(); // will not be overridden public abstract void publicAbstract_C1_C2(); // will be overridden in Class_C2 public abstract void publicAbstract_C1_C3(); // will be overridden in Class_C3 public abstract void publicAbstract_C1_C2_C3(); // will be overridden in Class_C2, Class_C3 public abstract void publicAbstract_C1(); // will not be overriden at all public void test(List l) { } } public abstract static class Class_C2 extends Class_C1 { protected void protectedAbstract_C1_C2() // Leave in Class_C2 { } public void publicAbstract_C1_C2() // Leave in Class_C2 { } protected abstract void protectedAbstract_C2_C3(); // will be overridden in Class_C3 protected abstract void protectedAbstract_C2(); // will not be overridden public abstract void publicAbstract_C2_C3(); // will be overridden in Class_C3 public abstract void publicAbstract_C2(); // will not be overridden public abstract void test(List list); } public abstract static class Class_C3 extends Class_C2 { public void protectedAbstract_C1_C3() { } public void publicAbstract_C1_C3() { } public void protectedAbstract_C2_C3() { } public void publicAbstract_C2_C3() { } } private boolean containsMethod(List collectedMethods, Class declaringClass, String methodName) { for(Method m: collectedMethods) { if (m.getDeclaringClass() == declaringClass && methodName.equals(m.getName())) { return true; } } return false; } private void printCollectedMethods(List collectedMethods) { for(Method m: collectedMethods) { if (m.getDeclaringClass() != Object.class) { System.out.println(m.getDeclaringClass().getName() + " " + m.getName()); } } } @Test public void testCollection_NonAbstractToAbstract() { ArrayList collectedMethods = proxyFactory.collectAllMethods(Class_NonAbstractToAbstract.class); printCollectedMethods(collectedMethods); } @Test public void testMethCollection_C1() { ArrayList collectedMethods = proxyFactory.collectAllMethods(Class_C1.class); // System.out.println("testCollectitOn0"); // printCollectedMethods(collectedMethods); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1")); } @Test public void testMethCollection_C2() { ArrayList collectedMethods = proxyFactory.collectAllMethods(Class_C2.class); // System.out.println("testMethCollection_C2"); // printCollectedMethods(collectedMethods); assertTrue(containsMethod(collectedMethods, Class_C2.class, "protectedAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "protectedAbstract_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "protectedAbstract_C2")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C2")); } @Test public void testMethCollection_C3() { ArrayList collectedMethods = proxyFactory.collectAllMethods(Class_C3.class); // System.out.println("testCollectitOn02"); // printCollectedMethods(collectedMethods); assertTrue(containsMethod(collectedMethods, Class_C2.class, "protectedAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C3.class, "protectedAbstract_C1_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "protectedAbstract_C1")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C1_C2")); assertTrue(containsMethod(collectedMethods, Class_C3.class, "publicAbstract_C1_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C1.class, "publicAbstract_C1")); assertTrue(containsMethod(collectedMethods, Class_C3.class, "protectedAbstract_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "protectedAbstract_C2")); assertTrue(containsMethod(collectedMethods, Class_C3.class, "publicAbstract_C2_C3")); assertTrue(containsMethod(collectedMethods, Class_C2.class, "publicAbstract_C2")); } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules proxy-module-project 2.0.2-SNAPSHOT ../pom.xml deltaspike-proxy-module-impl-asm jar Apache DeltaSpike Proxy-Module Impl ASM org.apache.deltaspike.proxy.impl.* * org.apache.maven.plugins maven-shade-plugin 3.2.1 shade-asm package shade false false true org.objectweb.asm org.apache.deltaspike.proxy.asm org.ow2.asm:asm org.ow2.asm:asm-commons org.ow2.asm:asm-tree org.ow2.asm asm ${asm.version} org.ow2.asm asm-commons ${asm.version} org.apache.felix maven-bundle-plugin OSGI-INF/* org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.apache.deltaspike.modules deltaspike-proxy-module-api ${project.version} org.ow2.asm asm ${asm.version} true org.ow2.asm asm-commons ${asm.version} true org.ow2.asm asm-tree ${asm.version} true org.jboss.shrinkwrap.descriptors shrinkwrap-descriptors-impl-javaee test ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/AsmDeltaSpikeProxyClassGenerator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxy; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.UndeclaredThrowableException; import java.util.ArrayList; import java.util.Arrays; import jakarta.enterprise.inject.Vetoed; import org.apache.deltaspike.proxy.spi.invocation.DeltaSpikeProxyInvocationHandler; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.GeneratorAdapter; import org.objectweb.asm.commons.Method; import org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator; @Vetoed public class AsmDeltaSpikeProxyClassGenerator implements DeltaSpikeProxyClassGenerator { private static final String FIELDNAME_INVOCATION_HANDLER = "invocationHandler"; private static final String FIELDNAME_DELEGATE_INVOCATION_HANDLER = "delegateInvocationHandler"; private static final String FIELDNAME_DELEGATE_METHODS = "delegateMethods"; private static final Type TYPE_CLASS = Type.getType(Class.class); private static final Type TYPE_OBJECT = Type.getType(Object.class); private static final Type TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER = Type.getType(DeltaSpikeProxyInvocationHandler.class); private static final Type TYPE_METHOD_ARRAY = Type.getType(java.lang.reflect.Method[].class); private static final Type TYPE_INVOCATION_HANDLER = Type.getType(InvocationHandler.class); @Override public Class generateProxyClass(ClassLoader classLoader, Class targetClass, String suffix, String superAccessorMethodSuffix, Class[] additionalInterfaces, java.lang.reflect.Method[] delegateMethods, java.lang.reflect.Method[] interceptMethods) { String proxyName = targetClass.getName() + suffix; String classFileName = proxyName.replace('.', '/'); byte[] proxyBytes = generateProxyClassBytes(targetClass, classFileName, superAccessorMethodSuffix, additionalInterfaces, delegateMethods, interceptMethods); Class proxyClass = (Class) ClassDefiner.defineClass(classLoader, proxyName, proxyBytes, targetClass, targetClass.getProtectionDomain()); return proxyClass; } private static byte[] generateProxyClassBytes(Class targetClass, String proxyName, String superAccessorMethodSuffix, Class[] additionalInterfaces, java.lang.reflect.Method[] delegateMethods, java.lang.reflect.Method[] interceptMethods) { Class superClass = targetClass; String[] interfaces = new String[] { }; if (targetClass.isInterface()) { superClass = Object.class; interfaces = new String[] { Type.getInternalName(targetClass) }; } // add DeltaSpikeProxy as interface interfaces = Arrays.copyOf(interfaces, interfaces.length + 1); interfaces[interfaces.length - 1] = Type.getInternalName(DeltaSpikeProxy.class); if (additionalInterfaces != null && additionalInterfaces.length > 0) { interfaces = Arrays.copyOf(interfaces, interfaces.length + additionalInterfaces.length); for (int i = 0; i < additionalInterfaces.length; i++) { interfaces[(interfaces.length - 1) + i] = Type.getInternalName(additionalInterfaces[i]); } } Type superType = Type.getType(superClass); Type proxyType = Type.getObjectType(proxyName); final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, proxyType.getInternalName(), null, superType.getInternalName(), interfaces); defineDefaultConstructor(cw, proxyType, superType); defineDeltaSpikeProxyFields(cw); defineDeltaSpikeProxyMethods(cw, proxyType); if (delegateMethods != null) { for (java.lang.reflect.Method method : delegateMethods) { defineMethod(cw, method, proxyType); } } if (interceptMethods != null) { for (java.lang.reflect.Method method : interceptMethods) { defineSuperAccessorMethod(cw, method, superType, superAccessorMethodSuffix); defineMethod(cw, method, proxyType); } } // copy all annotations from the source class try { // ClassVisitor to intercept all annotation visits on the class ClassVisitor cv = new ClassVisitor(Opcodes.ASM7) { @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return new CopyAnnotationVisitorAdapter( super.visitAnnotation(desc, visible), cw.visitAnnotation(desc, visible)); } }; // visit class to proxy with our visitor to copy all annotations from the source class to our ClassWriter String sourceClassFilename = targetClass.getName().replace('.', '/') + ".class"; ClassReader cr = new ClassReader(targetClass.getClassLoader().getResourceAsStream(sourceClassFilename)); cr.accept(cv, 0); } catch (Exception e) { throw new RuntimeException(e); } return cw.toByteArray(); } private static void defineDefaultConstructor(ClassWriter cw, Type proxyType, Type superType) { GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, new Method("", Type.VOID_TYPE, new Type[]{ }), null, null, cw); mg.visitCode(); // invoke super constructor mg.loadThis(); mg.invokeConstructor(superType, Method.getMethod("void ()")); mg.returnValue(); mg.endMethod(); mg.visitEnd(); } private static void defineDeltaSpikeProxyFields(ClassWriter cw) { // generates // private DeltaSpikeProxyInvocationHandler invocationHandler; cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd(); // generates // private MyInvocationHandler delegateInvocationHandler; cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_INVOCATION_HANDLER, TYPE_INVOCATION_HANDLER.getDescriptor(), null, null).visitEnd(); // generates // private Method[] delegateMethods; cw.visitField(Opcodes.ACC_PRIVATE, FIELDNAME_DELEGATE_METHODS, TYPE_METHOD_ARRAY.getDescriptor(), null, null).visitEnd(); } private static void defineDeltaSpikeProxyMethods(ClassWriter cw, Type proxyType) { try { // implement #setInvocationHandler Method asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( "setInvocationHandler", DeltaSpikeProxyInvocationHandler.class)); GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.loadArg(0); mg.checkCast(TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); mg.putField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); // implement #getInvocationHandler asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getInvocationHandler")); mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.getField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); // implement #setDelegateInvocationHandler asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( "setDelegateInvocationHandler", InvocationHandler.class)); mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.loadArg(0); mg.checkCast(TYPE_INVOCATION_HANDLER); mg.putField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, TYPE_INVOCATION_HANDLER); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); // implement #getDelegateInvocationHandler asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getDelegateInvocationHandler")); mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.getField(proxyType, FIELDNAME_DELEGATE_INVOCATION_HANDLER, TYPE_INVOCATION_HANDLER); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); // implement #setDelegateMethods asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod( "setDelegateMethods", java.lang.reflect.Method[].class)); mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.loadArg(0); mg.checkCast(TYPE_METHOD_ARRAY); mg.putField(proxyType, FIELDNAME_DELEGATE_METHODS, TYPE_METHOD_ARRAY); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); // implement #getDelegateMethods asmMethod = Method.getMethod(DeltaSpikeProxy.class.getDeclaredMethod("getDelegateMethods")); mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, asmMethod, null, null, cw); mg.visitCode(); mg.loadThis(); mg.getField(proxyType, FIELDNAME_DELEGATE_METHODS, TYPE_METHOD_ARRAY); mg.returnValue(); mg.visitMaxs(2, 1); mg.visitEnd(); } catch (NoSuchMethodException e) { throw new IllegalStateException("Unable to implement " + DeltaSpikeProxy.class.getName(), e); } } private static void defineSuperAccessorMethod(ClassWriter cw, java.lang.reflect.Method method, Type superType, String superAccessorMethodSuffix) { Method originalAsmMethod = Method.getMethod(method); Method newAsmMethod = new Method(method.getName() + superAccessorMethodSuffix, originalAsmMethod.getReturnType(), originalAsmMethod.getArgumentTypes()); GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, newAsmMethod, null, null, cw); mg.visitCode(); // call super method mg.loadThis(); mg.loadArgs(); mg.visitMethodInsn(Opcodes.INVOKESPECIAL, superType.getInternalName(), method.getName(), Type.getMethodDescriptor(method), false); mg.returnValue(); // finish the method mg.endMethod(); mg.visitMaxs(10, 10); mg.visitEnd(); } private static void defineMethod(ClassWriter cw, java.lang.reflect.Method method, Type proxyType) { Type methodType = Type.getType(method); ArrayList exceptionsToCatch = new ArrayList(); for (Class exception : method.getExceptionTypes()) { if (!RuntimeException.class.isAssignableFrom(exception)) { exceptionsToCatch.add(Type.getType(exception)); } } // push the method definition int modifiers = (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED) & method.getModifiers(); Method asmMethod = Method.getMethod(method); GeneratorAdapter mg = new GeneratorAdapter(modifiers, asmMethod, null, getTypes(method.getExceptionTypes()), cw); // copy annotations for (Annotation annotation : method.getDeclaredAnnotations()) { mg.visitAnnotation(Type.getDescriptor(annotation.annotationType()), true).visitEnd(); } mg.visitCode(); Label tryBlockStart = mg.mark(); mg.loadThis(); mg.getField(proxyType, FIELDNAME_INVOCATION_HANDLER, TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER); mg.loadThis(); loadCurrentMethod(mg, method, methodType); loadArguments(mg, method, methodType); mg.invokeVirtual(TYPE_DELTA_SPIKE_PROXY_INVOCATION_HANDLER, Method.getMethod("Object invoke(Object, java.lang.reflect.Method, Object[])")); // cast the result mg.unbox(methodType.getReturnType()); // build try catch Label tryBlockEnd = mg.mark(); // push return mg.returnValue(); // catch runtime exceptions and rethrow it Label rethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.throwException(); mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, Type.getInternalName(RuntimeException.class)); // catch checked exceptions and rethrow it boolean throwableCatched = false; if (!exceptionsToCatch.isEmpty()) { rethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.throwException(); // catch declared exceptions and rethrow it... for (Type exceptionType : exceptionsToCatch) { if (exceptionType.getClassName().equals(Throwable.class.getName())) { throwableCatched = true; } mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, rethrow, exceptionType.getInternalName()); } } // if throwable isn't alreached cachted, catch it and wrap it with an UndeclaredThrowableException and throw it if (!throwableCatched) { Type uteType = Type.getType(UndeclaredThrowableException.class); Label wrapAndRethrow = mg.mark(); mg.visitVarInsn(Opcodes.ASTORE, 1); mg.newInstance(uteType); mg.dup(); mg.visitVarInsn(Opcodes.ALOAD, 1); mg.invokeConstructor(uteType, Method.getMethod("void (java.lang.Throwable)")); mg.throwException(); mg.visitTryCatchBlock(tryBlockStart, tryBlockEnd, wrapAndRethrow, Type.getInternalName(Throwable.class)); } // finish the method mg.endMethod(); mg.visitMaxs(12, 12); mg.visitEnd(); } /** * Generates: *
     * Method method =
     *      method.getDeclaringClass().getMethod("methodName", new Class[] { args... });
     * 
* @param mg * @param method * @param methodType */ private static void loadCurrentMethod(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) { mg.push(Type.getType(method.getDeclaringClass())); mg.push(method.getName()); // create the Class[] mg.push(methodType.getArgumentTypes().length); mg.newArray(TYPE_CLASS); // push parameters into array for (int i = 0; i < methodType.getArgumentTypes().length; i++) { // keep copy of array on stack mg.dup(); // push index onto stack mg.push(i); mg.push(methodType.getArgumentTypes()[i]); mg.arrayStore(TYPE_CLASS); } // invoke getMethod() with the method name and the array of types mg.invokeVirtual(TYPE_CLASS, Method.getMethod("java.lang.reflect.Method getDeclaredMethod(String, Class[])")); } /** * Defines a new Object[] and push all method argmuments into the array. * * @param mg * @param method * @param methodType */ private static void loadArguments(GeneratorAdapter mg, java.lang.reflect.Method method, Type methodType) { // create the Object[] mg.push(methodType.getArgumentTypes().length); mg.newArray(TYPE_OBJECT); // push parameters into array for (int i = 0; i < methodType.getArgumentTypes().length; i++) { // keep copy of array on stack mg.dup(); // push index onto stack mg.push(i); mg.loadArg(i); mg.valueOf(methodType.getArgumentTypes()[i]); mg.arrayStore(TYPE_OBJECT); } } private static Type[] getTypes(Class... src) { Type[] result = new Type[src.length]; for (int i = 0; i < result.length; i++) { result[i] = Type.getType(src[i]); } return result; } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/ClassDefiner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import java.lang.invoke.MethodHandles; import java.lang.reflect.Method; import java.security.ProtectionDomain; class ClassDefiner { private static final Method CLASS_LOADER_DEFINE_CLASS; private static final Method GET_MODULE; private static final Method CAN_READ; private static final Method ADD_READS; private static final Method PRIVATE_LOOKUP_IN; private static final Method DEFINE_CLASS; static { Method classLoaderDefineClass = null; try { java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod( "defineClass", String.class, byte[].class, int.class, int.class, ProtectionDomain.class); method.setAccessible(true); classLoaderDefineClass = method; } catch (Exception ex) { // Ignore } CLASS_LOADER_DEFINE_CLASS = classLoaderDefineClass; Method getModule = null; Method canRead = null; Method addReads = null; Method privateLookupIn = null; Method defineClass = null; try { getModule = Class.class.getMethod("getModule"); Class moduleClass = getModule.getReturnType(); canRead = moduleClass.getMethod("canRead", moduleClass); addReads = moduleClass.getMethod("addReads", moduleClass); privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class); defineClass = MethodHandles.Lookup.class.getMethod("defineClass", byte[].class); } catch (Exception ex) { // Ignore } GET_MODULE = getModule; CAN_READ = canRead; ADD_READS = addReads; PRIVATE_LOOKUP_IN = privateLookupIn; DEFINE_CLASS = defineClass; } private ClassDefiner() { } static Class defineClass(ClassLoader loader, String className, byte[] b, Class originalClass, ProtectionDomain protectionDomain) { if (CLASS_LOADER_DEFINE_CLASS == null) { return defineClassMethodHandles(loader, className, b, originalClass, protectionDomain); } else { return defineClassClassLoader(loader, className, b, originalClass, protectionDomain); } } /** * Adapted from http://asm.ow2.org/doc/faq.html#Q5 * * @param b * * @return Class */ static Class defineClassClassLoader(ClassLoader loader, String className, byte[] b, Class originalClass, ProtectionDomain protectionDomain) { try { return (Class) CLASS_LOADER_DEFINE_CLASS.invoke( loader, className, b, Integer.valueOf(0), Integer.valueOf(b.length), protectionDomain); } catch (Exception e) { throw e instanceof RuntimeException ? ((RuntimeException) e) : new RuntimeException(e); } } /** * Implementation based on MethodHandles.Lookup. * * @return Class */ static Class defineClassMethodHandles(ClassLoader loader, String className, byte[] b, Class originalClass, ProtectionDomain protectionDomain) { try { Object thisModule = GET_MODULE.invoke(AsmDeltaSpikeProxyClassGenerator.class); Object lookupClassModule = GET_MODULE.invoke(originalClass); if (!(boolean) CAN_READ.invoke(thisModule, lookupClassModule)) { // we need to read the other module in order to have privateLookup access // see javadoc for MethodHandles.privateLookupIn() ADD_READS.invoke(thisModule, lookupClassModule); } Object lookup = PRIVATE_LOOKUP_IN.invoke(null, originalClass, MethodHandles.lookup()); return (Class) DEFINE_CLASS.invoke(lookup, b); } catch (Exception e) { throw new RuntimeException(e); } } // static Class defineClassMethodHandles(ClassLoader loader, String className, byte[] b, // Class originalClass, ProtectionDomain protectionDomain) // { // Module thisModule = AsmDeltaSpikeProxyClassGenerator.class.getModule(); // try // { // Module lookupClassModule = originalClass.getModule(); // if (!thisModule.canRead(lookupClassModule)) // { // // we need to read the other module in order to have privateLookup access // // see javadoc for MethodHandles.privateLookupIn() // thisModule.addReads(lookupClassModule); // } // MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(originalClass, MethodHandles.lookup()); // return lookup.defineClass(b); // } // catch (IllegalAccessException e) // { // throw new RuntimeException(e); // } // } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/java/org/apache/deltaspike/proxy/impl/CopyAnnotationVisitorAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Opcodes; public class CopyAnnotationVisitorAdapter extends AnnotationVisitor { private final AnnotationVisitor from; private final AnnotationVisitor to; public CopyAnnotationVisitorAdapter(AnnotationVisitor from, AnnotationVisitor copyTo) { super(Opcodes.ASM7); this.from = from; this.to = copyTo; } @Override public void visit(String name, Object value) { if (from != null) { from.visit(name, value); } to.visit(name, value); } @Override public void visitEnum(String name, String desc, String value) { if (from != null) { from.visitEnum(name, desc, value); } to.visitEnum(name, desc, value); } @Override public AnnotationVisitor visitAnnotation(String name, String desc) { if (from == null) { return new CopyAnnotationVisitorAdapter( null, to.visitAnnotation(name, desc)); } return new CopyAnnotationVisitorAdapter( from.visitAnnotation(name, desc), to.visitAnnotation(name, desc)); } @Override public AnnotationVisitor visitArray(String name) { if (from == null) { return new CopyAnnotationVisitorAdapter( null, to.visitArray(name)); } return new CopyAnnotationVisitorAdapter( from.visitArray(name), to.visitArray(name)); } @Override public void visitEnd() { if (from != null) { from.visitEnd(); } to.visitEnd(); } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/resources/META-INF/services/org.apache.deltaspike.proxy.spi.DeltaSpikeProxyClassGenerator ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.proxy.impl.AsmDeltaSpikeProxyClassGenerator ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/main/resources/OSGI-INF/AsmDeltaSpikeProxyClassGenerator.xml ================================================ ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/AsmProxyClassGeneratorTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import jakarta.inject.Named; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class AsmProxyClassGeneratorTest { private static Class proxyClass; @BeforeClass public static void init() { AsmDeltaSpikeProxyClassGenerator asmProxyClassGenerator = new AsmDeltaSpikeProxyClassGenerator(); proxyClass = asmProxyClassGenerator.generateProxyClass(TestClass.class.getClassLoader(), TestClass.class, "$Test", "$super", null, null, null); } @Test public void testCopyAnnotationValues() { Assert.assertEquals( TestClass.class.getAnnotations().length, proxyClass.getAnnotations().length); Assert.assertEquals( TestClass.class.getAnnotation(Named.class).value(), proxyClass.getAnnotation(Named.class).value()); Assert.assertEquals( TestClass.class.getAnnotation(TestAnnotation.class).value1(), proxyClass.getAnnotation(TestAnnotation.class).value1()); Assert.assertEquals( TestClass.class.getAnnotation(TestAnnotation.class).value2(), proxyClass.getAnnotation(TestAnnotation.class).value2()); Assert.assertEquals( TestClass.class.getAnnotation(TestAnnotation.class).value3(), proxyClass.getAnnotation(TestAnnotation.class).value3()); } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestAnnotation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Documented @Retention(value = RetentionPolicy.RUNTIME) public @interface TestAnnotation { int value1() default 13; Class value2() default TestAnnotation.class; String value3() default "tester"; } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import jakarta.inject.Named; @Named("test") @TestAnnotation(value2 = TestClass.class, value1 = 15) public class TestClass { } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/proxy/impl/TestInvocationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.proxy.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TestInvocationHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; } } ================================================ FILE: deltaspike/modules/proxy/impl-asm/src/test/java/org/apache/deltaspike/test/proxy/impl/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.proxy.impl.util; import java.util.ArrayList; import java.util.Arrays; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; public abstract class ArchiveUtils { private ArchiveUtils() { } public static JavaArchive[] getDeltaSpikeCoreAndProxyArchive() { ArrayList result = new ArrayList(); JavaArchive[] temp; temp = ShrinkWrapArchiveUtil.getArchives(null, "META-INF/beans.xml", new String[] { "org.apache.deltaspike.core", "org.apache.deltaspike.proxy", "org.apache.deltaspike.test.category"}, new String[] { "META-INF.apache-deltaspike.properties" }, "ds-core_and_proxy"); result.addAll(Arrays.asList(temp)); // add asm - it isn't shaded yet in the test phase result.add(ShrinkWrap.create(JavaArchive.class, "ds-asm.jar") .addPackages(true, "org.objectweb.asm")); return result.toArray(new JavaArchive[result.size()]); } } ================================================ FILE: deltaspike/modules/proxy/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules proxy-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Proxy-Module api impl-asm ================================================ FILE: deltaspike/modules/scheduler/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules scheduler-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-scheduler-module-api jar Apache DeltaSpike Scheduler-Module API org.apache.deltaspike.scheduler.* jakarta.enterprise.inject, !org.apache.deltaspike.scheduler.*, * org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided ================================================ FILE: deltaspike/modules/scheduler/api/src/main/java/org/apache/deltaspike/scheduler/api/Scheduled.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.api; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ TYPE }) @Retention(RUNTIME) @Documented public @interface Scheduled { String cronExpression(); boolean overrideOnStartup() default false; //'true' triggers a re-schedule if the job exists already Class[] startScopes() default { SessionScoped.class, RequestScoped.class }; Class group() default Scheduled.class; //type-safe group String description() default ""; boolean onStartup() default true; //use false to schedule it manually (after the bootstrapping-process) } ================================================ FILE: deltaspike/modules/scheduler/api/src/main/java/org/apache/deltaspike/scheduler/spi/Scheduler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.spi; import org.apache.deltaspike.core.spi.activation.Deactivatable; public interface Scheduler extends Deactivatable { void start(); void stop(); void pauseJob(Class jobClass); void resumeJob(Class jobClass); void interruptJob(Class jobClass); boolean deleteJob(Class jobClass); boolean isExecutingJob(Class jobClass); void registerNewJob(Class jobClass); void startJobManually(Class jobClass); S unwrap(Class schedulerClass); } ================================================ FILE: deltaspike/modules/scheduler/api/src/main/java/org/apache/deltaspike/scheduler/spi/SchedulerControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.spi; /** * This interface provides high-level controls for the scheduler. * * It allows to control the scheduler as a whole ({@link #isSchedulerEnabled()}()) and on a per-job basis * ({@link #vetoJobExecution(Class)}. * * The interface is meant to be implemented by a CDI bean. */ public interface SchedulerControl { /** * Control whether or not the scheduler should be started. * * @return if {@code true} the scheduler will be started, else not. */ default boolean isSchedulerEnabled() { return true; } /** * Invoked each time a job is triggered, this controls whether the given job shall be started or not. * * NOTE: This only applies if the scheduler is actually running (see {@link #isSchedulerEnabled()}). * * @param jobClass the job which was triggered * @return if {@code false} the job will be executed, else not. */ default boolean vetoJobExecution(Class jobClass) { return false; } } ================================================ FILE: deltaspike/modules/scheduler/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/scheduler/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules scheduler-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-scheduler-module-impl jar Apache DeltaSpike Scheduler-Module Impl org.apache.deltaspike.scheduler.impl.* !org.apache.deltaspike.scheduler.impl.*, * 3.2.1 org.jboss.shrinkwrap.resolver shrinkwrap-resolver-bom ${shrinkwrap.version} pom import org.apache.deltaspike.modules deltaspike-scheduler-module-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided org.quartz-scheduler quartz 2.3.2 true jakarta.el jakarta.el-api org.apache.tomcat tomcat-servlet-api org.apache.deltaspike.core deltaspike-core-impl ${project.version} test org.jboss.shrinkwrap.resolver shrinkwrap-resolver-impl-maven test OWB true org.apache.openwebbeans openwebbeans-impl ${owb.version} test org.apache.openwebbeans openwebbeans-spi ${owb.version} test org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} test Weld org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} test org.jboss.weld.se weld-se-core ${weld.version} test ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/AbstractJobAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.scheduler.spi.SchedulerControl; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import java.util.logging.Level; import java.util.logging.Logger; public abstract class AbstractJobAdapter implements Job { private static final Logger LOG = Logger.getLogger(AbstractJobAdapter.class.getName()); @Inject private BeanManager beanManager; @Override public void execute(JobExecutionContext context) { Class jobClass = ClassUtils.tryToLoadClassForName(context.getJobDetail().getKey().getName(), getJobBaseClass()); SchedulerControl schedulerControl = BeanProvider.getContextualReference(SchedulerControl.class, true); if (schedulerControl != null && schedulerControl.vetoJobExecution(jobClass)) { LOG.info("Execution of job " + jobClass + " has been vetoed by " + ProxyUtils.getUnproxiedClass(schedulerControl.getClass())); return; } T job = BeanProvider.getContextualReference(jobClass); try { execute(job, context); } catch (Throwable t) { LOG.log(Level.SEVERE, "Error while executing job " + jobClass, t); } } protected abstract Class getJobBaseClass(); public abstract void execute(T job, JobExecutionContext context) throws JobExecutionException; } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/AbstractQuartzScheduler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.api.provider.DependentProvider; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.PropertyFileUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.scheduler.api.Scheduled; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.quartz.CronScheduleBuilder; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.JobListener; import org.quartz.SchedulerException; import org.quartz.SchedulerFactory; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; import java.io.InputStream; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.ResourceBundle; import java.util.Stack; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; public abstract class AbstractQuartzScheduler implements Scheduler { private static final Logger LOG = Logger.getLogger(AbstractQuartzScheduler.class.getName()); private static final Scheduled DEFAULT_SCHEDULED_LITERAL = AnnotationInstanceProvider.of(Scheduled.class); private static ThreadLocal currentJobListenerContext = new ThreadLocal(); protected org.quartz.Scheduler scheduler; @Override public void start() { if (this.scheduler != null) { throw new UnsupportedOperationException("the scheduler is started already"); } SchedulerFactory schedulerFactory = null; try { Properties properties = new Properties(); properties.put(StdSchedulerFactory.PROP_SCHED_JOB_FACTORY_CLASS, CdiAwareJobFactory.class.getName()); try { ResourceBundle config = loadCustomQuartzConfig(); Enumeration keys = config.getKeys(); String key; while (keys.hasMoreElements()) { key = keys.nextElement(); properties.put(key, config.getString(key)); } } catch (Exception e1) { LOG.info("no custom quartz-config file found. falling back to the default config provided by quartz."); InputStream inputStream = null; try { inputStream = ClassUtils.getClassLoader(null).getResourceAsStream("org/quartz/quartz.properties"); properties.load(inputStream); } catch (Exception e2) { LOG.warning("failed to load quartz default-config"); schedulerFactory = new StdSchedulerFactory(); } finally { if (inputStream != null) { inputStream.close(); } } } if (schedulerFactory == null) { schedulerFactory = new StdSchedulerFactory(properties); } } catch (Exception e) { LOG.log(Level.WARNING, "fallback to default scheduler-factory", e); schedulerFactory = new StdSchedulerFactory(); } try { this.scheduler = schedulerFactory.getScheduler(); if (SchedulerBaseConfig.LifecycleIntegration.START_SCOPES_PER_JOB) { this.scheduler.getListenerManager().addJobListener(new InjectionAwareJobListener()); } if (!this.scheduler.isStarted()) { this.scheduler.startDelayed(SchedulerBaseConfig.LifecycleIntegration.DELAYED_START_IN_SECONDS); } } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } protected ResourceBundle loadCustomQuartzConfig() { //don't use quartz.properties as default-value String configFile = SchedulerBaseConfig.SCHEDULER_CONFIG_FILE; return PropertyFileUtils.getResourceBundle(configFile); } @Override public void stop() { try { if (this.scheduler != null && this.scheduler.isStarted()) { this.scheduler.shutdown(!SchedulerBaseConfig.LifecycleIntegration.FORCE_STOP); this.scheduler = null; } } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public void registerNewJob(Class jobClass) { JobKey jobKey = createJobKey(jobClass); try { Scheduled scheduled = jobClass.getAnnotation(Scheduled.class); String description = scheduled.description(); if ("".equals(scheduled.description())) { description = jobClass.getName(); } JobDetail jobDetail = this.scheduler.getJobDetail(jobKey); Trigger trigger; if (jobDetail == null) { Class jobClassToAdd = createFinalJobClass(jobClass); jobDetail = JobBuilder.newJob(jobClassToAdd) .withDescription(description) .withIdentity(jobKey) .build(); scheduleNewJob(scheduled, jobKey, jobDetail); } else if (scheduled.overrideOnStartup()) { List existingTriggers = this.scheduler.getTriggersOfJob(jobKey); if (existingTriggers == null || existingTriggers.isEmpty()) { scheduleNewJob(scheduled, jobKey, jobDetail); return; } if (existingTriggers.size() > 1) { throw new IllegalStateException("multiple triggers found for " + jobKey + " ('" + jobDetail + "')" + ", but aren't supported by @" + Scheduled.class.getName() + "#overrideOnStartup"); } trigger = existingTriggers.iterator().next(); if (scheduled.cronExpression().startsWith("{") && scheduled.cronExpression().endsWith("}")) { this.scheduler.unscheduleJobs(Arrays.asList(trigger.getKey())); scheduleNewJob(scheduled, jobKey, jobDetail); } else { trigger = TriggerBuilder.newTrigger() .withIdentity(trigger.getKey()) .withSchedule(CronScheduleBuilder.cronSchedule(scheduled.cronExpression())) .build(); this.scheduler.rescheduleJob(trigger.getKey(), trigger); } } else { Logger.getLogger(AbstractQuartzScheduler.class.getName()).info( jobKey + " exists already and will be ignored."); } } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } private void scheduleNewJob(Scheduled scheduled, JobKey jobKey, JobDetail jobDetail) throws SchedulerException { String cronExpression = evaluateExpression(scheduled); this.scheduler.scheduleJob(jobDetail, createTrigger(scheduled, jobKey, cronExpression)); } private Trigger createTrigger(Scheduled scheduled, JobKey jobKey, String cronExpression) throws SchedulerException { UUID triggerKey = UUID.randomUUID(); if (!scheduled.cronExpression().endsWith(cronExpression)) { createExpressionObserverJob(jobKey, triggerKey, scheduled.cronExpression(), cronExpression); } Trigger trigger = TriggerBuilder.newTrigger() .forJob(jobKey) .withIdentity(triggerKey.toString()) .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); return trigger; } private void createExpressionObserverJob( JobKey jobKey, UUID triggerKey, String configExpression, String cronExpression) throws SchedulerException { if (!ClassDeactivationUtils.isActivated(DynamicExpressionObserverJob.class)) { return; } JobKey observerJobKey = new JobKey(jobKey.getName() + DynamicExpressionObserverJob.OBSERVER_POSTFIX, jobKey.getGroup()); JobDetail jobDetail = JobBuilder.newJob(DynamicExpressionObserverJob.class) .usingJobData(DynamicExpressionObserverJob.CONFIG_EXPRESSION_KEY, configExpression) .usingJobData(DynamicExpressionObserverJob.TRIGGER_ID_KEY, triggerKey.toString()) .usingJobData(DynamicExpressionObserverJob.ACTIVE_CRON_EXPRESSION_KEY, cronExpression) .withDescription("Config observer for: " + jobKey) .withIdentity(observerJobKey) .build(); Trigger trigger = TriggerBuilder.newTrigger() .forJob(observerJobKey) .withSchedule(CronScheduleBuilder.cronSchedule( SchedulerBaseConfig.JobCustomization.DYNAMIC_EXPRESSION_OBSERVER_INTERVAL)) .build(); this.scheduler.scheduleJob(jobDetail, trigger); } private String evaluateExpression(Scheduled scheduled) { String expression = scheduled.cronExpression(); if (expression.startsWith("{") && expression.endsWith("}")) { String configKey = expression.substring(1, expression.length() - 1); expression = ConfigResolver.getProjectStageAwarePropertyValue(configKey, null); if (expression == null) { throw new IllegalStateException("No config-value found for config-key: " + configKey); } } return expression; } protected abstract Class createFinalJobClass(Class jobClass); @Override public void startJobManually(Class jobClass) { try { this.scheduler.triggerJob(createJobKey(jobClass)); } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public void interruptJob(Class jobClass) { try { this.scheduler.interrupt(createJobKey(jobClass)); } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public boolean deleteJob(Class jobClass) { try { return this.scheduler.deleteJob(createJobKey(jobClass)); } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public void pauseJob(Class jobClass) { try { this.scheduler.pauseJob(createJobKey(jobClass)); } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public void resumeJob(Class jobClass) { try { this.scheduler.resumeJob(createJobKey(jobClass)); } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } @Override public boolean isExecutingJob(Class jobClass) { try { JobKey jobKey = createJobKey(jobClass); JobDetail jobDetail = this.scheduler.getJobDetail(jobKey); if (jobDetail == null) { return false; } for (JobExecutionContext jobExecutionContext : this.scheduler.getCurrentlyExecutingJobs()) { if (jobKey.equals(jobExecutionContext.getJobDetail().getKey())) { return true; } } return false; } catch (SchedulerException e) { throw ExceptionUtils.throwAsRuntimeException(e); } } private JobKey createJobKey(Class jobClass) { Scheduled scheduled = jobClass.getAnnotation(Scheduled.class); if (scheduled == null) { throw new IllegalStateException("@" + Scheduled.class.getName() + " is missing on " + jobClass.getName()); } String groupName = scheduled.group().getSimpleName(); String jobName = getJobName(jobClass); if (!Scheduled.class.getSimpleName().equals(groupName)) { return new JobKey(jobName, groupName); } return new JobKey(jobName); } protected String getJobName(Class jobClass) { return jobClass.getSimpleName(); } private class InjectionAwareJobListener implements JobListener { @Override public String getName() { return getClass().getName(); } @Override public void jobToBeExecuted(JobExecutionContext jobExecutionContext) { Class jobClass = ProxyUtils.getUnproxiedClass(jobExecutionContext.getJobInstance().getClass()); Scheduled scheduled = jobClass.getAnnotation(Scheduled.class); //can happen with manually registered job-instances (via #unwrap) if (scheduled == null && !jobClass.equals(DynamicExpressionObserverJob.class)) { scheduled = DEFAULT_SCHEDULED_LITERAL; } if (scheduled == null) { return; } JobListenerContext jobListenerContext = new JobListenerContext(); currentJobListenerContext.set(jobListenerContext); jobListenerContext.startContexts(scheduled); boolean jobInstanceIsBean; try { jobInstanceIsBean = Boolean.TRUE.equals(jobExecutionContext.getScheduler().getContext().get(jobClass.getName())); } catch (SchedulerException e) { jobInstanceIsBean = false; } if (!jobInstanceIsBean) { BeanProvider.injectFields(jobExecutionContext.getJobInstance()); } } @Override public void jobExecutionVetoed(JobExecutionContext context) { stopStartedScopes(); } @Override public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) { stopStartedScopes(); } private void stopStartedScopes() { JobListenerContext jobListenerContext = currentJobListenerContext.get(); if (jobListenerContext != null) { jobListenerContext.stopStartedScopes(); currentJobListenerContext.set(null); currentJobListenerContext.remove(); } } } private static class JobListenerContext { private Stack> scopes = new Stack>(); private DependentProvider contextControl; public void startContexts(Scheduled scheduled) { Collections.addAll(this.scopes, scheduled.startScopes()); if (!this.scopes.isEmpty()) { this.contextControl = BeanProvider.getDependent(ContextControl.class); for (Class scopeAnnotation : this.scopes) { contextControl.get().startContext(scopeAnnotation); } } } private void stopStartedScopes() { if (this.contextControl == null) { return; } while (!this.scopes.empty()) { this.contextControl.get().stopContext(this.scopes.pop()); } this.contextControl.destroy(); } } @Override public S unwrap(Class schedulerClass) { if (schedulerClass.isAssignableFrom(this.scheduler.getClass())) { return (S)this.scheduler; } throw new IllegalArgumentException(schedulerClass.getName() + " isn't compatible with " + this.scheduler.getClass().getName()); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/CdiAwareJobFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ClassUtils; import org.quartz.Job; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.spi.JobFactory; import org.quartz.spi.TriggerFiredBundle; public class CdiAwareJobFactory implements JobFactory { private final JobFactory defaultFactory; public CdiAwareJobFactory() { String defaultJobFactoryName = SchedulerBaseConfig.JobCustomization.DEFAULT_JOB_FACTORY_CLASS_NAME; defaultFactory = ClassUtils.tryToInstantiateClassForName(defaultJobFactoryName, JobFactory.class); } @Override public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler) throws SchedulerException { Job result = null; try { Class jobClass = bundle.getJobDetail().getJobClass(); result = BeanProvider.getContextualReference(jobClass); scheduler.getContext().put(jobClass.getName(), Boolean.TRUE); } catch (Exception e) { if (result == null) { result = defaultFactory.newJob(bundle, scheduler); } } return result; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/DynamicExpressionObserverJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.quartz.CronScheduleBuilder; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.PersistJobDataAfterExecution; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import jakarta.inject.Inject; import java.util.logging.Logger; /** * This job is only active, if configurable cron-expressions are used - e.g.: @Scheduled(cronExpression = "{myKey}"). * It observes jobs with configurable cron-expressions and updates their job-triggers once a config-change was detected. * Per default this job gets executed once per minute. That can be changed via config-entry: * deltaspike.scheduler.dynamic-expression.observer-interval=[any valid cron-expression] */ @DisallowConcurrentExecution @PersistJobDataAfterExecution public class DynamicExpressionObserverJob implements Deactivatable, Job { static final String CONFIG_EXPRESSION_KEY = "ds_configExpression"; static final String ACTIVE_CRON_EXPRESSION_KEY = "ds_activeCronExpression"; static final String TRIGGER_ID_KEY = "ds_triggerKey"; static final String OBSERVER_POSTFIX = "_observer"; private static final Logger LOG = Logger.getLogger(DynamicExpressionObserverJob.class.getName()); @Inject private Scheduler scheduler; @Override public void execute(JobExecutionContext context) throws JobExecutionException { JobDataMap jobDataMap = context.getMergedJobDataMap(); String configExpression = jobDataMap.getString(CONFIG_EXPRESSION_KEY); String triggerId = jobDataMap.getString(TRIGGER_ID_KEY); String activeCronExpression = jobDataMap.getString(ACTIVE_CRON_EXPRESSION_KEY); String configKey = configExpression.substring(1, configExpression.length() - 1); String configuredValue = ConfigResolver.getPropertyAwarePropertyValue(configKey, activeCronExpression); if (!activeCronExpression.equals(configuredValue)) { //both #put calls are needed currently context.getJobDetail().getJobDataMap().put(ACTIVE_CRON_EXPRESSION_KEY, configuredValue); context.getTrigger().getJobDataMap().put(ACTIVE_CRON_EXPRESSION_KEY, configuredValue); BeanProvider.injectFields(this); JobKey observerJobKey = context.getJobDetail().getKey(); String observedJobName = observerJobKey.getName() .substring(0, observerJobKey.getName().length() - OBSERVER_POSTFIX.length()); JobKey observedJobKey = new JobKey(observedJobName, observerJobKey.getGroup()); Trigger trigger = TriggerBuilder.newTrigger() .withIdentity(triggerId) .forJob(observedJobName, observedJobKey.getGroup()) .withSchedule(CronScheduleBuilder.cronSchedule(configuredValue)) .build(); //use rescheduleJob instead of delete + add //(unwrap is ok here, because this class will only get active in case of a quartz-scheduler) org.quartz.Scheduler quartzScheduler = scheduler.unwrap(org.quartz.Scheduler.class); try { quartzScheduler.rescheduleJob(trigger.getKey(), trigger); } catch (SchedulerException e) { LOG.warning("failed to updated cron-expression for " + observedJobKey); } } } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/JobAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import jakarta.enterprise.inject.Vetoed; //configured via SchedulerBaseConfig @Vetoed public class JobAdapter extends AbstractJobAdapter { @Override protected Class getJobBaseClass() { return Job.class; } @Override public void execute(Job job, JobExecutionContext context) throws JobExecutionException { job.execute(context); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/JobQuartzScheduler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.quartz.Job; //vetoed class (see SchedulerExtension) public class JobQuartzScheduler extends AbstractQuartzScheduler { @Override protected String getJobName(Class jobClass) { return jobClass.getName(); } @Override protected Class createFinalJobClass(Class jobClass) { return JobAdapter.class; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/JobRunnableAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.quartz.JobExecutionContext; import jakarta.enterprise.inject.Vetoed; //configured via SchedulerBaseConfig @Vetoed public class JobRunnableAdapter extends AbstractJobAdapter { @Override protected Class getJobBaseClass() { return Runnable.class; } @Override public void execute(Runnable job, JobExecutionContext context) { job.run(); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/QuartzSchedulerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.quartz.Job; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.Produces; @Alternative public class QuartzSchedulerProducer extends SchedulerProducer { @Produces @ApplicationScoped protected Scheduler produceScheduler() { return super.produceScheduler(); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/RunnableQuartzScheduler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.util.ClassUtils; import org.quartz.Job; //vetoed class (see SchedulerExtension) public class RunnableQuartzScheduler extends AbstractQuartzScheduler { private Class runnableAdapter; @Override public void start() { String configuredAdapterClassName = SchedulerBaseConfig.JobCustomization.RUNNABLE_ADAPTER_CLASS_NAME; this.runnableAdapter = ClassUtils.tryToLoadClassForName(configuredAdapterClassName, Job.class); super.start(); } @Override protected String getJobName(Class jobClass) { return jobClass.getName(); } @Override protected Class createFinalJobClass(Class jobClass) { return runnableAdapter; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/SchedulerBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; //keep it in the impl. module for now, because it's mainly quartz specific config public interface SchedulerBaseConfig extends DeltaSpikeBaseConfig { interface JobCustomization { String JOB_CLASS_NAME_KEY = "deltaspike.scheduler.job-class"; String RUNNABLE_ADAPTER_CLASS_NAME_KEY = "deltaspike.scheduler.runnable-adapter-class"; String DYNAMIC_EXPRESSION_OBSERVER_INTERVAL_KEY = "deltaspike.scheduler.dynamic-expression.observer-interval"; //don't type it to class to keep quartz optional String DEFAULT_JOB_FACTORY_CLASS_NAME = ConfigResolver.resolve("deltaspike.scheduler.DefaultJobFactory") .withCurrentProjectStage(true) .withDefault("org.quartz.simpl.PropertySettingJobFactory") .getValue(); //don't type it to class to keep quartz optional String JOB_CLASS_NAME = ConfigResolver.resolve(JOB_CLASS_NAME_KEY) .withCurrentProjectStage(true) .withDefault("org.quartz.Job") .getValue(); //don't type it to class to keep quartz optional (JobRunnableAdapter imports classes from quartz) String RUNNABLE_ADAPTER_CLASS_NAME = ConfigResolver.resolve(RUNNABLE_ADAPTER_CLASS_NAME_KEY) .withCurrentProjectStage(true) .withDefault("org.apache.deltaspike.scheduler.impl.JobRunnableAdapter") .getValue(); String DYNAMIC_EXPRESSION_OBSERVER_INTERVAL = ConfigResolver.resolve(DYNAMIC_EXPRESSION_OBSERVER_INTERVAL_KEY) .withCurrentProjectStage(true) .withDefault("0 0/1 * * * ?") .getValue(); } String SCHEDULER_CONFIG_FILE = ConfigResolver.resolve("deltaspike.scheduler.quartz_config-file") .withCurrentProjectStage(true) .withDefault("quartz") .getValue(); interface LifecycleIntegration { String START_SCOPES_PER_JOB_KEY = "deltaspike.scheduler.start_scopes_for_jobs"; Boolean START_SCOPES_PER_JOB = ConfigResolver.resolve(START_SCOPES_PER_JOB_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.TRUE) .getValue(); Boolean FORCE_STOP = ConfigResolver.resolve("deltaspike.scheduler.force_stop") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); Integer DELAYED_START_IN_SECONDS = ConfigResolver.resolve("deltaspike.scheduler.delayed_start_in_seconds") .as(Integer.class) .withCurrentProjectStage(true) .withDefault(1) .getValue(); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/SchedulerExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.scheduler.api.Scheduled; import org.apache.deltaspike.scheduler.spi.SchedulerControl; import org.apache.deltaspike.scheduler.spi.Scheduler; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.*; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; public class SchedulerExtension implements Extension, Deactivatable { private static final Logger LOG = Logger.getLogger(SchedulerExtension.class.getName()); //keep it as a string (needed by some containers - due to the imports) private static Set classNamesToVeto = new HashSet(); private Boolean isActivated = true; private Set foundManagedJobClasses = new HashSet(); private Scheduler scheduler; private Class jobClass; public SchedulerExtension() { classNamesToVeto.add("org.apache.deltaspike.scheduler.impl.DynamicExpressionObserverJob"); } protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { this.isActivated = ClassDeactivationUtils.isActivated(getClass()); if (this.isActivated) { String jobClassName = SchedulerBaseConfig.JobCustomization.JOB_CLASS_NAME; this.jobClass = ClassUtils.tryToLoadClassForName(jobClassName); if (this.jobClass == null) { this.isActivated = false; } } } public void findScheduledJobs(@Observes ProcessAnnotatedType pat, BeanManager beanManager) { if (!this.isActivated) { return; } Class beanClass = pat.getAnnotatedType().getJavaClass(); //see SchedulerProducer if (Scheduler.class.isAssignableFrom(beanClass) || isInternalUnmanagedClass(beanClass)) { pat.veto(); return; } if (!jobClass.isAssignableFrom(beanClass) && !Runnable.class.isAssignableFrom(beanClass)) { return; } Scheduled scheduled = pat.getAnnotatedType().getAnnotation(Scheduled.class); if (scheduled != null && scheduled.onStartup()) { this.foundManagedJobClasses.add(beanClass); } } private boolean isInternalUnmanagedClass(Class beanClass) { return classNamesToVeto.contains(beanClass.getName()); } public void validateJobs(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { if (!this.isActivated) { return; } Class configuredJobClass = this.jobClass; this.jobClass = resolveFinalJobType(); if (this.jobClass == null) { afterBeanDiscovery.addDefinitionError(new IllegalStateException("Please only annotate classes with @" + Scheduled.class.getName() + " of type " + configuredJobClass.getName() + " or of type " + Runnable.class.getName() + ", but not both!")); return; } } public void scheduleJobs(@Observes AfterDeploymentValidation afterDeploymentValidation, BeanManager beanManager) { if (!this.isActivated) { return; } SchedulerControl schedulerControl = BeanProvider.getContextualReference(SchedulerControl.class, true); if (schedulerControl != null && !schedulerControl.isSchedulerEnabled()) { LOG.info("Scheduler has been disabled by " + ProxyUtils.getUnproxiedClass(schedulerControl.getClass())); return; } initScheduler(afterDeploymentValidation); if (this.scheduler == null) { return; } List foundJobNames = new ArrayList(); for (Class jobClass : this.foundManagedJobClasses) { if (foundJobNames.contains(jobClass.getSimpleName())) { afterDeploymentValidation.addDeploymentProblem( new IllegalStateException("Multiple Job-Classes found with name " + jobClass.getSimpleName())); } foundJobNames.add(jobClass.getSimpleName()); this.scheduler.registerNewJob(jobClass); } } /** * Allows to support implementations of {@link java.lang.Runnable} * annotated with {@link Scheduled} >without< explicit config. * @return the job-type which will be used to select the scheduler */ protected Class resolveFinalJobType() { Set foundTypes = new HashSet(); for (Class foundJobClass : this.foundManagedJobClasses) { if (jobClass.isAssignableFrom(foundJobClass)) { foundTypes.add(jobClass); } else if (Runnable.class.isAssignableFrom(foundJobClass)) { foundTypes.add(Runnable.class); } } if (foundTypes.size() > 1) { return null; } else if (foundTypes.size() == 1) { return foundTypes.iterator().next(); } else { //use the configured type //it's still useful if there is no annotated job-class, but a dyn. usage of the scheduler is still possible return jobClass; } } public void stopScheduler(@Observes BeforeShutdown beforeShutdown) { if (!this.isActivated) { return; } if (this.scheduler != null) { this.scheduler.stop(); this.scheduler = null; } } private void initScheduler(AfterDeploymentValidation afterDeploymentValidation) { List availableSchedulers = ServiceUtils.loadServiceImplementations(Scheduler.class, true); this.scheduler = findScheduler(availableSchedulers, this.jobClass); if (this.scheduler != null) { try { this.scheduler.start(); } catch (Throwable t) { afterDeploymentValidation.addDeploymentProblem(t); } } else if (!this.foundManagedJobClasses.isEmpty()) { LOG.warning( this.foundManagedJobClasses.size() + " scheduling-jobs found, but there is no configured scheduler"); } } private static Scheduler findScheduler(List availableSchedulers, Class jobClass) { for (Scheduler scheduler : availableSchedulers) { //in case of implementing the Scheduler interface directly for (Type interfaceClass : scheduler.getClass().getGenericInterfaces()) { if (!(interfaceClass instanceof ParameterizedType) || !Scheduler.class.isAssignableFrom((Class)((ParameterizedType)interfaceClass).getRawType())) { continue; } if (jobClass.isAssignableFrom(((Class)((ParameterizedType)interfaceClass).getActualTypeArguments()[0]))) { return scheduler; } } //in case of extending e.g. AbstractQuartzScheduler if (scheduler.getClass().getGenericSuperclass() instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) scheduler.getClass().getGenericSuperclass(); for (Type typeArgument : parameterizedType.getActualTypeArguments()) { if (jobClass.isAssignableFrom((Class)typeArgument)) { return scheduler; } } } } return null; } Scheduler getScheduler() { return scheduler; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/java/org/apache/deltaspike/scheduler/impl/SchedulerProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.scheduler.impl; import org.apache.deltaspike.scheduler.spi.Scheduler; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.inject.Inject; @ApplicationScoped public class SchedulerProducer { @Inject private SchedulerExtension schedulerExtension; @Produces @ApplicationScoped protected Scheduler produceScheduler() { return this.schedulerExtension.getScheduler(); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.scheduler.impl.SchedulerExtension ================================================ FILE: deltaspike/modules/scheduler/impl/src/main/resources/META-INF/services/org.apache.deltaspike.scheduler.spi.Scheduler ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #only one of the following schedulers will get active #default scheduler: org.apache.deltaspike.scheduler.impl.JobQuartzScheduler #alternative scheduler - add # deltaspike.scheduler.job-class=java.lang.Runnable #to META-INF/apache-deltaspike.properties org.apache.deltaspike.scheduler.impl.RunnableQuartzScheduler ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/AutoRegisteredJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.scheduler.api.Scheduled; @Scheduled(cronExpression = "*/1 * * * * ?") public class AutoRegisteredJob implements CustomJob { } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.scheduler.impl.SchedulerBaseConfig; import java.util.HashMap; import java.util.Map; public class CustomConfigSource implements ConfigSource { private Map config = new HashMap() {{ put(SchedulerBaseConfig.JobCustomization.JOB_CLASS_NAME_KEY, CustomJob.class.getName()); put(ClassDeactivator.class.getName(), QuartzDeactivator.class.getName()); }}; @Override public int getOrdinal() { return 1001; } @Override public Map getProperties() { return this.config; } @Override public String getPropertyValue(String key) { return this.config.get(key); } @Override public String getConfigName() { return "scheduler-test-config"; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomDeactivatedConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.scheduler.impl.SchedulerBaseConfig; import java.util.HashMap; import java.util.Map; public class CustomDeactivatedConfigSource implements ConfigSource { private Map config = new HashMap() {{ put(SchedulerBaseConfig.JobCustomization.JOB_CLASS_NAME_KEY, CustomJob.class.getName()); put(SchedulerBaseConfig.LifecycleIntegration.START_SCOPES_PER_JOB_KEY, Boolean.FALSE.toString()); put(ClassDeactivator.class.getName(), QuartzDeactivator.class.getName()); }}; @Override public int getOrdinal() { return 1001; } @Override public Map getProperties() { return this.config; } @Override public String getPropertyValue(String key) { return this.config.get(key); } @Override public String getConfigName() { return "scheduler-test-config"; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; public interface CustomJob { } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomSchedulerEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class CustomSchedulerEarFileTest extends CustomSchedulerTest { @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = CustomSchedulerWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsModule(CustomSchedulerWarFileTest.deploy()); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomSchedulerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import junit.framework.Assert; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.junit.Test; import jakarta.inject.Inject; public abstract class CustomSchedulerTest { @Inject private Scheduler scheduler; //workaround for weld-se - as an alternative it's possible to use: /* private Scheduler scheduler; @Before public void init() { this.scheduler = BeanProvider.getContextualReference(Scheduler.class); } */ @Inject private TestJobManager testJobManager; @Test public void checkAutoRegisteredSchedulerJob() { Assert.assertTrue(testJobManager.isStarted()); Assert.assertEquals(1, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(AutoRegisteredJob.class, testJobManager.getRegisteredJobs().iterator().next()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); Assert.assertEquals(AutoRegisteredJob.class, testJobManager.getRunningJobs().iterator().next()); } @Test public void checkManualSchedulerJobManagement() { Assert.assertTrue(testJobManager.isStarted()); Assert.assertEquals(1, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(AutoRegisteredJob.class, testJobManager.getRegisteredJobs().iterator().next()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); Assert.assertEquals(AutoRegisteredJob.class, testJobManager.getRunningJobs().iterator().next()); this.scheduler.registerNewJob(ManualJob.class); Assert.assertEquals(2, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(2, testJobManager.getRunningJobs().size()); this.scheduler.interruptJob(ManualJob.class); Assert.assertEquals(2, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); this.scheduler.pauseJob(ManualJob.class); Assert.assertEquals(1, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); this.scheduler.resumeJob(ManualJob.class); Assert.assertEquals(2, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); this.scheduler.startJobManually(ManualJob.class); Assert.assertEquals(2, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(2, testJobManager.getRunningJobs().size()); this.scheduler.interruptJob(ManualJob.class); this.scheduler.pauseJob(ManualJob.class); Assert.assertEquals(1, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(1, testJobManager.getRunningJobs().size()); } @Test public void checkDeleteJob() { this.scheduler.registerNewJob(DeleteJob.class); Assert.assertTrue(testJobManager.getRegisteredJobs().contains(DeleteJob.class)); this.scheduler.interruptJob(DeleteJob.class); this.scheduler.deleteJob(DeleteJob.class); Assert.assertFalse(testJobManager.getRegisteredJobs().contains(DeleteJob.class)); } @Test public void unwrap() { Assert.assertEquals(TestJobManager.class, this.scheduler.unwrap(TestJobManager.class).getClass()); } @Test(expected = IllegalArgumentException.class) public void invalidUnwrap() { this.scheduler.unwrap(MockedScheduler.class); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/CustomSchedulerWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.utils.BeansXmlUtil; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; 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.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.junit.runner.RunWith; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class CustomSchedulerWarFileTest extends CustomSchedulerTest { @Deployment public static WebArchive deploy() { String simpleName = CustomSchedulerWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "customSchedulerTest.jar") .addPackage(CustomSchedulerWarFileTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml") .addAsResource(new StringAsset(MockedScheduler.class.getName()), "META-INF/services/" + Scheduler.class.getName()) .addAsResource(new StringAsset(CustomConfigSource.class.getName()), "META-INF/services/" + ConfigSource.class.getName()); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSchedulerArchive()) .addAsLibraries(ArchiveUtils.getContextControlForDeployment()) .addAsLibraries(Maven.resolver().loadPomFromFile("pom.xml").resolve( "org.quartz-scheduler:quartz") .withTransitivity() .asFile()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/DeleteJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.scheduler.api.Scheduled; @Scheduled(cronExpression = "*/1 * * * * ?", onStartup = false) public class DeleteJob implements CustomJob { } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/ManualJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.scheduler.api.Scheduled; @Scheduled(cronExpression = "*/1 * * * * ?", onStartup = false) public class ManualJob implements CustomJob { } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/MockedScheduler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.scheduler.spi.Scheduler; public class MockedScheduler implements Scheduler { @Override public void start() { TestJobManager.getInstance().start(); } @Override public void stop() { TestJobManager.getInstance().stop(); } public void pauseJob(Class jobClass) { TestJobManager.getInstance().pauseJob(jobClass); } public void resumeJob(Class jobClass) { TestJobManager.getInstance().resumeJob(jobClass); } public void interruptJob(Class jobClass) { TestJobManager.getInstance().interruptJob(jobClass); } public boolean deleteJob(Class jobClass) { return TestJobManager.getInstance().deleteJob(jobClass); } public boolean isExecutingJob(Class jobClass) { return TestJobManager.getInstance().isExecutingJob(jobClass); } public void registerNewJob(Class jobClass) { TestJobManager.getInstance().registerNewJob(jobClass); } public void startJobManually(Class jobClass) { TestJobManager.getInstance().startJobManually(jobClass); } @Override public S unwrap(Class schedulerClass) { if (schedulerClass.isAssignableFrom(TestJobManager.getInstance().getClass())) { return (S)TestJobManager.getInstance(); } throw new IllegalArgumentException(schedulerClass.getName() + " isn't compatible with " + TestJobManager.getInstance().getClass().getName()); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/QuartzDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; public class QuartzDeactivator implements ClassDeactivator { private static final long serialVersionUID = 6185043496640765473L; @Override public Boolean isActivated(Class targetClass) { return !"QuartzScheduler".equals(targetClass.getSimpleName()) && !"RunnableQuartzScheduler".equals(targetClass.getSimpleName()); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/RequestScopedJob.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import org.apache.deltaspike.scheduler.api.Scheduled; import jakarta.enterprise.context.RequestScoped; @RequestScoped @Scheduled(cronExpression = "*/1 * * * * ?", onStartup = false) public class RequestScopedJob implements CustomJob { } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/ScopeNotStartedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import junit.framework.Assert; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.scheduler.spi.Scheduler; import org.apache.deltaspike.test.util.ArchiveUtils; import org.apache.deltaspike.test.utils.BeansXmlUtil; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; 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.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.junit.Test; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; @RunWith(Arquillian.class) public class ScopeNotStartedTest { //TODO even though this test exists, the tests in this module don't execute for quartz. @Deployment public static WebArchive deploy() { String simpleName = ScopeNotStartedTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive testJar = ShrinkWrap.create(JavaArchive.class, "scopeNotStartedTest.jar") .addPackage(CustomSchedulerWarFileTest.class.getPackage().getName()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml") .addAsResource(new StringAsset(MockedScheduler.class.getName()), "META-INF/services/" + Scheduler.class.getName()) .addAsResource(new StringAsset(CustomDeactivatedConfigSource.class.getName()), "META-INF/services/" + ConfigSource.class.getName()); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSchedulerArchive()) .addAsLibraries(ArchiveUtils.getContextControlForDeployment()) .addAsLibraries(Maven.resolver().loadPomFromFile("pom.xml").resolve( "org.quartz-scheduler:quartz") .withTransitivity() .asFile()) .addAsLibraries(testJar) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } @Inject private Scheduler scheduler; @Inject private TestJobManager testJobManager; @Test public void testRegisterBadJob() { Assert.assertTrue(testJobManager.isStarted()); this.scheduler.registerNewJob(ManualJob.class); Assert.assertEquals(2, testJobManager.getRegisteredJobs().size()); Assert.assertEquals(2, testJobManager.getRunningJobs().size()); } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/scheduler/custom/TestJobManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.scheduler.custom; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Typed; import java.util.ArrayList; import java.util.List; @Typed() // This bean doesn't get vetoed because it contains producer methods. But we don't want it to be injected with this type public class TestJobManager { private static TestJobManager currentManager = new TestJobManager(); private boolean started; private List> registeredJobs = new ArrayList>(); private List> runningJobs = new ArrayList>(); public static TestJobManager getInstance() { return currentManager; } @Produces @ApplicationScoped protected TestJobManager expose() { return currentManager; } public void start() { this.started = true; } public void stop() { currentManager = new TestJobManager(); } public void pauseJob(Class jobClass) { this.registeredJobs.remove(jobClass); } public void resumeJob(Class jobClass) { this.registeredJobs.add(jobClass); } public void interruptJob(Class jobClass) { this.runningJobs.remove(jobClass); } public boolean deleteJob(Class jobClass) { return this.registeredJobs.remove(jobClass); } public boolean isExecutingJob(Class jobClass) { return this.runningJobs.contains(jobClass); } public void registerNewJob(Class jobClass) { this.registeredJobs.add(jobClass); this.runningJobs.add(jobClass); } public void startJobManually(Class jobClass) { this.runningJobs.add(jobClass); } public boolean isStarted() { return started; } public List> getRegisteredJobs() { return registeredJobs; } public List> getRunningJobs() { return runningJobs; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/java/org/apache/deltaspike/test/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * This class contains helpers for building frequently used archives */ public class ArchiveUtils { private ArchiveUtils() { } public static JavaArchive[] getDeltaSpikeCoreAndSchedulerArchive() { return ShrinkWrapArchiveUtil.getArchives( null, "META-INF/beans.xml", new String[]{"org.apache.deltaspike.core", "org.apache.deltaspike.test.category", "org.apache.deltaspike.scheduler"}, null, "ds-core_and_scheduler"); } public static JavaArchive getContextControlForDeployment() { JavaArchive jar = ShrinkWrap.create(JavaArchive.class, "cdi-control.jar") .addClass(ContextControl.class); if (CdiContainerUnderTest.is("owb")) { jar.addPackage("org.apache.deltaspike.cdise.owb"); } return jar; } } ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource ================================================ ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.test.scheduler.custom.CustomConfigSource ================================================ FILE: deltaspike/modules/scheduler/impl/src/test/resources/META-INF/services/org.apache.deltaspike.scheduler.spi.Scheduler ================================================ ##################################################################################### # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ##################################################################################### org.apache.deltaspike.test.scheduler.custom.MockedScheduler ================================================ FILE: deltaspike/modules/scheduler/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules scheduler-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Scheduler-Module api impl ================================================ FILE: deltaspike/modules/security/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules security-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-security-module-api jar Apache DeltaSpike Security-Module API org.apache.deltaspike.security.* * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.apache.deltaspike.core deltaspike-core-api ${project.version} ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/SecurityException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api; /** * Any exception that is raised by the security module extends from this runtime * exception class, making it easy for other modules and extensions to catch all * security-related exceptions in a single catch block, if need be. */ public abstract class SecurityException extends RuntimeException { private static final long serialVersionUID = 789326682407249952L; public SecurityException() { super(); } public SecurityException(String message, Throwable cause) { super(message, cause); } public SecurityException(String message) { super(message); } public SecurityException(Throwable cause) { super(cause); } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AbstractAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.util.HashSet; import java.util.Set; /** * Base implementation which provides helper methods. */ public abstract class AbstractAccessDecisionVoter extends AbstractDecisionVoter implements AccessDecisionVoter { private static final long serialVersionUID = -9145021044568668681L; /** * It should be final - but proxy-libs won't support it. */ @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { Set result = new HashSet(); checkPermission(accessDecisionVoterContext, result); return result; } /** * Allows an easier implementation in combination with {@link #newSecurityViolation(String)}. * * @param accessDecisionVoterContext current accessDecisionVoterContext * @param violations set for adding violations */ protected abstract void checkPermission(AccessDecisionVoterContext accessDecisionVoterContext, Set violations); } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AbstractDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; /** * Base class for decision-voters */ //can be used also for similar parts //e.g. for custom scopes. like it was done in CODI (see AbstractBeanCreationDecisionVoter) public abstract class AbstractDecisionVoter { /** * Creates an instance of {@link SecurityViolation} for a given * string which will be used as reason to describe the violation. * * @param reason description of the violation * @return A new instance of {@link SecurityViolation} * which provides details about the found restriction. */ protected SecurityViolation newSecurityViolation(String reason) { return new SimpleSecurityViolation(reason); } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AccessDecisionState.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; /** * State-enum for {@link AccessDecisionVoterContext} */ public enum AccessDecisionState { INITIAL, VOTE_IN_PROGRESS, VIOLATION_FOUND, NO_VIOLATION_FOUND } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import java.io.Serializable; import java.util.Set; /** * Interface for implementing concrete voters. * A voter has to add an instance of * {@link SecurityViolation} to the given result-set, * if a restriction is detected.

* A voter has to be used in combination with * {@link Secured}.

* A voter can use every scope which is active. It's recommended to use * {@link jakarta.enterprise.context.ApplicationScoped} for stateless voters and e.g. * {@link jakarta.enterprise.context.RequestScoped} otherwise. */ public interface AccessDecisionVoter extends Serializable { /** * Checks the permission for the given {@link jakarta.interceptor.InvocationContext}. * If a violation is detected, it should be added to a set which gets returned by the method. * * @param accessDecisionVoterContext current access-decision-voter-context * @return a set which contains violations which have been detected */ @DefaultCallback Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext); } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AccessDecisionVoterContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.util.List; import java.util.Map; /** * Optional context which allows to get the current state as well as the results of the security check. * (Optional because it requires a useful scope which depends on the environment.) */ public interface AccessDecisionVoterContext { /** * Exposes the current state * @return current state */ AccessDecisionState getState(); /** * Exposes the found violations * @return found violations */ List getViolations(); /** * TODO review it (this method is new) * Exposes the source e.g. {@link jakarta.interceptor.InvocationContext} * @return the source which triggered the */ T getSource(); /** * Exposes the found meta-data * @return found meta-data */ Map getMetaData(); /** * Exposes meta-data for the given key * @param key meta-data key * @param targetType target type * @param target type * @return meta-data for the given key or null if there is no value for the given key */ T getMetaDataFor(String key, Class targetType); } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/AccessDeniedException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.util.Set; /** * Exception occurs in case of a security-violation. * It's aware of the reason for the violation as well as the error-view which should be used to display the restriction. */ public class AccessDeniedException extends SecurityException { private static final long serialVersionUID = -4066763895951237969L; private Set violations; /** * Constructor for creating the exception for the given violations and error-view * @param violations current violations */ public AccessDeniedException(Set violations) { this.violations = violations; } /** * All {@link SecurityViolation} which were found by a {@link AccessDecisionVoter} * * @return all security-violations */ public Set getViolations() { return violations; } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/ErrorViewAwareAccessDeniedException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import org.apache.deltaspike.core.api.config.view.ViewConfig; import java.util.Set; public class ErrorViewAwareAccessDeniedException extends AccessDeniedException { private static final long serialVersionUID = 3292231690460417731L; private final Class errorView; public ErrorViewAwareAccessDeniedException(Set violations, Class errorView) { super(violations); this.errorView = errorView; } public Class getErrorView() { return errorView; } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/Secured.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import org.apache.deltaspike.core.api.config.view.DefaultErrorView; import org.apache.deltaspike.core.api.config.view.ViewConfig; import org.apache.deltaspike.core.api.config.view.metadata.ExecutableCallbackDescriptor; import org.apache.deltaspike.core.api.config.view.metadata.DefaultCallback; import org.apache.deltaspike.core.api.config.view.metadata.ViewMetaData; import org.apache.deltaspike.core.spi.config.view.ConfigPreProcessor; import org.apache.deltaspike.core.spi.config.view.ViewConfigNode; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.List; import java.util.Set; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Interceptor for securing beans. * It's also possible to use it as meta-annotation for type-safe view-configs. */ @Target({ TYPE, METHOD, ANNOTATION_TYPE }) @Retention(RUNTIME) @Documented //cdi annotations @SecurityBindingType //don't use @Aggregated(true) - we need to support different error-pages (per folder/page) @ViewMetaData(preProcessor = Secured.AnnotationPreProcessor.class) public @interface Secured { /** * {@link AccessDecisionVoter}s which will be invoked before accessing the intercepted instance or in case of * view-configs before a view gets used. * * @return the configured access-decision-voters which should be used for the voting process */ @Nonbinding Class[] value(); /** * Optional inline error-view if it is required to show an error-page * which is different from the default error page. * @return type-safe view-config of the page which should be used as error-view */ @Nonbinding Class errorView() default DefaultErrorView.class; class AnnotationPreProcessor implements ConfigPreProcessor { @Override public Secured beforeAddToConfig(Secured metaData, ViewConfigNode viewConfigNode) { viewConfigNode.registerCallbackDescriptors(Secured.class, new Descriptor(metaData.value())); return metaData; //no change needed } } //can be used from outside to get a typed result static class Descriptor extends ExecutableCallbackDescriptor> { public Descriptor(Class[] accessDecisionVoterBeanClasses) { super(accessDecisionVoterBeanClasses, DefaultCallback.class); } public List> execute(AccessDecisionVoterContext accessDecisionVoterContext) { return super.execute(accessDecisionVoterContext); } } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SecuredReturn.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks an argument of a {@link Secures} method to be the result of the secured business method invocation. * If present, forces the {@link Secures} check to occure after invocation of the business method. */ @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface SecuredReturn { } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/Secures.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This annotation is used to delegate a method as the provider for a specific authorization check */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Secures { } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SecurityBindingType.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Applied to an annotation to indicate that it is a security binding type */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SecurityBindingType { } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SecurityDefinitionException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; /** * This exception is thrown when a security-related configuration error is detected, * such as a missing or ambiguous security binding type */ public class SecurityDefinitionException extends org.apache.deltaspike.security.api.SecurityException { private static final long serialVersionUID = -5683365417825375411L; public SecurityDefinitionException(String message) { super(message); } @SuppressWarnings("UnusedDeclaration") public SecurityDefinitionException(Throwable cause) { super(cause); } public SecurityDefinitionException(String message, Throwable cause) { super(message, cause); } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SecurityParameterBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Applied to an {@link java.lang.annotation.Annotation} to declare it as a security parameter binding; to use business * method invocation values as {@link Secures} method arguments. */ @Documented @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface SecurityParameterBinding { } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SecurityViolation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; import java.io.Serializable; /** * Provides the concrete reason for the restriction. */ public interface SecurityViolation extends Serializable { /** * Provides a description of the violation. * * @return description of the violation */ String getReason(); } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/api/authorization/SimpleSecurityViolation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.api.authorization; /** * Implementation which just returns the given reason */ class SimpleSecurityViolation implements SecurityViolation { private static final long serialVersionUID = -5017812464381395966L; private final String reason; SimpleSecurityViolation(String reason) { this.reason = reason; } @Override public String getReason() { return reason; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof SimpleSecurityViolation)) { return false; } SimpleSecurityViolation that = (SimpleSecurityViolation) o; return reason != null ? reason.equals(that.reason) : that.reason == null; } @Override public int hashCode() { return reason != null ? reason.hashCode() : 0; } } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/authorization/EditableAccessDecisionVoterContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.spi.authorization; import org.apache.deltaspike.security.api.authorization.AccessDecisionState; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; /** * Interface which allows to provide a custom {@link AccessDecisionVoterContext} implementation */ public interface EditableAccessDecisionVoterContext extends AccessDecisionVoterContext { /** * Allows to add custom meta-data. The default security strategy adds custom annotations of the intercepted method * as well as class-level annotations. (Currently inherited annotations aren't supported) * @param key key for the meta-data * @param metaData meta-data which should be added */ void addMetaData(String key, Object metaData); /** * Updates the state of the context * @param accessDecisionVoterState current state */ void setState(AccessDecisionState accessDecisionVoterState); /** * TODO review it (this method is new) * @param source e.g. the invocation-context */ void setSource(Object source); /** * Adds a new {@link SecurityViolation} to the context * @param securityViolation security-violation which should be added */ void addViolation(SecurityViolation securityViolation); } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/authorization/SecurityStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.spi.authorization; import org.apache.deltaspike.core.spi.InterceptorStrategy; /** * Marker interface for a pluggable strategy for * {@link org.apache.deltaspike.security.api.authorization.Secured} */ public interface SecurityStrategy extends InterceptorStrategy { } ================================================ FILE: deltaspike/modules/security/api/src/main/java/org/apache/deltaspike/security/spi/authorization/SecurityViolationHandler.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.spi.authorization; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import java.util.Set; /** * Allows to handle custom implementations of {@link SecurityViolation} */ public interface SecurityViolationHandler { /** * Instead of adding the violations as message for the user, it's possible to implement a custom behaviour * (e.g. something like an InternalViolation which won't get added) * @param securityViolations current violations */ void processSecurityViolations(Set securityViolations); } ================================================ FILE: deltaspike/modules/security/api/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/security/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules security-module-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules deltaspike-security-module-impl jar Apache DeltaSpike Security-Module Impl org.apache.deltaspike.security.impl.* * osgi.extender; filter:="(osgi.extender=pax.cdi)" org.ops4j.pax.cdi.extension; extension=deltaspike-security-module-impl org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.core deltaspike-core-impl ${project.version} org.apache.deltaspike.modules deltaspike-security-module-api ${project.version} ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/authorization/AccessDeniedExceptionBroadcaster.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.authorization; //X TODO import org.apache.deltaspike.core.api.exception.control.event.ExceptionToCatchEvent; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; //this broadcaster just allows to change the default behavior (if needed) //needed because it needs to be possible to 'consume' exceptions of type AccessDeniedException. //instead of ignoring the result of exception-control and throwing them in any case (like we have to do it per default). @Dependent public class AccessDeniedExceptionBroadcaster { @Inject private BeanManager beanManager; public void broadcastAccessDeniedException(AccessDeniedException accessDeniedException) { /* TODO: gpetracek please ExceptionToCatchEvent exceptionToCatchEvent = new ExceptionToCatchEvent(accessDeniedException); try { this.beanManager.fireEvent(exceptionToCatchEvent); } catch (AccessDeniedException e) { throw new SkipInternalProcessingException(accessDeniedException); } */ //we have to throw it in any case to support "observers" for AccessDeniedException (see DELTASPIKE-636) //however, currently we can't do it based on the exception-control api (see DELTASPIKE-638) throw new SkipInternalProcessingException(accessDeniedException); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/authorization/DefaultAccessDecisionVoterContext.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.authorization; import org.apache.deltaspike.security.api.authorization.AccessDecisionState; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import jakarta.enterprise.context.RequestScoped; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * {@inheritDoc} */ @RequestScoped //TODO we might need a different scope for it public class DefaultAccessDecisionVoterContext implements EditableAccessDecisionVoterContext { private AccessDecisionState state = AccessDecisionState.INITIAL; private List securityViolations; private Map metaData = new HashMap(); private Object source; /** * {@inheritDoc} */ @Override public AccessDecisionState getState() { return state; } /** * {@inheritDoc} */ @Override public List getViolations() { if (securityViolations == null) { return Collections.emptyList(); } return Collections.unmodifiableList(securityViolations); } /** * {@inheritDoc} */ @Override public T getSource() { return (T) source; } /** * {@inheritDoc} */ @Override public void setSource(Object source) { this.source = source; } /** * {@inheritDoc} */ @Override public Map getMetaData() { return Collections.unmodifiableMap(metaData); } /** * {@inheritDoc} */ @Override public T getMetaDataFor(String key, Class targetType) { return (T) metaData.get(key); } /** * {@inheritDoc} */ @Override public void addMetaData(String key, Object metaData) { //TODO specify nested security calls this.metaData.put(key, metaData); } /** * {@inheritDoc} */ @Override public void setState(AccessDecisionState accessDecisionVoterState) { if (AccessDecisionState.VOTE_IN_PROGRESS.equals(accessDecisionVoterState)) { securityViolations = new ArrayList(); //lazy init } state = accessDecisionVoterState; if (AccessDecisionState.INITIAL.equals(accessDecisionVoterState) || AccessDecisionState.VOTE_IN_PROGRESS.equals(accessDecisionVoterState)) { return; } //meta-data is only needed until the end of a voting process metaData.clear(); } /** * {@inheritDoc} */ @Override public void addViolation(SecurityViolation securityViolation) { if (securityViolations == null) { throw new IllegalStateException( AccessDecisionState.VOTE_IN_PROGRESS.name() + " is required for adding security-violations"); } securityViolations.add(securityViolation); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/authorization/SecuredAnnotationAuthorizer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.authorization; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.security.api.authorization.AccessDecisionState; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.api.authorization.Secured; import org.apache.deltaspike.security.api.authorization.Secures; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import org.apache.deltaspike.security.impl.util.SecurityUtils; import org.apache.deltaspike.security.spi.authorization.EditableAccessDecisionVoterContext; import jakarta.enterprise.context.Dependent; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.*; /** * Authorizer implementation for the {@link @Secured} annotation */ @Dependent @SuppressWarnings("UnusedDeclaration") public class SecuredAnnotationAuthorizer { @Inject private AccessDecisionVoterContext voterContext; @Inject private AccessDeniedExceptionBroadcaster exceptionBroadcaster; @Secures @Secured({ }) @SuppressWarnings("UnusedDeclaration") public boolean doSecuredCheck(InvocationContext invocationContext) throws Exception { List> voterClasses = new ArrayList>(); List annotatedTypeMetadata = extractMetadata(invocationContext); for (Annotation annotation : annotatedTypeMetadata) { if (Secured.class.isAssignableFrom(annotation.annotationType())) { voterClasses.addAll(Arrays.asList(((Secured) annotation).value())); } else if (voterContext instanceof EditableAccessDecisionVoterContext) { ((EditableAccessDecisionVoterContext) voterContext) .addMetaData(annotation.annotationType().getName(), annotation); } } invokeVoters(invocationContext, voterClasses); //needed by @SecurityBindingType //X TODO check the use-cases for it return true; } protected List extractMetadata(InvocationContext invocationContext) { List result = new ArrayList(); Method method = invocationContext.getMethod(); // some very old EE6 containers have a bug in resolving the target // so we fall back on the declaringClass of the method. Class targetClass = invocationContext.getTarget() != null ? ProxyUtils.getUnproxiedClass(invocationContext.getTarget().getClass()) : method.getDeclaringClass(); result.addAll(SecurityUtils.getAllAnnotations(targetClass.getAnnotations(), new HashSet())); //later on method-level annotations need to overrule class-level annotations -> don't change the order result.addAll(SecurityUtils.getAllAnnotations(method.getAnnotations(), new HashSet())); return result; } /** * Helper for invoking the given {@link AccessDecisionVoter}s * * @param invocationContext current invocation-context (might be null in case of secured views) * @param accessDecisionVoters current access-decision-voters */ private void invokeVoters(InvocationContext invocationContext, List> accessDecisionVoters) { if (accessDecisionVoters.isEmpty()) { return; } AccessDecisionState voterState = AccessDecisionState.VOTE_IN_PROGRESS; try { if (voterContext instanceof EditableAccessDecisionVoterContext) { ((EditableAccessDecisionVoterContext) voterContext).setState(voterState); ((EditableAccessDecisionVoterContext) voterContext).setSource(invocationContext); } Set violations; AccessDecisionVoter voter; for (Class voterClass : accessDecisionVoters) { voter = BeanProvider.getContextualReference(voterClass, false); violations = voter.checkPermission(voterContext); if (violations != null && !violations.isEmpty()) { if (voterContext instanceof EditableAccessDecisionVoterContext) { voterState = AccessDecisionState.VIOLATION_FOUND; for (SecurityViolation securityViolation : violations) { ((EditableAccessDecisionVoterContext) voterContext).addViolation(securityViolation); } } this.exceptionBroadcaster.broadcastAccessDeniedException(new AccessDeniedException(violations)); } } } finally { if (voterContext instanceof EditableAccessDecisionVoterContext) { if (AccessDecisionState.VOTE_IN_PROGRESS.equals(voterState)) { voterState = AccessDecisionState.NO_VIOLATION_FOUND; } ((EditableAccessDecisionVoterContext) voterContext).setState(voterState); } } } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/authorization/SecurityParameterValueRedefiner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.authorization; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.interceptor.InvocationContext; import org.apache.deltaspike.core.util.metadata.builder.ParameterValueRedefiner; import org.apache.deltaspike.security.api.authorization.SecuredReturn; import org.apache.deltaspike.security.api.authorization.SecurityParameterBinding; /** * Responsible for supplying requested method invocation values to the security binding method. */ public class SecurityParameterValueRedefiner implements ParameterValueRedefiner { private final BeanManager beanManager; private CreationalContext creationalContext; private InvocationContext invocation; private Object result; public SecurityParameterValueRedefiner(BeanManager beanManager, CreationalContext creationalContext, InvocationContext invocation, Object result) { this.beanManager = beanManager; this.creationalContext = creationalContext; this.invocation = invocation; this.result = result; } @Override public Object redefineParameterValue(ParameterValue value) { InjectionPoint injectionPoint = value.getInjectionPoint(); if (injectionPoint != null) { if (value.getInjectionPoint().getAnnotated().getBaseType().equals(InvocationContext.class)) { return invocation; } else if (value.getInjectionPoint().getAnnotated().isAnnotationPresent(SecuredReturn.class)) { return result; } else { Annotated securingParameterAnnotatedType = injectionPoint.getAnnotated(); Set securingParameterAnnotations = securingParameterAnnotatedType.getAnnotations(); Set requiredBindingAnnotations = new HashSet(); for (Annotation annotation : securingParameterAnnotations) { if (annotation.annotationType().isAnnotationPresent(SecurityParameterBinding.class)) { requiredBindingAnnotations.add(annotation); } } if (!requiredBindingAnnotations.isEmpty()) { Method method = invocation.getMethod(); Annotation[][] businessMethodParameterAnnotations = method.getParameterAnnotations(); for (int i = 0; i < businessMethodParameterAnnotations.length; i++) { List businessParameterAnnotations = Arrays .asList(businessMethodParameterAnnotations[i]); for (Annotation annotation : requiredBindingAnnotations) { if (businessParameterAnnotations.contains(annotation)) { return invocation.getParameters()[i]; } } Set hashCodesOfBusinessParameterAnnotations = new HashSet(businessParameterAnnotations.size()); for (Annotation annotation : businessParameterAnnotations) { hashCodesOfBusinessParameterAnnotations.add(beanManager.getQualifierHashCode(annotation)); } //2nd try (detailed check) for (Annotation annotation : requiredBindingAnnotations) { if (hashCodesOfBusinessParameterAnnotations.contains(beanManager.getQualifierHashCode(annotation))) { return invocation.getParameters()[i]; } } } throw new IllegalStateException("Missing required security parameter binding " + requiredBindingAnnotations + " on method invocation [" + method.getDeclaringClass().getName() + "." + method.getName() + Arrays.asList(method.getParameterTypes()).toString().replaceFirst("\\[", "(") .replaceFirst("\\]$", ")") + "]"); } } } return value.getDefaultValue(creationalContext); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/authorization/SkipInternalProcessingException.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.authorization; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; //just to avoid a 2nd call of the handlers //the first one can't be removed, because we need an active AccessDecisionVoterContext public class SkipInternalProcessingException extends RuntimeException { private static final long serialVersionUID = 3585306529694592791L; private final AccessDeniedException accessDeniedException; public SkipInternalProcessingException(AccessDeniedException accessDeniedException) { this.accessDeniedException = accessDeniedException; } public AccessDeniedException getAccessDeniedException() { return accessDeniedException; } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/AuthorizationParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import java.util.Set; import jakarta.enterprise.util.Nonbinding; import org.apache.deltaspike.security.api.authorization.SecurityDefinitionException; class AuthorizationParameter { private Type type; private Map, Map> bindings; public AuthorizationParameter() { } AuthorizationParameter(Type type, Set bindings) { this.type = type; this.bindings = new HashMap, Map>(); for (Annotation bindingAnnotation : bindings) { Map bindingMembers = new HashMap(); try { for (Method method : bindingAnnotation.annotationType().getDeclaredMethods()) { if (method.isAnnotationPresent(Nonbinding.class)) { continue; } bindingMembers.put(method, method.invoke(bindingAnnotation)); } } catch (InvocationTargetException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } catch (IllegalAccessException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } this.bindings.put(bindingAnnotation.annotationType(), bindingMembers); } } /** * TODO comment is no equals!!! * * @param parameter * @return */ boolean matches(AuthorizationParameter parameter) { if (!type.equals(parameter.type)) { return false; } for (Map.Entry, Map> bindingEntry : bindings.entrySet()) { Map bindingValues = parameter.bindings.get(bindingEntry.getKey()); if (bindingValues == null) { // annotation is not present return false; } for (Map.Entry value : bindingEntry.getValue().entrySet()) { if (!bindingValues.get(value.getKey()).equals(value.getValue())) { return false; } } } return true; } public String toString() { StringBuilder builder = new StringBuilder(); for (Map.Entry, Map> bindingEntry : bindings.entrySet()) { builder.append('@').append(bindingEntry.getKey().getName()).append('('); for (Map.Entry value : bindingEntry.getValue().entrySet()) { builder.append(value.getKey().getName()).append('=').append(value.getValue()).append(','); } if (bindingEntry.getValue().isEmpty()) { builder.append(')'); } else { builder.setCharAt(builder.length() - 1, ')'); } } if (!bindings.isEmpty()) { builder.append(' '); } builder.append(type); return builder.toString(); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/Authorizer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.Stereotype; import jakarta.enterprise.inject.Vetoed; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.util.Nonbinding; import jakarta.interceptor.InvocationContext; import org.apache.deltaspike.core.util.metadata.builder.InjectableMethod; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.api.authorization.SecurityBindingType; import org.apache.deltaspike.security.api.authorization.SecurityDefinitionException; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import org.apache.deltaspike.security.api.authorization.SecuredReturn; import org.apache.deltaspike.security.impl.authorization.SecurityParameterValueRedefiner; import org.apache.deltaspike.security.impl.util.SecurityUtils; /** * Responsible for authorizing method invocations. */ @Vetoed class Authorizer { private Annotation bindingAnnotation; private Map bindingSecurityBindingMembers = new HashMap(); private Set authorizationParameters = new HashSet(); private Class securedReturnType; private volatile AnnotatedMethod boundAuthorizerMethod; private volatile Bean boundAuthorizerBean; private volatile InjectableMethod boundAuthorizerMethodProxy; Authorizer(Annotation bindingAnnotation, AnnotatedMethod boundAuthorizerMethod) { this.bindingAnnotation = bindingAnnotation; this.boundAuthorizerMethod = boundAuthorizerMethod; try { for (Method method : bindingAnnotation.annotationType().getDeclaredMethods()) { if (method.isAnnotationPresent(Nonbinding.class)) { continue; } bindingSecurityBindingMembers.put(method, method.invoke(bindingAnnotation)); } } catch (InvocationTargetException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } catch (IllegalAccessException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } for (AnnotatedParameter annotatedParameter : boundAuthorizerMethod.getParameters()) { Set securityParameterBindings = null; Class securedReturnType = null; for (Annotation annotation : annotatedParameter.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityParameterBinding(annotation)) { if (securityParameterBindings == null) { securityParameterBindings = new HashSet(); } securityParameterBindings.add(annotation); } if (annotation.annotationType().equals(SecuredReturn.class)) { securedReturnType = boundAuthorizerMethod.getJavaMember().getParameterTypes()[annotatedParameter.getPosition()]; } } if (securityParameterBindings != null && securedReturnType != null) { StringBuilder errorMessage = new StringBuilder(); errorMessage.append("@SecurityParameterBinding annotations must not occure "); errorMessage.append("at the same parameter with @Result annotation, but parameter "); errorMessage.append(annotatedParameter.getPosition()).append(" of method "); errorMessage.append(boundAuthorizerMethod.getJavaMember()).append(" is annotated with @Result and "); boolean first = true; for (Annotation securityParameterBinding : securityParameterBindings) { if (first) { first = false; } else { errorMessage.append(" and "); } errorMessage.append(securityParameterBinding); } if (securityParameterBindings.size() == 1) { errorMessage.append(", which is a @SecurityParameterBinding annotation"); } else { errorMessage.append(", which are @SecurityParameterBinding annotations"); } throw new SecurityDefinitionException(errorMessage.toString()); } else if (securityParameterBindings != null) { AuthorizationParameter authorizationParameter = new AuthorizationParameter(annotatedParameter.getBaseType(), securityParameterBindings); authorizationParameters.add(authorizationParameter); } else if (securedReturnType != null) { if (this.securedReturnType != null && !this.securedReturnType.equals(securedReturnType)) { throw new SecurityDefinitionException("More than one parameter of " + boundAuthorizerMethod.getJavaMember() + " is annotated with @Result"); } this.securedReturnType = securedReturnType; } } } boolean isBeforeMethodInvocationAuthorizer() { return securedReturnType == null; } boolean isAfterMethodInvocationAuthorizer() { return securedReturnType != null; } void authorize(final InvocationContext ic, final Object returnValue, BeanManager beanManager) throws IllegalAccessException, IllegalArgumentException { if (boundAuthorizerBean == null) { lazyInitTargetBean(beanManager); } final CreationalContext creationalContext = beanManager.createCreationalContext(boundAuthorizerBean); Object reference = beanManager.getReference(boundAuthorizerBean, boundAuthorizerMethod.getJavaMember().getDeclaringClass(), creationalContext); Object result = boundAuthorizerMethodProxy.invoke(reference, creationalContext, new SecurityParameterValueRedefiner(beanManager, creationalContext, ic, returnValue)); if (Boolean.FALSE.equals(result)) { Set violations = new HashSet(); violations.add(new SecurityViolation() { private static final long serialVersionUID = 2358753444038521129L; @Override public String getReason() { return "Authorization check failed"; } }); throw new AccessDeniedException(violations); } } @SuppressWarnings({ "unchecked" }) private synchronized void lazyInitTargetBean(BeanManager beanManager) { if (boundAuthorizerBean == null) { Method method = boundAuthorizerMethod.getJavaMember(); Set> beans = beanManager.getBeans(method.getDeclaringClass()); Bean foundBoundAuthorizerBean = beanManager.resolve(beans); if (foundBoundAuthorizerBean == null) { throw new IllegalStateException("Exception looking up authorizer method bean - " + "no beans found for method [" + method.getDeclaringClass() + "." + method.getName() + "]"); } boundAuthorizerMethodProxy = new InjectableMethod( boundAuthorizerMethod, foundBoundAuthorizerBean, beanManager); boundAuthorizerBean = foundBoundAuthorizerBean; } } boolean matchesBindings(Annotation annotation, Set parameterBindings, Class returnType) { if (!annotation.annotationType().isAnnotationPresent(SecurityBindingType.class) && annotation.annotationType().isAnnotationPresent(Stereotype.class)) { annotation = SecurityUtils.resolveSecurityBindingType(annotation); } if (!annotation.annotationType().equals(bindingAnnotation.annotationType())) { return false; } for (Method method : annotation.annotationType().getDeclaredMethods()) { if (method.isAnnotationPresent(Nonbinding.class)) { continue; } if (!bindingSecurityBindingMembers.containsKey(method)) { return false; } try { Object value = method.invoke(annotation); if (!bindingSecurityBindingMembers.get(method).equals(value)) { return false; } } catch (InvocationTargetException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } catch (IllegalAccessException ex) { throw new SecurityDefinitionException("Error reading security binding members", ex); } } for (AuthorizationParameter authorizationParameter : authorizationParameters) { boolean found = false; for (AuthorizationParameter parameterBinding : parameterBindings) { if (parameterBinding.matches(authorizationParameter)) { found = true; } } if (!found) { return false; } } if (!matches(returnType)) { return false; } return true; } private boolean matches(Class returnType) { if (securedReturnType == null) { return true; } if (securedReturnType.isAssignableFrom(returnType)) { return true; } if (securedReturnType.equals(Void.class) && returnType.equals(Void.TYPE)) { return true; } return false; } Method getBoundAuthorizerMethod() { return boundAuthorizerMethod.getJavaMember(); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/DefaultSecurityStrategy.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import org.apache.deltaspike.core.util.ProxyUtils; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.security.impl.authorization.SkipInternalProcessingException; import org.apache.deltaspike.security.spi.authorization.SecurityStrategy; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Inject; import jakarta.interceptor.InvocationContext; import java.lang.reflect.Method; import java.util.Set; /** * {@inheritDoc} */ @Dependent public class DefaultSecurityStrategy implements SecurityStrategy { private static final long serialVersionUID = 7992336651801599079L; @Inject private BeanManager beanManager; @Inject private SecurityExtension securityExtension; /** * {@inheritDoc} */ @Override public Object execute(InvocationContext invocationContext) throws Exception { Method method = invocationContext.getMethod(); SecurityMetaDataStorage metaDataStorage = securityExtension.getMetaDataStorage(); Class targetClass = ProxyUtils.getUnproxiedClass(invocationContext.getTarget().getClass()); //see DELTASPIKE-517 Set authorizers = metaDataStorage.getAuthorizers(targetClass, method); invokeBeforeMethodInvocationAuthorizers(invocationContext, authorizers); Object result = invocationContext.proceed(); invokeAfterMethodInvocationAuthorizers(invocationContext, authorizers, result); return result; } protected void invokeBeforeMethodInvocationAuthorizers( InvocationContext invocationContext, Set authorizers) throws IllegalAccessException { try { for (Authorizer authorizer : authorizers) { if (authorizer.isBeforeMethodInvocationAuthorizer()) { authorizer.authorize(invocationContext, null, this.beanManager); } } } catch (SkipInternalProcessingException e) { throw e.getAccessDeniedException(); } catch (AccessDeniedException e) { RuntimeException exceptionToThrow = handleAccessDeniedException(e); if (exceptionToThrow != null) { throw exceptionToThrow; } } } protected void invokeAfterMethodInvocationAuthorizers(InvocationContext invocationContext, Set authorizers, Object result) throws IllegalAccessException { try { for (Authorizer authorizer : authorizers) { if (authorizer.isAfterMethodInvocationAuthorizer()) { authorizer.authorize(invocationContext, result, this.beanManager); } } } catch (AccessDeniedException e) { RuntimeException exceptionToThrow = handleAccessDeniedException(e); if (exceptionToThrow != null) { throw exceptionToThrow; } } } /** * It also allows to change the default handling. * * @param originalException exception thrown by an authorizer * @return the original exception if the default behavior was changed and the exception is unhandled */ protected RuntimeException handleAccessDeniedException(AccessDeniedException originalException) { return originalException; } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/SecurityExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.security.api.authorization.Secures; import org.apache.deltaspike.security.api.authorization.SecurityDefinitionException; import org.apache.deltaspike.security.impl.util.SecurityUtils; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; import java.util.Set; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AfterBeanDiscovery; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedParameter; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.ProcessAnnotatedType; /** * Extension for processing typesafe security annotations */ public class SecurityExtension implements Extension, Deactivatable { private static final SecurityInterceptorBinding INTERCEPTOR_BINDING = new SecurityInterceptorBindingLiteral(); private SecurityMetaDataStorage securityMetaDataStorage; private Boolean isActivated = null; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); securityMetaDataStorage = new SecurityMetaDataStorage(); } //workaround for OWB public SecurityMetaDataStorage getMetaDataStorage() { return securityMetaDataStorage; } /** * Handles @Secured beans */ public void processAnnotatedType(@Observes ProcessAnnotatedType event) { if (!isActivated) { return; } AnnotatedType type = event.getAnnotatedType(); boolean isSecured = false; // Add the security interceptor to the class if the class is annotated // with a security binding type for (final Annotation annotation : type.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { event.configureAnnotatedType() .add(INTERCEPTOR_BINDING); getMetaDataStorage().addSecuredType(type); isSecured = true; break; } } // If the class isn't annotated with a security binding type, check if // any of its methods are, and if so, add the security interceptor to the // method if (!isSecured) { for (final AnnotatedMethod m : type.getMethods()) { if (m.isAnnotationPresent(Secures.class)) { registerAuthorizer(m); continue; } for (final Annotation annotation : m.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { event.configureAnnotatedType() .filterMethods(cm -> cm.getJavaMember().equals(m.getJavaMember())) .findFirst() .get() .add(INTERCEPTOR_BINDING); getMetaDataStorage().addSecuredMethod(m); break; } } } } } public void validateBindings(@Observes AfterBeanDiscovery event, BeanManager beanManager) { if (!isActivated) { return; } SecurityMetaDataStorage metaDataStorage = getMetaDataStorage(); metaDataStorage.registerSecuredMethods(); for (final AnnotatedMethod method : metaDataStorage.getSecuredMethods()) { // Here we simply want to validate that each method that is annotated with // one or more security bindings has a valid authorizer for each binding Class targetClass = method.getDeclaringType().getJavaClass(); Method targetMethod = method.getJavaMember(); for (final Annotation annotation : SecurityUtils.getSecurityBindingTypes(targetClass, targetMethod)) { boolean found = false; Set authorizationParameters = new HashSet(); for (AnnotatedParameter parameter : (List>) (List) method.getParameters()) { Set securityParameterBindings = null; for (Annotation a : parameter.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityParameterBinding(a)) { if (securityParameterBindings == null) { securityParameterBindings = new HashSet(); } securityParameterBindings.add(a); } } if (securityParameterBindings != null) { AuthorizationParameter authorizationParameter = new AuthorizationParameter(parameter.getBaseType(), securityParameterBindings); authorizationParameters.add(authorizationParameter); } } // Validate the authorizer for (Authorizer auth : metaDataStorage.getAuthorizers()) { if (auth.matchesBindings(annotation, authorizationParameters, targetMethod.getReturnType())) { found = true; break; } } if (!found) { event.addDefinitionError(new SecurityDefinitionException("Secured type " + method.getDeclaringType().getJavaClass().getName() + " has no matching authorizer method for security binding @" + annotation.annotationType().getName())); } } for (final Annotation annotation : method.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { metaDataStorage.registerSecuredMethod(targetClass, targetMethod); break; } } } // Clear securedTypes, we don't require it any more metaDataStorage.resetSecuredMethods(); } /** * Registers the specified authorizer method (i.e. a method annotated with * the @Secures annotation) * * @throws SecurityDefinitionException */ private void registerAuthorizer(AnnotatedMethod annotatedMethod) { if (!annotatedMethod.getJavaMember().getReturnType().equals(Boolean.class) && !annotatedMethod.getJavaMember().getReturnType().equals(Boolean.TYPE)) { throw new SecurityDefinitionException("Invalid authorizer method [" + annotatedMethod.getJavaMember().getDeclaringClass().getName() + "." + annotatedMethod.getJavaMember().getName() + "] - does not return a boolean."); } // Locate the binding type Annotation binding = null; for (Annotation annotation : annotatedMethod.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { if (binding != null) { throw new SecurityDefinitionException("Invalid authorizer method [" + annotatedMethod.getJavaMember().getDeclaringClass().getName() + "." + annotatedMethod.getJavaMember().getName() + "] - declares multiple security binding types"); } binding = annotation; } } Authorizer authorizer = new Authorizer(binding, annotatedMethod); getMetaDataStorage().addAuthorizer(authorizer); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/SecurityInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import jakarta.annotation.Priority; import org.apache.deltaspike.security.spi.authorization.SecurityStrategy; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; /** * Interceptor for {@link SecurityInterceptorBinding} - details see {@link SecurityStrategy} */ @SecurityInterceptorBinding @Interceptor @Priority(1000) public class SecurityInterceptor implements Serializable { private static final long serialVersionUID = -7094673146532371976L; @Inject private SecurityStrategy securityStrategy; @AroundInvoke public Object filterDeniedInvocations(InvocationContext invocationContext) throws Exception { return securityStrategy.execute(invocationContext); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/SecurityInterceptorBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Interceptor binding type for SecurityInterceptor. Users should not apply * this binding themselves, it is applied by the security portable extension. */ @Retention(RetentionPolicy.RUNTIME) @InterceptorBinding @Target({ElementType.TYPE, ElementType.METHOD }) @interface SecurityInterceptorBinding { } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/SecurityInterceptorBindingLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import jakarta.enterprise.util.AnnotationLiteral; /** * Annotation literal for SecurityInterceptorBinding */ class SecurityInterceptorBindingLiteral extends AnnotationLiteral implements SecurityInterceptorBinding { private static final long serialVersionUID = 2189092542638784524L; } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/extension/SecurityMetaDataStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.extension; import org.apache.deltaspike.security.api.authorization.SecurityDefinitionException; import org.apache.deltaspike.security.impl.util.SecurityUtils; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; class SecurityMetaDataStorage { /** * Contains all known authorizers */ private Set authorizers = new HashSet(); /** * Contains all known secured methods. */ private Set> securedMethods = new HashSet>(); /** * A mapping between a secured method of a class and its authorizers */ private Map, Map>> methodAuthorizers = new HashMap, Map>>(); void addAuthorizer(Authorizer authorizer) { authorizers.add(authorizer); } void addSecuredType(AnnotatedType annotatedType) { for (AnnotatedMethod securedMethod : annotatedType.getMethods()) { addSecuredMethod(securedMethod); } } void addSecuredMethod(AnnotatedMethod annotatedMethod) { securedMethods.add(annotatedMethod); } Set> getSecuredMethods() { return securedMethods; } void resetSecuredMethods() { securedMethods = null; } /** * This method is invoked by the security interceptor to obtain the * authorizer stack for a secured method */ Set getAuthorizers(Class targetClass, Method targetMethod) { if (!isMethodMetaDataAvailable(targetClass, targetMethod)) { registerSecuredMethod(targetClass, targetMethod); } return getMethodAuthorizers(targetClass, targetMethod); } void registerSecuredMethods() { for (AnnotatedMethod method : securedMethods) { registerSecuredMethod(method.getDeclaringType().getJavaClass(), method.getJavaMember()); } } synchronized void registerSecuredMethod(Class targetClass, Method targetMethod) { ensureInitializedAuthorizersForClass(targetClass); if (!containsMethodAuthorizers(targetClass, targetMethod)) { Set parameterBindings = new HashSet(); Class[] parameterTypes = targetMethod.getParameterTypes(); Annotation[][] parameterAnnotations = targetMethod.getParameterAnnotations(); for (int i = 0; i < parameterTypes.length; i++) { Set securityBindings = null; for (final Annotation parameterAnnotation : parameterAnnotations[i]) { if (SecurityUtils.isMetaAnnotatedWithSecurityParameterBinding(parameterAnnotation)) { if (securityBindings == null) { securityBindings = new HashSet(); } securityBindings.add(parameterAnnotation); } } if (securityBindings != null) { parameterBindings.add(new AuthorizationParameter(parameterTypes[i], securityBindings)); } } Set authorizerStack = new HashSet(); for (Annotation binding : SecurityUtils.getSecurityBindingTypes(targetClass, targetMethod)) { boolean found = false; // For each security binding, find a valid authorizer for (Authorizer authorizer : authorizers) { if (authorizer.matchesBindings(binding, parameterBindings, targetMethod.getReturnType())) { if (found) { StringBuilder sb = new StringBuilder(); sb.append("Matching authorizer methods found: ["); sb.append(authorizer.getBoundAuthorizerMethod().getDeclaringClass().getName()); sb.append("."); sb.append(authorizer.getBoundAuthorizerMethod().getName()); sb.append("]"); for (Authorizer a : authorizerStack) { if (a.matchesBindings(binding, parameterBindings, targetMethod.getReturnType())) { sb.append(", ["); sb.append(a.getBoundAuthorizerMethod().getDeclaringClass().getName()); sb.append("."); sb.append(a.getBoundAuthorizerMethod().getName()); sb.append("]"); } } throw new SecurityDefinitionException( "Ambiguous authorizers found for security binding type [@" + binding.annotationType().getName() + "] on method [" + targetMethod.getDeclaringClass().getName() + "." + targetMethod.getName() + "]. " + sb.toString()); } authorizerStack.add(authorizer); found = true; } } if (!found) { throw new SecurityDefinitionException( "No matching authorizer found for security binding type [@" + binding.annotationType().getName() + "] on method [" + targetMethod.getDeclaringClass().getName() + "." + targetMethod.getName() + "]."); } } addMethodAuthorizer(targetClass, targetMethod, authorizerStack); } } Set getAuthorizers() { return authorizers; } private boolean containsMethodAuthorizers(Class targetClass, Method targetMethod) { Map> resultForClass = methodAuthorizers.get(targetClass); return resultForClass.containsKey(targetMethod); } private void ensureInitializedAuthorizersForClass(Class targetClass) { Map> resultForClass = methodAuthorizers.get(targetClass); if (resultForClass == null) { methodAuthorizers.put(targetClass, new HashMap>()); } } private boolean isMethodMetaDataAvailable(Class targetClass, Method targetMethod) { Map> result = methodAuthorizers.get(targetClass); return result != null && result.containsKey(targetMethod); } private void addMethodAuthorizer(Class targetClass, Method targetMethod, Set authorizersToAdd) { Map> authorizerMapping = methodAuthorizers.get(targetClass); if (authorizerMapping == null) { authorizerMapping = new HashMap>(); methodAuthorizers.put(targetClass, authorizerMapping); } Set authorizersForMethod = authorizerMapping.get(targetMethod); if (authorizersForMethod == null) { authorizersForMethod = new HashSet(); authorizerMapping.put(targetMethod, authorizersForMethod); } authorizersForMethod.addAll(authorizersToAdd); } private Set getMethodAuthorizers(Class targetClass, Method targetMethod) { Map> resultForClass = methodAuthorizers.get(targetClass); if (resultForClass == null) { throw new IllegalStateException( "no meta-data available for: " + targetClass.getName() + targetMethod.getName()); } return resultForClass.get(targetMethod); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/java/org/apache/deltaspike/security/impl/util/SecurityUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.security.impl.util; import org.apache.deltaspike.core.util.ReflectionUtils; import org.apache.deltaspike.security.api.authorization.SecurityBindingType; import org.apache.deltaspike.security.api.authorization.SecurityParameterBinding; import jakarta.enterprise.inject.Stereotype; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @Vetoed public abstract class SecurityUtils { private SecurityUtils() { // prevent instantiation } public static Set getSecurityBindingTypes(Class targetClass, Method targetMethod) { Set securityBindingTypes = new HashSet(); Class cls = targetClass; while (cls != null && !cls.equals(Object.class)) { for (final Annotation annotation : cls.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { securityBindingTypes.add(annotation); } } cls = cls.getSuperclass(); } for (final Annotation annotation : targetMethod.getAnnotations()) { if (SecurityUtils.isMetaAnnotatedWithSecurityBindingType(annotation)) { securityBindingTypes.add(annotation); } } return securityBindingTypes; } public static boolean isMetaAnnotatedWithSecurityBindingType(Annotation annotation) { if (annotation.annotationType().isAnnotationPresent(SecurityBindingType.class)) { return true; } List result = getAllAnnotations(annotation.annotationType().getAnnotations(), new HashSet()); for (Annotation foundAnnotation : result) { if (SecurityBindingType.class.isAssignableFrom(foundAnnotation.annotationType())) { return true; } } return false; } public static Annotation resolveSecurityBindingType(Annotation annotation) { List result = getAllAnnotations(annotation.annotationType().getAnnotations(), new HashSet()); for (Annotation foundAnnotation : result) { if (foundAnnotation.annotationType().isAnnotationPresent(SecurityBindingType.class)) { return foundAnnotation; } } throw new IllegalStateException(annotation.annotationType().getName() + " is a " + Stereotype.class.getName() + " but it isn't annotated with " + SecurityBindingType.class.getName()); } public static boolean isMetaAnnotatedWithSecurityParameterBinding(Annotation annotation) { if (annotation.annotationType().isAnnotationPresent(SecurityParameterBinding.class)) { return true; } List result = getAllAnnotations(annotation.annotationType().getAnnotations(), new HashSet()); for (Annotation foundAnnotation : result) { if (SecurityParameterBinding.class.isAssignableFrom(foundAnnotation.annotationType())) { return true; } } return false; } public static List getAllAnnotations(Annotation[] annotations, Set annotationPath) { List result = new ArrayList(); String annotationName; for (Annotation annotation : annotations) { annotationName = annotation.annotationType().getName(); if (annotationName.startsWith("java.") || annotationName.startsWith("javax.") || annotationName.startsWith("jakarta.")) { continue; } int annotationHashCode = hashCodeOfAnnotation(annotation); if (!annotationPath.contains(annotationHashCode)) { result.add(annotation); annotationPath.add(annotationHashCode); result.addAll(getAllAnnotations(annotation.annotationType().getAnnotations(), annotationPath)); } } return result; } private static int hashCodeOfAnnotation(Annotation annotation) { //with using System#identityHashCode instead, we could detect the real instances //-> that would lead to multiple entries in the result which look the same (same type and members) //to detect real cycles, nonbinding members aren't ignored here return ReflectionUtils.calculateHashCodeOfAnnotation(annotation, false); } } ================================================ FILE: deltaspike/modules/security/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/security/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.security.impl.extension.SecurityExtension ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/CustomAuthorizer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; import org.apache.deltaspike.security.api.authorization.Secures; import jakarta.enterprise.context.ApplicationScoped; import jakarta.interceptor.InvocationContext; @ApplicationScoped public class CustomAuthorizer { @Secures @CustomSecurityBinding public boolean doSecuredCheck(@ParamBindingWithNonbindingMember(info = "test") ParameterValue obj, InvocationContext invocationContext) throws Exception { if (invocationContext == null) { throw new IllegalArgumentException("no invocation-context found"); } return obj.isValue(); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/CustomSecurityBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; import org.apache.deltaspike.security.api.authorization.SecurityBindingType; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ TYPE, METHOD }) @Documented @SecurityBindingType public @interface CustomSecurityBinding { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/ParamBindingWithNonbindingMember.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; import org.apache.deltaspike.security.api.authorization.SecurityParameterBinding; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ PARAMETER }) @Documented @SecurityParameterBinding public @interface ParamBindingWithNonbindingMember { @Nonbinding String info(); } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/ParameterValue.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; public class ParameterValue { private boolean value; public ParameterValue(boolean value) { this.value = value; } public boolean isValue() { return value; } public void setValue(boolean value) { this.value = value; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/SecuredBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; import jakarta.enterprise.context.ApplicationScoped; @CustomSecurityBinding @ApplicationScoped public class SecuredBean { public boolean getResult(@ParamBindingWithNonbindingMember(info = "test") ParameterValue parameterValue) { return parameterValue.isValue(); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/nonbinding/SecurityParameterWithNonbindingMemberTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.nonbinding; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ @RunWith(Arquillian.class) public class SecurityParameterWithNonbindingMemberTest { @Deployment public static WebArchive deploy() { String simpleName = SecurityParameterWithNonbindingMemberTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSecurityArchive()) .addPackage(SecurityParameterWithNonbindingMemberTest.class.getPackage()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Test //don't use expected = AccessDeniedException.class //(reason: with some adapters it would lead to an ArquillianProxyException) public void securityParameterWithNonbindingMember() { SecuredBean testBean = BeanProvider.getContextualReference(SecuredBean.class, false); try { testBean.getResult(new ParameterValue(false)); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { //expected exception } catch (Exception e) { Assert.fail("Unexpected Exception: " + e); } } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredAnnotationEarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.EnterpriseArchive; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ @RunWith(Arquillian.class) @Category(EnterpriseArchiveProfileCategory.class) public class SecuredAnnotationEarFileTest extends SecuredAnnotationTest { public static final String CONFIG = "deltaspike.bean-manager.delegate_lookup=false\n"; // Weld3 bug :( @Deployment public static EnterpriseArchive deployEar() { //workaround for tomee - the ear-file needs to have the same name as the war-file String simpleName = SecuredAnnotationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); JavaArchive configJar = ShrinkWrap.create(JavaArchive.class, "dsConfig.jar") .addAsManifestResource(new StringAsset(CONFIG), "apache-deltaspike.properties"); return ShrinkWrap.create(EnterpriseArchive.class, archiveName + ".ear") .addAsLibrary(configJar) .addAsModule(SecuredAnnotationWarFileTest.deploy()); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredAnnotationTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.junit.Assert; import org.junit.Test; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ public abstract class SecuredAnnotationTest { @Test public void simpleInterceptorTestOk() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertEquals("result", testBean.getResult()); } @Test public void simpleInterceptorTestParentOk() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertEquals("allfine", testBean.someFineMethodFromParent()); } @Test(expected = AccessDeniedException.class) public void simpleInterceptorTestDenied() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); testBean.getBlockedResult(); } @Test(expected = AccessDeniedException.class) public void simpleInterceptorTestParentDenied() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); testBean.someBlockedMethodFromParent(); } @Test public void interceptorTestWithStereotypeOk() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); Assert.assertEquals("result", testBean.getResult()); } @Test public void interceptorTestWithStereotypeParentOk() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); Assert.assertEquals("allfine", testBean.someFineMethodFromParent()); } @Test(expected = AccessDeniedException.class) public void interceptorTestWithStereotypeDenied() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); testBean.getBlockedResult(); } @Test(expected = AccessDeniedException.class) public void interceptorTestWithStereotypeParentDenied() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); testBean.someBlockedMethodFromParent(); } @Test public void interceptorTestWithStereotypeWithValue() { SecuredBean5 testBean = BeanProvider.getContextualReference(SecuredBean5.class, false); Assert.assertEquals("result", testBean.getResult()); try { testBean.getBlockedResult(); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { //expected exception } catch (Exception e) { Assert.fail("Unexpected Exception: " + e); } } @Test public void simpleInterceptorTestOnMethods() { SecuredBean3 testBean = BeanProvider.getContextualReference(SecuredBean3.class, false); Assert.assertEquals("result", testBean.getResult()); try { testBean.getBlockedResult(); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { //expected exception } catch (Exception e) { Assert.fail("Unexpected Exception: " + e); } } @Test public void invocationOfMultipleSecuredStereotypes() { SecuredBean4 testBean = BeanProvider.getContextualReference(SecuredBean4.class, false); TestAccessDecisionVoter1 voter1 = BeanProvider.getContextualReference(TestAccessDecisionVoter1.class, false); TestAccessDecisionVoter2 voter2 = BeanProvider.getContextualReference(TestAccessDecisionVoter2.class, false); Assert.assertFalse(voter1.isCalled()); Assert.assertFalse(voter2.isCalled()); Assert.assertEquals("result", testBean.getResult()); Assert.assertTrue(voter1.isCalled()); Assert.assertTrue(voter2.isCalled()); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredAnnotationWarFileTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.runner.RunWith; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ @RunWith(Arquillian.class) public class SecuredAnnotationWarFileTest extends SecuredAnnotationTest { @Deployment public static WebArchive deploy() { String simpleName = SecuredAnnotationWarFileTest.class.getSimpleName(); String archiveName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1); return ShrinkWrap.create(WebArchive.class, archiveName + ".war") .addPackage(SecuredAnnotationWarFileTest.class.getPackage()) .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSecurityArchive()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBean1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @Secured(TestAccessDecisionVoter.class) public class SecuredBean1 extends SomeParentClass { public String getBlockedResult() { return "blocked result"; } public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @SecuredBeanWithStereotype public class SecuredBean2 extends SomeParentClass { public String getBlockedResult() { return "blocked result"; } public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBean3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class SecuredBean3 { @Secured(TestAccessDecisionVoter.class) public String getBlockedResult() { return "blocked result"; } @Secured(TestAccessDecisionVoter.class) public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBean4.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @SecuredBeanWithStereotype1 @SecuredBeanWithStereotype2 public class SecuredBean4 { public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBean5.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @SecuredBeanWithStereotype3("test") public class SecuredBean5 { public String getBlockedResult() { return "blocked result"; } public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBeanWithStereotype.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Stereotype @Retention(value = RUNTIME) @Target({TYPE, METHOD } ) @Secured(TestAccessDecisionVoter.class) public @interface SecuredBeanWithStereotype { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBeanWithStereotype1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Stereotype @Retention(value = RUNTIME) @Target({TYPE, METHOD } ) @Secured(TestAccessDecisionVoter1.class) public @interface SecuredBeanWithStereotype1 { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBeanWithStereotype2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Stereotype @Retention(value = RUNTIME) @Target({TYPE, METHOD } ) @Secured(TestAccessDecisionVoter2.class) public @interface SecuredBeanWithStereotype2 { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SecuredBeanWithStereotype3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.Secured; import jakarta.enterprise.inject.Stereotype; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Stereotype @Retention(value = RUNTIME) @Target({TYPE, METHOD } ) @Secured(TestAccessDecisionVoter.class) public @interface SecuredBeanWithStereotype3 { String value(); } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/SomeParentClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; /** * To verify if the permission annotation also works on the methods * of the parent class */ public class SomeParentClass { public String someFineMethodFromParent() { return "allfine"; } public String someBlockedMethodFromParent() { return "shouldgetblocked"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/TestAccessDecisionVoter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import jakarta.enterprise.context.ApplicationScoped; import jakarta.interceptor.InvocationContext; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * */ @ApplicationScoped public class TestAccessDecisionVoter implements AccessDecisionVoter { private static final long serialVersionUID = 1331427301357439804L; @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { Method method = accessDecisionVoterContext.getSource().getMethod(); if (!method.getName().contains("Blocked")) { return Collections.emptySet(); } return new HashSet() { private static final long serialVersionUID = 9033579102593906350L; { add(new SecurityViolation() { private static final long serialVersionUID = -7990980050100180829L; @Override public String getReason() { return "blocked"; } }); } }; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/TestAccessDecisionVoter1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import jakarta.enterprise.context.RequestScoped; import java.util.Collections; import java.util.Set; @RequestScoped public class TestAccessDecisionVoter1 implements AccessDecisionVoter { private static final long serialVersionUID = 1331427301357439805L; private boolean called; @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { this.called = true; return Collections.emptySet(); } public boolean isCalled() { return called; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/secured/TestAccessDecisionVoter2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.secured; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoter; import org.apache.deltaspike.security.api.authorization.AccessDecisionVoterContext; import org.apache.deltaspike.security.api.authorization.SecurityViolation; import jakarta.enterprise.context.RequestScoped; import java.util.Collections; import java.util.Set; @RequestScoped public class TestAccessDecisionVoter2 implements AccessDecisionVoter { private static final long serialVersionUID = 1331427301357439806L; private boolean called; @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { this.called = true; return Collections.emptySet(); } public boolean isCalled() { return called; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/CustomAuthorizer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; import org.apache.deltaspike.security.api.authorization.Secures; import jakarta.enterprise.context.ApplicationScoped; import jakarta.interceptor.InvocationContext; @ApplicationScoped @SuppressWarnings("UnusedDeclaration") public class CustomAuthorizer { @Secures @CustomSecurityBinding @SuppressWarnings("UnusedDeclaration") public boolean doSecuredCheck(InvocationContext invocationContext) throws Exception { return !invocationContext.getMethod().getName().contains("Blocked"); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/CustomSecurityBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; import org.apache.deltaspike.security.api.authorization.SecurityBindingType; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ TYPE, METHOD }) @Documented //cdi annotations @SecurityBindingType public @interface CustomSecurityBinding { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/SecuredBean1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; import jakarta.enterprise.context.ApplicationScoped; @CustomSecurityBinding @ApplicationScoped public class SecuredBean1 extends SomeParentClass { public String getBlockedResult() { return "blocked result"; } public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/SecuredBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class SecuredBean2 { @CustomSecurityBinding public String getBlockedResult() { return "blocked result"; } @CustomSecurityBinding public String getResult() { return "result"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/SecurityBindingTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ @RunWith(Arquillian.class) public class SecurityBindingTest { @Deployment public static WebArchive deploy() { return ShrinkWrap.create(WebArchive.class, "security-binding-test.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSecurityArchive()) .addPackage(SecurityBindingTest.class.getPackage()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Test public void simpleInterceptorTestOk() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertEquals("result", testBean.getResult()); } @Test public void simpleInterceptorTestParentOk() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertEquals("allfine", testBean.someFineMethodFromParent()); } @Test public void simpleInterceptorTestDenied() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); try { testBean.getBlockedResult(); Assert.fail(); } catch (AccessDeniedException e) { //expected } } @Test public void simpleInterceptorTestParentDenied() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); try { testBean.someBlockedMethodFromParent(); Assert.fail(); } catch (AccessDeniedException e) { //expected } } @Test public void simpleInterceptorTestOnMethodsOk() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); Assert.assertEquals("result", testBean.getResult()); } @Test public void simpleInterceptorTestOnMethodsDenied() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); try { testBean.getBlockedResult(); } catch (AccessDeniedException e) { //expected } } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securitybinding/SomeParentClass.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securitybinding; /** * To verify if the permission annotation also works on the methods * of the parent class */ public class SomeParentClass { public String someFineMethodFromParent() { return "allfine"; } public String someBlockedMethodFromParent() { return "shouldgetblocked"; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/CustomAuthorizer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import org.apache.deltaspike.security.api.authorization.SecuredReturn; import org.apache.deltaspike.security.api.authorization.Secures; import jakarta.enterprise.context.ApplicationScoped; import jakarta.interceptor.InvocationContext; @ApplicationScoped public class CustomAuthorizer { @Secures @CustomSecurityBinding public boolean doSecuredCheck(@MockParamBinding MockObject obj, InvocationContext invocationContext) throws Exception { return obj.isValue(); } @Secures @CustomSecurityBinding public boolean doSecuredCheck(@MockParamBinding MockObject2 obj) { return obj.isValue(); } @Secures @CustomSecurityBinding public boolean doSecuredCheckAfterMethodInvocation(@SecuredReturn MockObject obj) { return obj.isValue(); } @Secures @CustomSecurityBinding public boolean doSecuredCheckAfterMethodInvocationWithVoidMethod(@SecuredReturn Void result) { return false; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/CustomSecurityBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import org.apache.deltaspike.security.api.authorization.SecurityBindingType; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ TYPE, METHOD }) @Documented //cdi annotations @SecurityBindingType public @interface CustomSecurityBinding { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/MethodInvocationParameter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; public class MethodInvocationParameter { private boolean methodInvoked; public boolean isMethodInvoked() { return methodInvoked; } public void setMethodInvoked(boolean value) { this.methodInvoked = value; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/MockObject.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; public class MockObject { private boolean value; public MockObject(boolean value) { this.value = value; } public boolean isValue() { return value; } public void setValue(boolean value) { this.value = value; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/MockObject2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; public class MockObject2 { private boolean value; public MockObject2(boolean value) { this.value = value; } public boolean isValue() { return value; } public void setValue(boolean value) { this.value = value; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/MockParamBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import org.apache.deltaspike.security.api.authorization.SecurityParameterBinding; @Retention(value = RUNTIME) @Target({ PARAMETER }) @Documented // CDI Annotation under test @SecurityParameterBinding public @interface MockParamBinding { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/SecuredBean1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import jakarta.enterprise.context.ApplicationScoped; @CustomSecurityBinding @ApplicationScoped public class SecuredBean1 { public boolean getResult(@MockParamBinding MockObject mockObject) { return mockObject.isValue(); } public boolean getResult(@MockParamBinding MockObject2 mockObject) { return mockObject.isValue(); } public MockObject getResult(boolean value) { return new MockObject(value); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/SecuredBean2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class SecuredBean2 { @CustomSecurityBinding public boolean getBlockedResult(@MockParamBinding MockObject mockObject) { return mockObject.isValue(); } public boolean getResult(MockObject mockObject) { return mockObject.isValue(); } @CustomSecurityBinding public void securityCheckAfterMethodInvocation(MethodInvocationParameter parameter) { parameter.setMethodInvoked(true); } @CustomSecurityBinding public Void securityCheckAfterMethodInvocationWithVoidResult(MethodInvocationParameter parameter) { parameter.setMethodInvoked(true); return null; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/securityparameterbinding/SecurityParameterBindingTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.securityparameterbinding; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.security.api.authorization.AccessDeniedException; import org.apache.deltaspike.test.util.ArchiveUtils; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; /** * Test for {@link org.apache.deltaspike.security.api.authorization.Secured} */ @RunWith(Arquillian.class) public class SecurityParameterBindingTest { @Deployment public static WebArchive deploy() { return ShrinkWrap.create(WebArchive.class, "security-parameter-binding-test.war") .addAsLibraries(ArchiveUtils.getDeltaSpikeCoreAndSecurityArchive()) .addPackage(SecurityParameterBindingTest.class.getPackage()) .addAsWebInfResource(ArchiveUtils.getBeansXml(), "beans.xml"); } @Test public void simpleInterceptorThrowsExceptionWhenImproperlyAnnotated() { try { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); testBean.getResult(new MockObject2(false)); Assert.fail("Expected exception, IllegalStateException was not thrown"); } catch (AccessDeniedException e) { // expected exception } } @Test public void simpleInterceptorDeniesTest() { try { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); testBean.getResult(new MockObject(false)); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { // expected } catch (Exception e) { Assert.fail("Unexpected Exception: " + e); } } @Test public void simpleInterceptorAllowsTest() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertTrue(testBean.getResult(new MockObject(true))); } @Test public void simpleInterceptorIgnoresUnsecuredMethods() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); Assert.assertTrue(testBean.getResult(new MockObject(true))); } @Test public void simpleInterceptorTestOnMethodsDenies() { try { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); testBean.getBlockedResult(new MockObject(false)); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { // expected } catch (Exception e) { Assert.fail("Unexpected Exception: " + e); } } @Test public void simpleInterceptorTestOnMethodsAllows() { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); Assert.assertTrue(testBean.getBlockedResult(new MockObject(true))); } @Test public void afterInvocationAuthorizerCheckWithAllowedResult() { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); Assert.assertTrue(testBean.getResult(true).isValue()); } @Test public void afterInvocationAuthorizerCheckWithDeniedResult() { try { SecuredBean1 testBean = BeanProvider.getContextualReference(SecuredBean1.class, false); testBean.getResult(false); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { // expected } } @Test public void afterInvocationAuthorizerWithoutReturnType() { MethodInvocationParameter parameter = new MethodInvocationParameter(); try { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); testBean.securityCheckAfterMethodInvocation(parameter); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { Assert.assertTrue(parameter.isMethodInvoked()); } } @Test public void afterInvocationAuthorizerWithVoidReturnType() { MethodInvocationParameter parameter = new MethodInvocationParameter(); try { SecuredBean2 testBean = BeanProvider.getContextualReference(SecuredBean2.class, false); testBean.securityCheckAfterMethodInvocationWithVoidResult(parameter); Assert.fail("AccessDeniedException expect, but was not thrown"); } catch (AccessDeniedException e) { Assert.assertTrue(parameter.isMethodInvoked()); } } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/Annotation1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({TYPE, ANNOTATION_TYPE } ) @Annotation1("1") public @interface Annotation1 { String value(); } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/Annotation2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({TYPE, ANNOTATION_TYPE } ) @Annotation1("2") public @interface Annotation2 { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/Annotation3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({TYPE, ANNOTATION_TYPE } ) @Annotation1("3") @Annotation2 public @interface Annotation3 { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/AnnotationA.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({TYPE, ANNOTATION_TYPE } ) @AnnotationC public @interface AnnotationA { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/AnnotationB.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ANNOTATION_TYPE } ) @AnnotationA public @interface AnnotationB { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/AnnotationC.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({ANNOTATION_TYPE } ) @AnnotationB public @interface AnnotationC { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/AnnotationX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(value = RUNTIME) @Target({TYPE, ANNOTATION_TYPE } ) @AnnotationX public @interface AnnotationX { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/DirectCycle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; @AnnotationX public class DirectCycle { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/IndirectCycle.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; @AnnotationA public class IndirectCycle { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/IndirectCycleWithAnnotationMemberValues.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; @Annotation1("usage") @Annotation2 @Annotation3 public class IndirectCycleWithAnnotationMemberValues { } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/security/impl/authorization/util/SecurityUtilsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.security.impl.authorization.util; import org.apache.deltaspike.security.impl.util.SecurityUtils; import org.junit.Assert; import org.junit.Test; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.List; public class SecurityUtilsTest { @Test public void directCycleDetection() { List result = SecurityUtils.getAllAnnotations( DirectCycle.class.getAnnotations(), new HashSet()); Assert.assertNotNull(result); Assert.assertEquals(1, result.size()); } @Test public void indirectCycleDetection() { List result = SecurityUtils.getAllAnnotations( IndirectCycle.class.getAnnotations(), new HashSet()); Assert.assertNotNull(result); Assert.assertEquals(3, result.size()); } @Test public void indirectCycleDetection6() { List result = SecurityUtils.getAllAnnotations( IndirectCycleWithAnnotationMemberValues.class.getAnnotations(), new HashSet()); Assert.assertNotNull(result); Assert.assertEquals(6, result.size()); } } ================================================ FILE: deltaspike/modules/security/impl/src/test/java/org/apache/deltaspike/test/util/ArchiveUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.util; import org.apache.deltaspike.test.utils.ShrinkWrapArchiveUtil; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; /** * This class contains helpers for building frequently used archives */ public class ArchiveUtils { private ArchiveUtils() { // private ct } public static JavaArchive[] getDeltaSpikeCoreAndSecurityArchive() { String[] excludedFiles; excludedFiles = new String[]{"META-INF.apache-deltaspike.properties"}; return ShrinkWrapArchiveUtil.getArchives(null, "META-INF/beans.xml", new String[]{"org.apache.deltaspike.core", "org.apache.deltaspike.test.category", "org.apache.deltaspike.security"}, excludedFiles, "ds-core_and_security"); } public static Asset getBeansXml() { Asset beansXml = new StringAsset( "" + "" + "org.apache.deltaspike.security.impl.extension.SecurityInterceptor" + "" + "" ); return beansXml; } } ================================================ FILE: deltaspike/modules/security/impl/src/test/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/security/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules security-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Security-Module api impl ================================================ FILE: deltaspike/modules/test-control/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules test-control-module-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.modules deltaspike-test-control-module-api jar Apache DeltaSpike Test-Control-Module API org.apache.deltaspike.testcontrol.* jakarta.enterprise.inject, !org.apache.deltaspike.testcontrol.*, * org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided junit junit provided ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/TestControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Optional control annotation for unit-tests */ @Target({ TYPE, METHOD }) @Retention(RUNTIME) public @interface TestControl { /** * only supports contexts supported by ContextControl#startContext * defaults: session- and request-scope */ Class[] startScopes() default { }; //TODO discuss callbacks Class projectStage() default ProjectStage.UnitTest.class; /** * only supported on test-class-level */ Class logHandler() default ConsoleHandler.class; /** * Requires additional service-loader config * Currently only supported on class-level */ boolean startExternalContainers() default true; /** * allows to label alternative cdi-beans similar to global alternatives to bind them to 0-n tests */ Class activeAlternativeLabel() default Label.class; //with cdi 1.1+ it can be used to implement labeled-alternatives without text based config //(details see DELTASPIKE-1338) /** * low-level filter (mainly needed for special cases if labeled-alternatives aren't enough) * @return the class-filter class which should be used for the current test-class */ Class classFilter() default ClassFilter.class; interface Label { } } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/junit/CdiTestRunner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.junit; import junit.framework.Assert; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.api.provider.BeanManagerProvider; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.literal.TestControlLiteral; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.deltaspike.testcontrol.spi.TestAware; import org.apache.deltaspike.testcontrol.spi.TestControlValidator; import org.apache.deltaspike.testcontrol.spi.junit.TestStatementDecoratorFactory; import org.junit.Test; import org.junit.internal.runners.statements.FailOnTimeout; import org.junit.runner.notification.RunNotifier; import org.junit.runners.BlockJUnit4ClassRunner; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.Bean; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.inject.Singleton; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; import java.util.Stack; import java.util.concurrent.CopyOnWriteArraySet; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import static java.lang.Boolean.TRUE; /** * A JUnit test runner to start up with a CDI or embedded JavaEE container. * *

If the underlying container supports it you can even pass in a property file * to the bootstrap. You can configure the name of the configuration file via a * {@link org.apache.deltaspike.core.api.config.ConfigResolver} property named * cdiTestRunnerConfig. By default the name of the config file is * cdiTestRunnerConfig.properties.

*/ public class CdiTestRunner extends BlockJUnit4ClassRunner { private static final Logger LOGGER = Logger.getLogger(CdiTestRunner.class.getName()); private static final boolean USE_TEST_CLASS_AS_CDI_BEAN; private static final boolean ALLOW_INJECTION_POINT_MANIPULATION; private static Set notifierIdentities = new CopyOnWriteArraySet(); static { USE_TEST_CLASS_AS_CDI_BEAN = TestBaseConfig.ContainerIntegration.USE_TEST_CLASS_AS_CDI_BEAN; ALLOW_INJECTION_POINT_MANIPULATION = TestBaseConfig.MockIntegration.ALLOW_MANUAL_INJECTION_POINT_MANIPULATION; } private static ThreadLocal automaticScopeHandlingActive = new ThreadLocal(); private static ThreadLocal currentTestRunner = new ThreadLocal(); private List statementDecoratorFactories; private ContainerAwareTestContext testContext; public CdiTestRunner(Class testClass) throws InitializationError { super(testClass); TestControl testControl = testClass.getAnnotation(TestControl.class); this.testContext = new ContainerAwareTestContext(testControl, null); //benefits from the fallback-handling in ContainerAwareTestContext Class logHandlerClass = this.testContext.getLogHandlerClass(); if (!Handler.class.equals(logHandlerClass)) { try { LOGGER.addHandler(logHandlerClass.newInstance()); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } this.statementDecoratorFactories = ServiceUtils.loadServiceImplementations(TestStatementDecoratorFactory.class); Collections.sort(this.statementDecoratorFactories, new Comparator() { @Override public int compare(TestStatementDecoratorFactory f1, TestStatementDecoratorFactory f2) { return f1.getOrdinal() > f2.getOrdinal() ? 1 : -1; } }); } @Override public void run(RunNotifier runNotifier) { try { CdiTestSuiteRunner.getCdiTestRunnerExecutionRef().set(TRUE); if (!CdiTestSuiteRunner.isContainerStarted()) //not called as a part of a test-suite { int identityHashCode = System.identityHashCode(runNotifier); if (!notifierIdentities.contains(identityHashCode)) { addLogRunListener(runNotifier, identityHashCode); } } super.run(runNotifier); } finally { CdiTestSuiteRunner.getCdiTestRunnerExecutionRef().set(null); CdiTestSuiteRunner.getCdiTestRunnerExecutionRef().remove(); } } private static synchronized void addLogRunListener(RunNotifier notifier, int identityHashCode) { if (notifierIdentities.contains(identityHashCode)) { return; } notifierIdentities.add(identityHashCode); notifier.addListener(new CdiTestSuiteRunner.LogRunListener()); } @Override protected Statement methodInvoker(FrameworkMethod method, Object test) { return new ContainerAwareMethodInvoker(method, test); } @Override protected void runChild(FrameworkMethod method, RunNotifier notifier) { currentTestRunner.set(this); TestControl testControl = method.getAnnotation(TestControl.class); ContainerAwareTestContext currentTestContext = new ContainerAwareTestContext(testControl, this.testContext); currentTestContext.applyBeforeMethodConfig(method.getMethod()); try { super.runChild(method, notifier); } finally { currentTestContext.applyAfterMethodConfig(); } } @Override protected Object createTest() throws Exception { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Class type = getTestClass().getJavaClass(); Set> beans = beanManager.getBeans(type); Object result; if (!USE_TEST_CLASS_AS_CDI_BEAN || beans == null || beans.isEmpty()) { result = super.createTest(); BeanProvider.injectFields(result); //fallback to simple injection } else { Bean bean = (Bean) beanManager.resolve(beans); CreationalContext creationalContext = beanManager.createCreationalContext(bean); result = beanManager.getReference(bean, type, creationalContext); } return result; } //TODO use Rules instead @Override protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) { Statement result = super.withBefores(method, target, statement); result = wrapBeforeStatement(result, getTestClass(), target); return result; } private Statement wrapBeforeStatement(Statement statement, TestClass testClass, Object target) { for (TestStatementDecoratorFactory statementHandler : this.statementDecoratorFactories) { Statement result = statementHandler.createBeforeStatement(statement, testClass, target); if (result != null) { statement = result; } } return statement; } //TODO use Rules instead @Override protected Statement withAfters(FrameworkMethod method, final Object target, final Statement statement) { Statement result = super.withAfters(method, target, statement); result = wrapAfterStatement(result, getTestClass(), target); return result; } private Statement wrapAfterStatement(Statement statement, TestClass testClass, Object target) { for (TestStatementDecoratorFactory statementHandler : this.statementDecoratorFactories) { Statement result = statementHandler.createAfterStatement(statement, testClass, target); if (result != null) { statement = result; } } return statement; } @Override protected Statement withBeforeClasses(Statement statement) { return new BeforeClassStatement(super.withBeforeClasses(statement), this.testContext, getTestClass().getJavaClass()); } @Override protected Statement withAfterClasses(Statement statement) { Statement result = super.withAfterClasses(statement); if (!CdiTestSuiteRunner.isContainerStarted()) { return new AfterClassStatement(result, this.testContext); } return result; } //TODO use Rules instead @Override protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) { Statement result = super.withPotentialTimeout(method, test, next); if (result instanceof FailOnTimeout) { return new Statement() { @Override public void evaluate() throws Throwable { throw new RuntimeException("@" + Test.class.getName() + "#timeout isn't supported"); } }; } return result; } private class ContainerAwareMethodInvoker extends Statement { private final FrameworkMethod method; private final Object originalTarget; public ContainerAwareMethodInvoker(FrameworkMethod method, Object originalTarget) { this.method = method; this.originalTarget = originalTarget; } @Override public void evaluate() throws Throwable { BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); Class type = this.method.getMethod().getDeclaringClass(); Set> beans = beanManager.getBeans(type); if (!USE_TEST_CLASS_AS_CDI_BEAN || beans == null || beans.isEmpty()) { if (!ALLOW_INJECTION_POINT_MANIPULATION) { BeanProvider.injectFields(this.originalTarget); //fallback to simple injection } invokeMethod(this.originalTarget); } else { Bean bean = (Bean) beanManager.resolve(beans); CreationalContext creationalContext = beanManager.createCreationalContext(bean); Object target = beanManager.getReference(bean, type, creationalContext); try { invokeMethod(target); } finally { if (bean.getScope().equals(Dependent.class)) { bean.destroy(target, creationalContext); } } } } private void invokeMethod(Object target) { try { this.method.invokeExplosively(target); } catch (Throwable throwable) { throw ExceptionUtils.throwAsRuntimeException(throwable); } } } private class BeforeClassStatement extends Statement { private final Statement wrapped; private final ContainerAwareTestContext testContext; private final Class testClass; BeforeClassStatement(Statement statement, ContainerAwareTestContext testContext, Class testClass) { this.wrapped = statement; this.testContext = testContext; this.testClass = testClass; } @Override public void evaluate() throws Throwable { testContext.applyBeforeClassConfig(this.testClass); wrapped.evaluate(); } } private class AfterClassStatement extends Statement { private final Statement wrapped; private final ContainerAwareTestContext testContext; public AfterClassStatement(Statement statement, ContainerAwareTestContext testContext) { this.wrapped = statement; this.testContext = testContext; } @Override public void evaluate() throws Throwable { try { wrapped.evaluate(); } finally { testContext.applyAfterClassConfig(); } } } private static class ContainerAwareTestContext { private ContainerAwareTestContext parent; private final ProjectStage projectStage; private final TestControl testControl; private ProjectStage previousProjectStage; private boolean containerStarted = false; //only true for the layer it was started in private Stack> startedScopes = new Stack>(); private List externalContainers; ContainerAwareTestContext(TestControl testControl, ContainerAwareTestContext parent) { this.parent = parent; Class foundProjectStageClass; if (testControl == null) { this.testControl = new TestControlLiteral(); if (parent != null) { foundProjectStageClass = parent.testControl.projectStage(); } else { foundProjectStageClass = this.testControl.projectStage(); } } else { this.testControl = testControl; foundProjectStageClass = this.testControl.projectStage(); } this.projectStage = ProjectStage.valueOf(foundProjectStageClass.getSimpleName()); ProjectStageProducer.setProjectStage(this.projectStage); } boolean isContainerStarted() { return this.containerStarted || (this.parent != null && this.parent.isContainerStarted()) || CdiTestSuiteRunner.isContainerStarted(); } Class getLogHandlerClass() { return this.testControl.logHandler(); } void applyBeforeClassConfig(Class testClass) { CdiContainer container = CdiContainerLoader.getCdiContainer(); if (!isContainerStarted()) { if (!CdiTestSuiteRunner.isContainerStarted()) { // We are setting this system property to make the deployment for Weld "flat" // This (amongst other things) means that alternatives enabled via beans.xml will be // enabled globally // Beginning with Weld 2.x you could use Weld.property(), but here we depend on Weld 1.x API // Note that Weld 1 was "flat" anyway, so this property only affects newer versions of Weld // System.setProperty("org.jboss.weld.se.archive.isolation", "false"); // Weld 5.0: https://docs.jboss.org/weld/reference/5.0.0.Final/en-US/html_single/#_bean_archive_isolation System.setProperty("org.jboss.weld.environment.servlet.archive.isolation", "false"); CdiTestSuiteRunner.applyTestSpecificMetaData(testClass); container.boot(CdiTestSuiteRunner.getTestContainerConfig()); setContainerStarted(); bootExternalContainers(testClass); } } List> restrictedScopes = new ArrayList>(); //controlled by the container and not supported by weld: restrictedScopes.add(ApplicationScoped.class); restrictedScopes.add(Singleton.class); if (this.parent == null && this.testControl.getClass().equals(TestControlLiteral.class)) { //skip scope-handling if @TestControl isn't used explicitly on the test-class -> TODO re-visit it restrictedScopes.add(RequestScoped.class); restrictedScopes.add(SessionScoped.class); } startScopes(container, testClass, null, restrictedScopes.toArray(new Class[restrictedScopes.size()])); } private void bootExternalContainers(Class testClass) { if (!this.testControl.startExternalContainers()) { return; } if (this.externalContainers == null) { List configuredExternalContainers = ServiceUtils.loadServiceImplementations(ExternalContainer.class); Collections.sort(configuredExternalContainers, new Comparator() { @Override public int compare(ExternalContainer ec1, ExternalContainer ec2) { return ec1.getOrdinal() > ec2.getOrdinal() ? 1 : -1; } }); this.externalContainers = new ArrayList(configuredExternalContainers.size()); ExternalContainer externalContainerBean; for (ExternalContainer externalContainer : configuredExternalContainers) { //needed to use cdi-observers in the container optionally externalContainerBean = BeanProvider.getContextualReference(externalContainer.getClass(), true); if (externalContainerBean != null) { this.externalContainers.add(externalContainerBean); } else { this.externalContainers.add(externalContainer); } } for (ExternalContainer externalContainer : this.externalContainers) { try { if (externalContainer instanceof TestAware) { ((TestAware)externalContainer).setTestClass(testClass); } externalContainer.boot(); } catch (RuntimeException e) { Logger.getLogger(CdiTestRunner.class.getName()).log(Level.WARNING, "booting " + externalContainer.getClass().getName() + " failed", e); } } } } void applyAfterClassConfig() { CdiContainer container = CdiContainerLoader.getCdiContainer(); stopStartedScopes(container); if (this.containerStarted) { if (CdiTestSuiteRunner.isStopContainerAllowed()) { shutdownExternalContainers(); container.shutdown(); //stop the container on the same level which started it CdiTestSuiteRunner.setContainerStarted(false); } } } private void shutdownExternalContainers() { if (this.externalContainers == null) { return; } for (ExternalContainer externalContainer : this.externalContainers) { try { externalContainer.shutdown(); } catch (RuntimeException e) { Logger.getLogger(CdiTestRunner.class.getName()).log(Level.WARNING, "shutting down " + externalContainer.getClass().getName() + " failed", e); } } } void applyBeforeMethodConfig(Method testMethod) { this.previousProjectStage = ProjectStageProducer.getInstance().getProjectStage(); ProjectStageProducer.setProjectStage(this.projectStage); setCurrentTestMethod(testMethod); startScopes(CdiContainerLoader.getCdiContainer(), testMethod.getDeclaringClass(), testMethod); } void applyAfterMethodConfig() { try { stopStartedScopes(CdiContainerLoader.getCdiContainer()); } finally { setCurrentTestMethod(null); ProjectStageProducer.setProjectStage(previousProjectStage); previousProjectStage = null; currentTestRunner.set(null); currentTestRunner.remove(); } } void setContainerStarted() { this.containerStarted = true; CdiTestSuiteRunner.setContainerStarted(true); } private void startScopes(CdiContainer container, Class testClass, Method testMethod, Class... restrictedScopes) { try { automaticScopeHandlingActive.set(TRUE); ContextControl contextControl = container.getContextControl(); List> scopeClasses = new ArrayList>(); Collections.addAll(scopeClasses, this.testControl.startScopes()); if (scopeClasses.isEmpty()) { addScopesForDefaultBehavior(scopeClasses); } else { List testControlValidatorList = ServiceUtils.loadServiceImplementations(TestControlValidator.class); for (TestControlValidator testControlValidator : testControlValidatorList) { if (testControlValidator instanceof TestAware) { if (testMethod != null) { ((TestAware)testControlValidator).setTestMethod(testMethod); } ((TestAware)testControlValidator).setTestClass(testClass); } try { testControlValidator.validate(this.testControl); } finally { if (testControlValidator instanceof TestAware) { ((TestAware)testControlValidator).setTestClass(null); ((TestAware)testControlValidator).setTestMethod(null); } } } } for (Class scopeAnnotation : scopeClasses) { if (this.parent != null && this.parent.isScopeStarted(scopeAnnotation)) { continue; } if (isRestrictedScope(scopeAnnotation, restrictedScopes)) { continue; } try { //force a clean context - TODO discuss onScopeStopped call contextControl.stopContext(scopeAnnotation); contextControl.startContext(scopeAnnotation); this.startedScopes.add(scopeAnnotation); onScopeStarted(scopeAnnotation); } catch (RuntimeException e) { Logger logger = Logger.getLogger(CdiTestRunner.class.getName()); logger.setLevel(Level.SEVERE); logger.log(Level.SEVERE, "failed to start scope @" + scopeAnnotation.getName(), e); } } } finally { automaticScopeHandlingActive.set(null); automaticScopeHandlingActive.remove(); } } private void addScopesForDefaultBehavior(List> scopeClasses) { if (this.parent != null && !this.parent.isScopeStarted(RequestScoped.class)) { if (!scopeClasses.contains(RequestScoped.class)) { scopeClasses.add(RequestScoped.class); } } if (this.parent != null && !this.parent.isScopeStarted(SessionScoped.class)) { if (!scopeClasses.contains(SessionScoped.class)) { scopeClasses.add(SessionScoped.class); } } } private boolean isRestrictedScope(Class scopeAnnotation, Class[] restrictedScopes) { for (Class restrictedScope : restrictedScopes) { if (scopeAnnotation.equals(restrictedScope)) { return true; } } return false; } private boolean isScopeStarted(Class scopeAnnotation) { return this.startedScopes.contains(scopeAnnotation); } private void stopStartedScopes(CdiContainer container) { try { automaticScopeHandlingActive.set(TRUE); while (!this.startedScopes.empty()) { Class scopeAnnotation = this.startedScopes.pop(); //TODO check if context was started by parent try { container.getContextControl().stopContext(scopeAnnotation); onScopeStopped(scopeAnnotation); } catch (RuntimeException e) { Logger logger = Logger.getLogger(CdiTestRunner.class.getName()); logger.setLevel(Level.SEVERE); logger.log(Level.SEVERE, "failed to stop scope @" + scopeAnnotation.getName(), e); } } } finally { automaticScopeHandlingActive.remove(); automaticScopeHandlingActive.set(null); } } private void onScopeStarted(Class scopeClass) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { externalContainer.startScope(scopeClass); } } private void onScopeStopped(Class scopeClass) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { externalContainer.stopScope(scopeClass); } } private static List collectExternalContainers(ContainerAwareTestContext testContext) { List result = new ArrayList(); if (testContext.externalContainers != null) { result.addAll(testContext.externalContainers); } if (testContext.parent != null) { result.addAll(collectExternalContainers(testContext.parent)); } return result; } private void setCurrentTestMethod(Method testMethod) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { if (externalContainer instanceof TestAware) { try { ((TestAware)externalContainer).setTestMethod(testMethod); } catch (Throwable t) { //with a correct setup it shouldn't happen //TODO better handling for invalid constellations Assert.fail(t.getMessage()); } } } } } public static Boolean isAutomaticScopeHandlingActive() { return automaticScopeHandlingActive.get(); } public static List getActiveExternalContainers() { CdiTestRunner cdiTestRunner = currentTestRunner.get(); if (cdiTestRunner == null || cdiTestRunner.testContext == null || cdiTestRunner.testContext.externalContainers == null) { return Collections.emptyList(); } return Collections.unmodifiableList(cdiTestRunner.testContext.externalContainers); } } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/junit/CdiTestSuiteRunner.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.junit; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.PropertyLoader; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.testcontrol.api.TestControl; import org.junit.runner.Description; import org.junit.runner.Runner; import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; import org.junit.runner.notification.RunNotifier; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; import org.junit.runners.model.RunnerBuilder; import jakarta.inject.Named; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import static java.lang.Boolean.TRUE; @SuppressWarnings("UnusedDeclaration") public class CdiTestSuiteRunner extends Suite { /** * Configuration key to define a custom configuration properties file. * e.g.: * deltaspike.testcontrol.test-container.config-file=META-INF/dsTestContainerBootConfig.properties */ public static final String CUSTOM_TEST_CONTAINER_CONFIG_FILE_KEY = "deltaspike.testcontrol.test-container.config-file"; /** * Default resource location of the property file which gets used * for the container bootstrap. * This value can be overridden by using {@link #CUSTOM_TEST_CONTAINER_CONFIG_FILE_KEY} */ public static final String DEFAULT_TEST_CONTAINER_CONFIG_FILE_NAME = "META-INF/apache-deltaspike_test-container"; private static final boolean STOP_CONTAINER; private static final ThreadLocal IS_CDI_TEST_RUNNER_EXECUTION = new ThreadLocal(); private static volatile boolean containerStarted; //TODO private final Class testSuiteClass; static { STOP_CONTAINER = TestBaseConfig.ContainerIntegration.STOP_CONTAINER; } public CdiTestSuiteRunner(Class klass, RunnerBuilder builder) throws InitializationError { super(klass, builder); this.testSuiteClass = klass; } protected CdiTestSuiteRunner(Class klass, Class[] suiteClasses) throws InitializationError { super(klass, suiteClasses); this.testSuiteClass = klass; } protected CdiTestSuiteRunner(RunnerBuilder builder, Class klass, Class[] suiteClasses) throws InitializationError { super(builder, klass, suiteClasses); this.testSuiteClass = klass; } protected CdiTestSuiteRunner(Class klass, List runners) throws InitializationError { super(klass, runners); this.testSuiteClass = klass; } @Override public void run(RunNotifier notifier) { if (this.testSuiteClass == null) { throw new IllegalStateException("no test-suite class found"); } CdiContainer container = CdiContainerLoader.getCdiContainer(); if (!containerStarted) { applyTestSpecificMetaData(getTestClass().getJavaClass()); container.boot(getTestContainerConfig()); containerStarted = true; } notifier.addListener(new LogRunListener()); try { super.run(notifier); } finally { if (STOP_CONTAINER) { container.shutdown(); containerStarted = false; } } } public static boolean isContainerStarted() { return containerStarted; } static Boolean isStopContainerAllowed() { return STOP_CONTAINER; } static ThreadLocal getCdiTestRunnerExecutionRef() { return IS_CDI_TEST_RUNNER_EXECUTION; } static void setContainerStarted(boolean containerStarted) { CdiTestSuiteRunner.containerStarted = containerStarted; } static class LogRunListener extends RunListener { private final Logger logger = Logger.getLogger(LogRunListener.class.getName()); LogRunListener() { } @Override public void testStarted(Description description) throws Exception { if (TRUE.equals(IS_CDI_TEST_RUNNER_EXECUTION.get())) { this.logger.info("[run] " + description.getClassName() + "#" + description.getMethodName()); } super.testRunStarted(description); } @Override public void testFinished(Description description) throws Exception { if (TRUE.equals(IS_CDI_TEST_RUNNER_EXECUTION.get())) { this.logger.info("[finished] " + description.getClassName() + "#" + description.getMethodName()); } super.testFinished(description); } @Override public void testFailure(Failure failure) throws Exception { if (TRUE.equals(IS_CDI_TEST_RUNNER_EXECUTION.get())) { Description description = failure.getDescription(); this.logger.log(Level.SEVERE, "[failed] " + description.getClassName() + "#" + description.getMethodName() + " message: " + failure.getMessage()); } super.testFailure(failure); } } public static Properties getTestContainerConfig() { String cdiTestRunnerConfig = ConfigResolver.getProjectStageAwarePropertyValue( CUSTOM_TEST_CONTAINER_CONFIG_FILE_KEY, DEFAULT_TEST_CONTAINER_CONFIG_FILE_NAME); return PropertyLoader.getProperties(cdiTestRunnerConfig); } //just here, because all shared methods are in this class static void applyTestSpecificMetaData(Class currentAnnotationSource) { TestControl testControl = currentAnnotationSource.getAnnotation(TestControl.class); String activeAlternativeLabel = checkForLabeledAlternativeConfig(testControl); initTestEnvConfig(currentAnnotationSource, activeAlternativeLabel, testControl); } private static String checkForLabeledAlternativeConfig(TestControl testControl) { String activeAlternativeLabel = ""; if (testControl != null) { Class activeTypedAlternativeLabel = testControl.activeAlternativeLabel(); if (!TestControl.Label.class.equals(activeTypedAlternativeLabel)) { Named labelName = activeTypedAlternativeLabel.getAnnotation(Named.class); if (labelName != null) { activeAlternativeLabel = labelName.value(); } else { String labelClassName = activeTypedAlternativeLabel.getSimpleName(); activeAlternativeLabel = labelClassName.substring(0, 1).toLowerCase(); if (labelClassName.length() > 1) { activeAlternativeLabel += labelClassName.substring(1); } } } } return activeAlternativeLabel; } private static void initTestEnvConfig(Class testClass, String activeAlternativeLabel, TestControl testControl) { if (ClassDeactivationUtils.isActivated(TestConfigSource.class)) { TestConfigSource testConfigSource = null; for (ConfigSource configSource : ConfigResolver.getConfigSources()) { if (configSource instanceof TestConfigSource) { //if it happens: parallel test-execution can't be supported with labeled alternatives testConfigSource = (TestConfigSource) configSource; } } if (testConfigSource == null) { testConfigSource = new TestConfigSource(); ConfigResolver.addConfigSources(Arrays.asList(testConfigSource)); } //always set it even if it is empty (it might overrule the value of the prev. test testConfigSource.getProperties().put("activeAlternativeLabel", activeAlternativeLabel); testConfigSource.getProperties().put("activeAlternativeLabelSource", testClass.getName()); if (testControl != null) { testConfigSource.getProperties().put(TestControl.class.getName(), testClass.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), testControl.classFilter().getName()); } else { //reset it to avoid leaks between tests testConfigSource.getProperties().put(TestControl.class.getName(), TestControl.class.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), ClassFilter.class.getName()); } } else { //always set it even if it is empty (it might overrule the value of the prev. test System.setProperty("activeAlternativeLabel", activeAlternativeLabel); //will be picked up by ds-core System.setProperty("activeAlternativeLabelSource", testClass.getName()); //can be used for custom logic if (testControl != null) //can be used for custom logic { System.setProperty(TestControl.class.getName(), testClass.getName()); System.setProperty(ClassFilter.class.getName(), testControl.classFilter().getName()); } else { //reset it to avoid leaks between tests System.setProperty(TestControl.class.getName(), TestControl.class.getName()); System.setProperty(ClassFilter.class.getName(), ClassFilter.class.getName()); } } } //config-sources are already stored per classloader //keep it public to allow type-safe deactivation (if needed) public static class TestConfigSource implements ConfigSource, Deactivatable { private Map testConfig = new ConcurrentHashMap(); @Override public int getOrdinal() { return Integer.MIN_VALUE; } @Override public Map getProperties() { return testConfig; } @Override public String getPropertyValue(String key) { return testConfig.get(key); } @Override public String getConfigName() { return "ds-test-config"; } @Override public boolean isScannable() { return true; } } } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/junit/TestBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.junit; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; public interface TestBaseConfig extends DeltaSpikeBaseConfig { interface ContainerIntegration { //default is false to improve the compatibility with @Before and @After Boolean USE_TEST_CLASS_AS_CDI_BEAN = ConfigResolver.resolve("deltaspike.testcontrol.use_test_class_as_cdi_bean") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); Boolean STOP_CONTAINER = ConfigResolver.resolve("deltaspike.testcontrol.stop_container") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.TRUE) .getValue(); } interface MockIntegration { String ALLOW_MOCKED_BEANS_KEY = "deltaspike.testcontrol.mock-support.allow_mocked_beans"; String ALLOW_MOCKED_PRODUCERS_KEY = "deltaspike.testcontrol.mock-support.allow_mocked_producers"; String ALLOW_MANUAL_INJECTION_POINT_MANIPULATION_KEY = "deltaspike.testcontrol.mock-support.allow_manual_injection-point_manipulation"; Boolean ALLOW_MOCKED_BEANS = ConfigResolver.resolve(ALLOW_MOCKED_BEANS_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); Boolean ALLOW_MOCKED_PRODUCERS = ConfigResolver.resolve(ALLOW_MOCKED_PRODUCERS_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); //if enabled it's possible to change the value of injection-points after the injection-process and //before test-execution. that allows to replace injection-points (e.g. with a mock) conditionally //via a test-rule or @Before Boolean ALLOW_MANUAL_INJECTION_POINT_MANIPULATION = ConfigResolver.resolve(ALLOW_MANUAL_INJECTION_POINT_MANIPULATION_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); } } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/literal/TestControlLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.literal; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.testcontrol.api.TestControl; import jakarta.enterprise.util.AnnotationLiteral; import java.lang.annotation.Annotation; import java.util.logging.Handler; public class TestControlLiteral extends AnnotationLiteral implements TestControl { private static final long serialVersionUID = 6684011035751678259L; private final TestControl defaultInstance; public TestControlLiteral() { this.defaultInstance = AnnotationInstanceProvider.of(TestControl.class); } @Override public Class[] startScopes() { return defaultInstance.startScopes(); } @Override public Class projectStage() { return defaultInstance.projectStage(); } @Override public Class logHandler() { return defaultInstance.logHandler(); } @Override public boolean startExternalContainers() { return defaultInstance.startExternalContainers(); } @Override public Class activeAlternativeLabel() { return defaultInstance.activeAlternativeLabel(); } @Override public Class classFilter() { return defaultInstance.classFilter(); } } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/mock/ApplicationMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.mock; import java.lang.annotation.Annotation; //needed e.g. due to caches for application-scoped,... beans public interface ApplicationMockManager { void addMock(Object mockInstance, Annotation... qualifiers); T getMock(Class beanClass, Annotation... qualifiers); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/mock/DynamicMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.mock; public interface DynamicMockManager extends ApplicationMockManager { void reset(); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/api/mock/TypedMock.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.api.mock; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; //equivalent to @Typed for mocks to avoid conflicts with cdi @Target({ FIELD, METHOD, TYPE }) @Retention(RUNTIME) public @interface TypedMock { Class[] value() default { }; } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/spi/ExternalContainer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.spi; import java.lang.annotation.Annotation; public interface ExternalContainer { /** * Bootstraps the container */ void boot(); /** * Closes the container */ void shutdown(); int getOrdinal(); /** * Signals a started scope * @param scopeClass annotation-class of the scope */ void startScope(Class scopeClass); /** * Signals a stopped scope * @param scopeClass annotation-class of the scope */ void stopScope(Class scopeClass); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/spi/TestAware.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.spi; import java.lang.reflect.Method; public interface TestAware { void setTestClass(Class testClass); void setTestMethod(Method testMethod); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/spi/TestControlValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.spi; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.testcontrol.api.TestControl; /** * Allows to provide a different validator which could * allow e.g. more scope-annotations (if a custom cdi-control implementation supports that custom contexts as well). * A custom validator could also validate e.g. the usage of project-stages,... */ public interface TestControlValidator extends Deactivatable { void validate(TestControl testControl); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/spi/junit/TestStatementDecoratorFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.spi.junit; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; //TODO find a better name public interface TestStatementDecoratorFactory { Statement createBeforeStatement(Statement originalStatement, TestClass testClass, Object target); Statement createAfterStatement(Statement originalStatement, TestClass testClass, Object target); int getOrdinal(); } ================================================ FILE: deltaspike/modules/test-control/api/src/main/java/org/apache/deltaspike/testcontrol/spi/mock/MockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.spi.mock; import org.apache.deltaspike.core.spi.activation.Deactivatable; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.BeanManager; public interface MockFilter extends Deactivatable { boolean isMockedImplementationSupported(BeanManager beanManager, Annotated annotated); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/jsf/MockedJsf2TestContainer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.jsf; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.myfaces.test.mock.MockApplicationFactory; import org.apache.myfaces.test.mock.MockExceptionHandlerFactory; import org.apache.myfaces.test.mock.MockExternalContext; import org.apache.myfaces.test.mock.MockFacesContext; import org.apache.myfaces.test.mock.MockFacesContextFactory; import org.apache.myfaces.test.mock.MockHttpServletRequest; import org.apache.myfaces.test.mock.MockHttpServletResponse; import org.apache.myfaces.test.mock.MockHttpSession; import org.apache.myfaces.test.mock.MockPartialViewContextFactory; import org.apache.myfaces.test.mock.MockRenderKit; import org.apache.myfaces.test.mock.MockRenderKitFactory; import org.apache.myfaces.test.mock.MockServletConfig; import org.apache.myfaces.test.mock.MockServletContext; import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory; import org.apache.myfaces.test.mock.visit.MockVisitContextFactory; import jakarta.el.ExpressionFactory; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.faces.FactoryFinder; import jakarta.faces.application.Application; import jakarta.faces.application.ApplicationFactory; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.ExceptionHandler; import jakarta.faces.context.ExceptionHandlerFactory; import jakarta.faces.context.FacesContext; import jakarta.faces.context.FacesContextFactory; import jakarta.faces.lifecycle.Lifecycle; import jakarta.faces.lifecycle.LifecycleFactory; import jakarta.faces.render.RenderKit; import jakarta.faces.render.RenderKitFactory; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Locale; import java.util.Map; //known restriction: faces-config.xml files are ignored @ApplicationScoped public class MockedJsf2TestContainer implements ExternalContainer { protected MockServletConfig servletConfig; protected MockServletContext servletContext; protected Lifecycle lifecycle; protected RenderKit renderKit; protected Application application; protected FacesContext facesContext; protected MockHttpServletRequest request; protected MockHttpServletResponse response; protected MockHttpSession session; protected Map containerConfig; public void boot() { initContainerConfig(); initServletObjects(); initJsf(); } protected void initContainerConfig() { containerConfig = new HashMap(); for (Map.Entry entry : ConfigResolver.getAllProperties().entrySet()) { if (entry.getKey().startsWith("org.apache.myfaces.") || entry.getKey().startsWith("jakarta.faces.") || entry.getKey().startsWith("facelets.")) { containerConfig.put(entry.getKey(), entry.getValue()); } } } protected void initServletObjects() { this.servletContext = new MockServletContext(); this.servletConfig = new MockServletConfig(this.servletContext); applyContainerConfig(); } protected void applyContainerConfig() { //add the default values servletContext.addInitParameter("jakarta.faces.PROJECT_STAGE", "UnitTest"); servletContext.addInitParameter("jakarta.faces.PARTIAL_STATE_SAVING", "true"); servletContext.addInitParameter("jakarta.faces.FACELETS_REFRESH_PERIOD", "-1"); servletContext.addInitParameter("org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true"); servletContext.addInitParameter("org.apache.myfaces.spi.InjectionProvider", "org.apache.myfaces.spi.impl.NoInjectionAnnotationInjectionProvider"); servletContext.addInitParameter("org.apache.myfaces.config.annotation.LifecycleProvider", "org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider"); servletConfig.addInitParameter("org.apache.myfaces.CHECKED_VIEWID_CACHE_ENABLED", "false"); servletContext.addInitParameter(ExpressionFactory.class.getName(), "org.apache.el.ExpressionFactoryImpl"); //add custom values (might replace the default values) for (Map.Entry entry : containerConfig.entrySet()) { servletContext.addInitParameter(entry.getKey(), entry.getValue()); } } protected void initJsf() { FactoryFinder.releaseFactories(); onPreInitJsf(); initLifecycle(); initApplication(); initRenderKit(); } protected void onPreInitJsf() { //init mocked jsf factories addFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName()); addFactory(FactoryFinder.FACES_CONTEXT_FACTORY, MockFacesContextFactory.class.getName()); addFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifecycleFactory.class.getName()); addFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName()); addFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY, MockExceptionHandlerFactory.class.getName()); addFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY, MockPartialViewContextFactory.class.getName()); addFactory(FactoryFinder.VISIT_CONTEXT_FACTORY, MockVisitContextFactory.class.getName()); } protected void addFactory(String factoryName, String className) { FactoryFinder.setFactory(factoryName, className); } protected void initLifecycle() { LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); this.lifecycle = lifecycleFactory.getLifecycle(getLifecycleId()); } protected void initApplication() { ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); this.application = applicationFactory.getApplication(); } protected void initRenderKit() { RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder .getFactory(FactoryFinder.RENDER_KIT_FACTORY); this.renderKit = new MockRenderKit(); renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, this.renderKit); } @Override public void startScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { initRequest(); initResponse(); initFacesContext(); initDefaultView(); } else if (SessionScoped.class.equals(scopeClass)) { initSession(); } } protected void initRequest() { this.request = new MockHttpServletRequest(this.session); this.request.setServletContext(this.servletContext); } protected void initResponse() { this.response = new MockHttpServletResponse(); } protected void initFacesContext() { FacesContextFactory facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY); this.facesContext = facesContextFactory.getFacesContext( this.servletContext, this.request, this.response, this.lifecycle); ((MockFacesContext) this.facesContext).setApplication(this.application); ExceptionHandler exceptionHandler = ((ExceptionHandlerFactory) FactoryFinder.getFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY)).getExceptionHandler(); this.facesContext.setExceptionHandler(exceptionHandler); ((MockFacesContext) this.facesContext).setExternalContext( new MockExternalContext(this.servletContext, this.request, this.response)); } protected void initDefaultView() { UIViewRoot root = new UIViewRoot(); root.setViewId("/viewId"); root.setLocale(getLocale()); root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); this.facesContext.setViewRoot(root); } protected void initSession() { if (this.request != null) { this.session = (MockHttpSession)this.request.getSession(true); } else { this.session = new MockHttpSession(); this.session.setServletContext(this.servletContext); } } @Override public void stopScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { if (this.facesContext != null) { this.facesContext.release(); } this.facesContext = null; this.request = null; this.response = null; } else if (SessionScoped.class.equals(scopeClass)) { this.session = null; } } protected Locale getLocale() { return Locale.getDefault(); } public void shutdown() { this.application = null; this.servletConfig = null; this.containerConfig = null; this.lifecycle = null; this.renderKit = null; this.servletContext = null; FactoryFinder.releaseFactories(); } @Override public int getOrdinal() { return 1000; //default in ds } protected String getLifecycleId() { return LifecycleFactory.DEFAULT_LIFECYCLE; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/jsf/MockedJsfTestContainerAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.jsf; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.myfaces.test.mock.MockedJsfTestContainer; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import java.lang.annotation.Annotation; /** * Optional adapter for MockedJsfTestContainer * Requires MyFaces-Test v1.0.6 or higher */ @ApplicationScoped public class MockedJsfTestContainerAdapter implements ExternalContainer { private final MockedJsfTestContainer mockedMyFacesTestContainer = new MockedJsfTestContainer(); public void boot() { this.mockedMyFacesTestContainer.setUp(); } @Override public void startScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.startRequest(); } else if (SessionScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.startSession(); } } @Override public void stopScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.endRequest(); } else if (SessionScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.endSession(); } } public void shutdown() { this.mockedMyFacesTestContainer.tearDown(); } @Override public int getOrdinal() { return 1000; //default in ds } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/jsf/MyFacesContainerAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.jsf; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.deltaspike.testcontrol.spi.TestAware; import org.apache.myfaces.mc.test.core.annotation.TestConfig; import org.apache.myfaces.mc.test.core.runner.MyFacesContainer; import org.junit.runners.model.TestClass; import jakarta.el.ExpressionFactory; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * Optional adapter for MyFacesContainer * Requires MyFaces-Core 2.2.x, MyFaces-Test v1.0.6 or higher as well as org.apache.myfaces.core:myfaces-impl-test */ @ApplicationScoped public class MyFacesContainerAdapter implements TestAware, ExternalContainer { private static final TestConfig DEFAULT_TEST_CONFIG_LITERAL = AnnotationInstanceProvider.of(TestConfig.class); protected MyFacesContainer mockedMyFacesTestContainer; protected Class testClass; protected Map containerConfig = new HashMap(); public void boot() { final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); this.mockedMyFacesTestContainer = new MyFacesContainer(new TestClass(this.testClass)) { @Override protected String getWebappResourcePath() { TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class); if (testConfig == null || DEFAULT_TEST_CONFIG_LITERAL.webappResourcePath().equals( testConfig.webappResourcePath())) { return MyFacesTestBaseConfig.WEBAPP_RESOURCE_PATH; } return testConfig.webappResourcePath(); } @Override protected void setUpServletObjects() { //just needed for MyFaces-Test util v1.0.7 //(to bypass issues with the outdated URLClassLoader used by AbstractJsfTestContainer) setCurrentClassLoader(originalClassLoader); super.setUpServletObjects(); } @Override protected void setUpWebConfigParams() { servletContext.addInitParameter("org.apache.myfaces.config.annotation.LifecycleProvider", "org.apache.myfaces.config.annotation.NoInjectionAnnotationLifecycleProvider"); servletContext.addInitParameter("org.apache.myfaces.CHECKED_VIEWID_CACHE_ENABLED", "false"); servletContext.addInitParameter(ExpressionFactory.class.getName(), "org.apache.el.ExpressionFactoryImpl"); super.setUpWebConfigParams(); initContainerConfig(); //add custom values (might replace the default values) for (Map.Entry entry : containerConfig.entrySet()) { servletContext.addInitParameter(entry.getKey(), entry.getValue()); } } }; this.mockedMyFacesTestContainer.setUp(new Object() /*we don't need the test-instance here*/); } protected void setCurrentClassLoader(ClassLoader originalClassLoader) { Thread.currentThread().setContextClassLoader(originalClassLoader); } protected void initContainerConfig() { containerConfig = new HashMap(); for (Map.Entry entry : ConfigResolver.getAllProperties().entrySet()) { if (entry.getKey().startsWith("org.apache.myfaces.") || entry.getKey().startsWith("jakarta.faces.") || entry.getKey().startsWith("facelets.")) { containerConfig.put(entry.getKey(), entry.getValue()); } } } @Override public void startScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.startRequest(); } } @Override public void stopScope(Class scopeClass) { if (RequestScoped.class.equals(scopeClass)) { this.mockedMyFacesTestContainer.endRequest(); } } public void shutdown() { if (this.mockedMyFacesTestContainer == null) { throw new IllegalStateException("During starting MyFaces-Core an exception happened."); } this.mockedMyFacesTestContainer.tearDown(); } @Override public int getOrdinal() { return 1000; //default in ds } @Override public void setTestClass(Class testClass) { this.testClass = testClass; } @Override public void setTestMethod(Method method) { //not needed } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/jsf/MyFacesContainerPerTestMethodAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.jsf; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.deltaspike.testcontrol.spi.TestAware; import jakarta.enterprise.context.ApplicationScoped; import java.lang.annotation.Annotation; import java.lang.reflect.Method; /** * Optional adapter for MyFacesContainer which gets started and stopped for every test-method * Requires MyFaces-Core 2.2.x, MyFaces-Test v1.0.6 or higher as well as org.apache.myfaces.core:myfaces-impl-test */ @ApplicationScoped public class MyFacesContainerPerTestMethodAdapter implements TestAware, ExternalContainer { private static ThreadLocal myFacesContainerAdapterThreadLocal = new ThreadLocal(); @Override public void boot() { } @Override public void shutdown() { } @Override public int getOrdinal() { return 1000; //default in ds } @Override public void startScope(Class scopeClass) { myFacesContainerAdapterThreadLocal.get().startScope(scopeClass); } @Override public void stopScope(Class scopeClass) { myFacesContainerAdapterThreadLocal.get().stopScope(scopeClass); } @Override public void setTestClass(Class testClass) { MyFacesContainerAdapter myFacesContainerAdapter = new MyFacesContainerAdapter(); myFacesContainerAdapter.setTestClass(testClass); myFacesContainerAdapterThreadLocal.set(myFacesContainerAdapter); } @Override public void setTestMethod(Method testMethod) { if (testMethod != null) { myFacesContainerAdapterThreadLocal.get().boot(); } else { myFacesContainerAdapterThreadLocal.get().shutdown(); } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/jsf/MyFacesTestBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.jsf; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; public interface MyFacesTestBaseConfig extends DeltaSpikeBaseConfig { String WEBAPP_RESOURCE_PATH = ConfigResolver.resolve("deltaspike.testcontrol.mf.test.webapp_resource_path") .as(String.class) .withCurrentProjectStage(true) .withDefault("") .getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/main/java/org/apache/deltaspike/testcontrol/impl/transaction/TransactionStatementDecoratorFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.transaction; import junit.framework.AssertionFailedError; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.testcontrol.spi.junit.TestStatementDecoratorFactory; import org.junit.After; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.MultipleFailureException; import org.junit.runners.model.Statement; import org.junit.runners.model.TestClass; import jakarta.persistence.EntityManager; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * Not compatible with too short scopes, because they are closed too early */ public class TransactionStatementDecoratorFactory implements TestStatementDecoratorFactory { private static final Logger LOG = Logger.getLogger(TransactionStatementDecoratorFactory.class.getName()); static { LOG.setLevel(Level.INFO); } @Override public Statement createBeforeStatement(Statement originalStatement, TestClass testClass, Object target) { return originalStatement; } @Override public Statement createAfterStatement(Statement originalStatement, TestClass testClass, Object target) { final List afters = testClass.getAnnotatedMethods(After.class); return new TransactionAwareRunAfters(originalStatement, afters, target); } @Override public int getOrdinal() { return 1000; //default in ds } //see org.junit.internal.runners.statements.RunAfters private class TransactionAwareRunAfters extends Statement { private final Statement wrapped; private final List afters; private final Object target; public TransactionAwareRunAfters(Statement wrapped, List afters, Object target) { this.wrapped = wrapped; this.afters = afters; this.target = target; } @Override public void evaluate() throws Throwable { List result = new ArrayList(); try { this.wrapped.evaluate(); } catch (Throwable e) { result.add(performConsistencyCheck(e)); } finally { Throwable t = performConsistencyCheck(null); if (t != null) { result.add(t); } for (FrameworkMethod each : this.afters) { try { each.invokeExplosively(this.target); } catch (Throwable e) { result.add(e); } } } if (!result.isEmpty()) { MultipleFailureException.assertEmpty(result); } } private Throwable performConsistencyCheck(Throwable t) { Throwable result = t; if (t instanceof InvocationTargetException) { result = t.getCause(); } List entityManagerList = BeanProvider.getContextualReferences(EntityManager.class, true, false); for (Field field : this.target.getClass().getDeclaredFields()) { if (EntityManager.class.isAssignableFrom(field.getType())) { field.setAccessible(true); try { entityManagerList.add((EntityManager) field.get(this.target)); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } } for (EntityManager entityManager : entityManagerList) { if (entityManager.getTransaction().isActive()) { if (t instanceof AssertionFailedError) { LOG.severe("assert failed within a transaction"); } LOG.severe("start manual rollback"); //force rollback - otherwise there can be side-effects in other tests or cleanup-code // (e.g. 'TRUNCATE SCHEMA' would fail) entityManager.getTransaction().rollback(); if (result == null) { result = new IllegalStateException("open transaction found"); } } } return result; } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/InternalMyFacesTestContainerAdapter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol; import org.apache.deltaspike.test.testcontrol.uc005.MockedJsfContainerTest; import org.apache.deltaspike.test.testcontrol.uc006.SkipExternalContainerTest; import org.apache.deltaspike.test.testcontrol.uc009.JsfContainerTest; import org.apache.deltaspike.test.testcontrol.uc010.JsfContainerPerTestMethodTest; import org.apache.deltaspike.testcontrol.impl.jsf.MockedJsf2TestContainer; import org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerAdapter; import org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerPerTestMethodAdapter; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import org.apache.deltaspike.testcontrol.spi.TestAware; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class InternalMyFacesTestContainerAdapter implements TestAware, ExternalContainer { private ExternalContainer wrapped; @Override public void boot() { wrapped.boot(); } @Override public void shutdown() { wrapped.shutdown(); } @Override public int getOrdinal() { return wrapped.getOrdinal(); } @Override public void startScope(Class scopeClass) { wrapped.startScope(scopeClass); } @Override public void stopScope(Class scopeClass) { wrapped.stopScope(scopeClass); } @Override public void setTestClass(Class testClass) { if (MockedJsfContainerTest.class.equals(testClass) || SkipExternalContainerTest.class.equals(testClass)) { this.wrapped = new MockedJsf2TestContainer(); } else if (JsfContainerTest.class.equals(testClass)) { this.wrapped = new MyFacesContainerAdapter(); ((TestAware)this.wrapped).setTestClass(testClass); } else if (JsfContainerPerTestMethodTest.class.equals(testClass)) { this.wrapped = new MyFacesContainerPerTestMethodAdapter(); ((TestAware)this.wrapped).setTestClass(testClass); } else { this.wrapped = new ExternalContainer() { @Override public void boot() { } @Override public void shutdown() { } @Override public int getOrdinal() { return 0; } @Override public void startScope(Class scopeClass) { } @Override public void stopScope(Class scopeClass) { } }; } } @Override public void setTestMethod(Method testMethod) { if (this.wrapped instanceof TestAware) { ((TestAware)this.wrapped).setTestMethod(testMethod); } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/shared/ApplicationScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.shared; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationScopedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/shared/MyQualifier.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.shared; import jakarta.inject.Qualifier; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(value = RetentionPolicy.RUNTIME) @Documented @Qualifier public @interface MyQualifier { } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/shared/RequestScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.shared; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class RequestScopedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/shared/SessionScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.shared; import jakarta.enterprise.context.SessionScoped; import java.io.Serializable; @SessionScoped public class SessionScopedBean implements Serializable { private static final long serialVersionUID = -6055362670706159152L; protected int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc001/MockedRequestScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc001; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedRequestScopedBeanTest { @Inject private RequestScopedBean requestScopedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMock1() { mockManager.addMock(new RequestScopedBean() { @Override public int getCount() { return 7; } }); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(7, requestScopedBean.getCount()); } @Test public void manualMock2() //same test with different mock { mockManager.addMock(new RequestScopedBean() { @Override public int getCount() { return 14; } }); Assert.assertEquals(14, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(14, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc002/MockedSessionScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc002; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedSessionScopedBeanTest { @Inject private SessionScopedBean sessionScopedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMock1() { mockManager.addMock(new SessionScopedBean() { @Override public int getCount() { return 7; } }); Assert.assertEquals(7, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(7, sessionScopedBean.getCount()); } @Test public void manualMock2() //same test with different mock { mockManager.addMock(new SessionScopedBean() { @Override public int getCount() { return 14; } }); Assert.assertEquals(14, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(14, sessionScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc003/MockedSessionScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc003; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class MockedSessionScopedBean extends SessionScopedBean { public void setCount(int count) { this.count = count; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc003/MockedSessionScopedBeanAcrossMethodsTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc003; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(startScopes = {ApplicationScoped.class, SessionScoped.class}) public class MockedSessionScopedBeanAcrossMethodsTest { @Inject private SessionScopedBean sessionScopedBean; @Inject private DynamicMockManager mockManager; //static is needed here, because the session spans across all test-methods private static MockedSessionScopedBean mockedSessionScopedBean = new MockedSessionScopedBean(); @Before public void init() { mockManager.addMock(mockedSessionScopedBean); } @Test public void manualMock1() { mockedSessionScopedBean.setCount(7); Assert.assertEquals(7, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(8, sessionScopedBean.getCount()); } @Test public void manualMock2() { mockedSessionScopedBean.setCount(14); Assert.assertEquals(14, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(15, sessionScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc004/MockedApplicationScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc004; import org.apache.deltaspike.test.testcontrol.mock.shared.ApplicationScopedBean; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class MockedApplicationScopedBean extends ApplicationScopedBean { @Override public int getCount() { return 14; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc004/MockedApplicationScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc004; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.ApplicationScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.ApplicationMockManager; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedApplicationScopedBeanTest { @Inject private ApplicationScopedBean applicationScopedBean; //e.g. application-scoped beans are cached very early -> usage of ApplicationMockManager to register mocks for them @BeforeClass public static void init() { ApplicationMockManager applicationMockManager = BeanProvider.getContextualReference(ApplicationMockManager.class); applicationMockManager.addMock(new MockedApplicationScopedBean()); } @Test public void manualMock1() { Assert.assertEquals(14, applicationScopedBean.getCount()); applicationScopedBean.increaseCount(); Assert.assertEquals(14, applicationScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc005/MockedProducedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc005; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedProducedBeanTest { @Inject private ProducedBean producedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMockForProducedBean1() { mockManager.addMock(new ProducedBean() { @Override public int getCount() { return 7; } }); Assert.assertEquals(7, producedBean.getCount()); producedBean.increaseCount(); Assert.assertEquals(7, producedBean.getCount()); } @Test public void manualMockForProducedBean2() { mockManager.addMock(new ProducedBean() { @Override public int getCount() { return 14; } }); Assert.assertEquals(14, producedBean.getCount()); producedBean.increaseCount(); Assert.assertEquals(14, producedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc005/ProducedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc005; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class ProducedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc005/ProducedBeanProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc005; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class ProducedBeanProducer { @Produces @RequestScoped public ProducedBean produceBean() { return new ProducedBean(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc006/MockedRequestScopedQualifiedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc006; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.MyQualifier; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedRequestScopedQualifiedBeanTest { @Inject @MyQualifier private QualifiedBean qualifiedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMockWithQualifier() { mockManager.addMock(new QualifiedBean() { @Override public int getCount() { return 7; } }, AnnotationInstanceProvider.of(MyQualifier.class)); Assert.assertEquals(7, qualifiedBean.getCount()); qualifiedBean.increaseCount(); Assert.assertEquals(7, qualifiedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc006/QualifiedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc006; import org.apache.deltaspike.test.testcontrol.mock.shared.MyQualifier; import jakarta.enterprise.context.RequestScoped; @RequestScoped @MyQualifier public class QualifiedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc007/MockedProducedQualifiedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc007; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.MyQualifier; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedProducedQualifiedBeanTest { @Inject @MyQualifier private ProducedBean producedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMockWithQualifierForProducedBean1() { mockManager.addMock(new ProducedBean() { @Override public int getCount() { return 7; } }, AnnotationInstanceProvider.of(MyQualifier.class)); Assert.assertEquals(7, producedBean.getCount()); producedBean.increaseCount(); Assert.assertEquals(7, producedBean.getCount()); } @Test public void manualMockWithQualifierForProducedBean2() { mockManager.addMock(new ProducedBean() { @Override public int getCount() { return 14; } }, AnnotationInstanceProvider.of(MyQualifier.class)); Assert.assertEquals(14, producedBean.getCount()); producedBean.increaseCount(); Assert.assertEquals(14, producedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc007/ProducedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc007; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class ProducedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc007/ProducedBeanProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc007; import org.apache.deltaspike.test.testcontrol.mock.shared.MyQualifier; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class ProducedBeanProducer { @Produces @RequestScoped @MyQualifier public ProducedBean produceBean() { return new ProducedBean(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/MockedTypedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol.api.mock.TypedMock; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedTypedBeanTest { @Inject private T1 t1; @Inject private T2 t2; @Inject private T3 t3; @Inject private DynamicMockManager mockManager; @Test public void manualMockForTypedBeans() { mockManager.addMock(new MockedTypedBean1and2(7)); mockManager.addMock(new MockedTypedBean3(14)); Assert.assertEquals(7, t1.getCount()); Assert.assertEquals(7, t2.getCount()); Assert.assertEquals(14, t3.getCount()); } @Typed() //exclude it for the cdi type-check private static class MockedTypedBean1and2 extends TypedBean1and2 { private final int mockedCount; private MockedTypedBean1and2(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } @Typed() //exclude it for the cdi type-check @TypedMock(T3.class) //optional - only needed in case of producers private static class MockedTypedBean3 extends TypedBean3 { private final int mockedCount; private MockedTypedBean3(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/T1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; public interface T1 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/T2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; public interface T2 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/T3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; public interface T3 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/TypedBean1and2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Vetoed; @RequestScoped @Typed({T1.class, T2.class}) public class TypedBean1and2 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc008/TypedBean3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc008; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Vetoed; @RequestScoped @Typed({T3.class}) public class TypedBean3 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/MockedTypedProducedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedTypedProducedBeanTest { @Inject private T1 t1; @Inject private T2 t2; @Inject private T3 t3; @Inject private DynamicMockManager mockManager; @Test public void manualMockT1() { mockManager.addMock(new MockedTypedBean1and2(7)); mockManager.addMock(new MockedTypedBean3(14)); Assert.assertEquals(7, t1.getCount()); Assert.assertEquals(7, t2.getCount()); Assert.assertEquals(14, t3.getCount()); } @Typed({T1.class, T2.class}) //fine for the cdi-container due to parametrized constructor private static class MockedTypedBean1and2 extends TypedBean1and2 { private final int mockedCount; private MockedTypedBean1and2(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } @Typed(T3.class) //fine for the cdi-container due to parametrized constructor private static class MockedTypedBean3 extends TypedBean3 { private final int mockedCount; private MockedTypedBean3(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/T1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; public interface T1 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/T2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; public interface T2 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/T3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; public interface T3 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/TypedBean1and2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean1and2 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/TypedBean3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean3 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc009/TypedBeanProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc009; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBeanProducer { @Produces @RequestScoped @Typed({T1.class, T2.class}) public TypedBean1and2 produce1and2() { return new TypedBean1and2(); } @Produces @RequestScoped @Typed(T3.class) public TypedBean3 produce3() { return new TypedBean3(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc010/MockedRequestScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc010; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.mockito.Mockito.*; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedRequestScopedBeanTest { @Inject private RequestScopedBean requestScopedBean; @Inject private DynamicMockManager mockManager; @Test public void mockitoMock1() { RequestScopedBean mockedRequestScopedBean = mock(RequestScopedBean.class); when(mockedRequestScopedBean.getCount()).thenReturn(7); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(7, requestScopedBean.getCount()); } @Test public void mockitoMock2() //same test with different mock { RequestScopedBean mockedRequestScopedBean = mock(RequestScopedBean.class); when(mockedRequestScopedBean.getCount()).thenReturn(14); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(14, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(14, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc011/MockedRequestScopedBeanWithInjection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc011; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; @Typed() //exclude it for the cdi type-check public class MockedRequestScopedBeanWithInjection extends RequestScopedBean { @Inject private SessionScopedBean sessionScopedBean; @Override public int getCount() { return sessionScopedBean.getCount(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc011/MockedRequestScopedBeanWithInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc011; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedRequestScopedBeanWithInjectionTest { @Inject private RequestScopedBean requestScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMockWithInjection() { RequestScopedBean mockedRequestScopedBean = new MockedRequestScopedBeanWithInjection(); BeanProvider.injectFields(mockedRequestScopedBean); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); //not delegated Assert.assertEquals(0, requestScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); Assert.assertEquals(1, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc012/MockedRequestScopedBeanWithInjection.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc012; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; @Typed() //exclude it for the cdi type-check public class MockedRequestScopedBeanWithInjection extends RequestScopedBean { @Inject private SessionScopedBean sessionScopedBean; @Override public int getCount() { return sessionScopedBean.getCount(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc012/MockedRequestScopedBeanWithInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc012; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.mock.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import static org.mockito.Mockito.*; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedRequestScopedBeanWithInjectionTest { @Inject private RequestScopedBean requestScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private DynamicMockManager mockManager; @Test public void mixedMocksWithInjection1() { SessionScopedBean mockedSessionScopedBean = mock(SessionScopedBean.class); when(mockedSessionScopedBean.getCount()).thenReturn(7); mockManager.addMock(mockedSessionScopedBean); RequestScopedBean mockedRequestScopedBean = new MockedRequestScopedBeanWithInjection(); BeanProvider.injectFields(mockedRequestScopedBean); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); //not delegated Assert.assertEquals(7, requestScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(7, sessionScopedBean.getCount()); //still mocked Assert.assertEquals(7, requestScopedBean.getCount()); //still mocked } @Test public void mixedMocksWithInjection2() { SessionScopedBean mockedSessionScopedBean = mock(SessionScopedBean.class); when(mockedSessionScopedBean.getCount()).thenReturn(14); mockManager.addMock(mockedSessionScopedBean); RequestScopedBean mockedRequestScopedBean = new MockedRequestScopedBeanWithInjection(); BeanProvider.injectFields(mockedRequestScopedBean); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(14, requestScopedBean.getCount()); requestScopedBean.increaseCount(); //not delegated Assert.assertEquals(14, requestScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(14, sessionScopedBean.getCount()); //still mocked Assert.assertEquals(14, requestScopedBean.getCount()); //still mocked } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/MockedTypedProducedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol.api.mock.TypedMock; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedTypedProducedBeanTest { @Inject private T1 t1; @Inject private T2 t2; @Inject private T3 t3; @Inject private DynamicMockManager mockManager; @Test public void manualMockT1() { mockManager.addMock(new MockedTypedBean1and2(7)); mockManager.addMock(new MockedTypedBean3(14)); Assert.assertEquals(7, t1.getCount()); Assert.assertEquals(7, t2.getCount()); Assert.assertEquals(14, t3.getCount()); } @TypedMock({T1.class, T2.class}) //specify the types for mocking (to replace the producer) private static class MockedTypedBean1and2 extends TypedBean1and2 { private final int mockedCount; private MockedTypedBean1and2(int mockedCount) //-> no @Typed() needed { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } //exclude it for the cdi type-check @TypedMock(T3.class) private static class MockedTypedBean3 extends TypedBean3 { private final int mockedCount; private MockedTypedBean3(int mockedCount) //-> no @Typed() needed { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/T1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; public interface T1 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/T2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; public interface T2 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/T3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; public interface T3 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/TypedBean1and2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean1and2 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/TypedBean3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean3 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc013/TypedBeanProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc013; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBeanProducer { @Produces @RequestScoped @Typed({T1.class, T2.class}) public TypedBean1and2 produce1and2() { return new TypedBean1and2(); } @Produces @RequestScoped @Typed(T3.class) public TypedBean3 produce3() { return new TypedBean3(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/MockedTypedProducedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol.api.mock.TypedMock; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.enterprise.inject.Vetoed; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class MockedTypedProducedBeanTest { @Inject private T1 t1; @Inject private T2 t2; @Inject private T3 t3; @Inject private DynamicMockManager mockManager; @Test public void manualMockT1() { MockedTypedBean1and2 mockedTypedBean1and2 = new MockedTypedBean1and2(); mockedTypedBean1and2.setMockedCount(7); mockManager.addMock(mockedTypedBean1and2); MockedTypedBean3 mockedTypedBean3 = new MockedTypedBean3(); mockedTypedBean3.setMockedCount(14); mockManager.addMock(mockedTypedBean3); Assert.assertEquals(7, t1.getCount()); Assert.assertEquals(7, t2.getCount()); Assert.assertEquals(14, t3.getCount()); } @Typed() //exclude it for the cdi type-check @TypedMock({T1.class, T2.class}) //specify the types for mocking (to replace the producer) private static class MockedTypedBean1and2 extends TypedBean1and2 { private int mockedCount; private void setMockedCount(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } @Typed() //exclude it for the cdi type-check @TypedMock(T3.class) private static class MockedTypedBean3 extends TypedBean3 { private int mockedCount; private void setMockedCount(int mockedCount) { this.mockedCount = mockedCount; } @Override public int getCount() { return mockedCount; } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/T1.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; public interface T1 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/T2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; public interface T2 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/T3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; public interface T3 { int getCount(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/TypedBean1and2.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean1and2 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/TypedBean3.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBean3 implements T1, T2, T3 { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc014/TypedBeanProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc014; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.Vetoed; @Typed() //exclude it for the cdi type-check public class TypedBeanProducer { @Produces @RequestScoped @Typed({T1.class, T2.class}) public TypedBean1and2 produce1and2() { return new TypedBean1and2(); } @Produces @RequestScoped @Typed(T3.class) public TypedBean3 produce3() { return new TypedBean3(); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc016/CustomMockManagerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc016; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.CustomMockManager; import org.apache.deltaspike.test.testcontrol.mock.shared.RequestScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) //same base logic as uc001 + a manual check of CustomMockManager public class CustomMockManagerTest { @Inject private RequestScopedBean requestScopedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMock1() { CustomMockManager.resetInternals(); mockManager.addMock(new RequestScopedBean() { @Override public int getCount() { return 7; } }); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(7, requestScopedBean.getCount()); Assert.assertTrue(CustomMockManager.isIsCalled()); } @Test public void manualMock2() //same test with different mock { CustomMockManager.resetInternals(); mockManager.addMock(new RequestScopedBean() { @Override public int getCount() { return 14; } }); Assert.assertEquals(14, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(14, requestScopedBean.getCount()); Assert.assertTrue(CustomMockManager.isIsCalled()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc005/MockedJsfContainerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc005; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; import jakarta.faces.render.RenderKitFactory; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(startExternalContainers = true) public class MockedJsfContainerTest { @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); Assert.assertNotNull(FacesContext.getCurrentInstance().getViewRoot()); Assert.assertEquals("/viewId", FacesContext.getCurrentInstance().getViewRoot().getViewId()); UIViewRoot uiViewRoot = new UIViewRoot(); uiViewRoot.setViewId("/test1.xhtml"); uiViewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertEquals("/test1.xhtml", FacesContext.getCurrentInstance().getViewRoot().getViewId()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExternalContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getApplication()); Assert.assertNotNull(FacesContext.getCurrentInstance().getELContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getPartialViewContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getRenderKit()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExceptionHandler()); Assert.assertNull(FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "1"); Assert.assertEquals("1", FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); } @Test public void secondTest() { Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); Assert.assertNotNull(FacesContext.getCurrentInstance().getViewRoot()); Assert.assertEquals("/viewId", FacesContext.getCurrentInstance().getViewRoot().getViewId()); UIViewRoot uiViewRoot = new UIViewRoot(); uiViewRoot.setViewId("/test2.xhtml"); uiViewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertEquals("/test2.xhtml", FacesContext.getCurrentInstance().getViewRoot().getViewId()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExternalContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getApplication()); Assert.assertNotNull(FacesContext.getCurrentInstance().getELContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getPartialViewContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getRenderKit()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExceptionHandler()); Assert.assertNull(FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "2"); Assert.assertEquals("2", FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc006/SkipExternalContainerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc006; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.faces.context.FacesContext; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(startExternalContainers = false) public class SkipExternalContainerTest { @Test public void skippedSetupTest() { Assert.assertNull(FacesContext.getCurrentInstance()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc009/JsfContainerTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc009; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.faces.component.UIViewRoot; import jakarta.faces.context.FacesContext; import jakarta.faces.render.RenderKitFactory; import jakarta.inject.Inject; import java.util.Map; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(startExternalContainers = true) public class JsfContainerTest { private Integer identityHashCode; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); UIViewRoot uiViewRoot = new UIViewRoot(); uiViewRoot.setViewId("/viewId"); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertNotNull(FacesContext.getCurrentInstance().getViewRoot()); Assert.assertEquals("/viewId", FacesContext.getCurrentInstance().getViewRoot().getViewId()); uiViewRoot.setViewId("/test1.xhtml"); uiViewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertEquals("/test1.xhtml", FacesContext.getCurrentInstance().getViewRoot().getViewId()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExternalContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getApplication()); Assert.assertNotNull(FacesContext.getCurrentInstance().getELContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getPartialViewContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getRenderKit()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExceptionHandler()); Assert.assertNull(FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "1"); Assert.assertEquals("1", FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap(); if (identityHashCode == null) { identityHashCode = System.identityHashCode(applicationMap); } else { Assert.assertSame(identityHashCode, System.identityHashCode(applicationMap)); } } @Test public void secondTest() { Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); UIViewRoot uiViewRoot = new UIViewRoot(); uiViewRoot.setViewId("/viewId"); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertNotNull(FacesContext.getCurrentInstance().getViewRoot()); Assert.assertEquals("/viewId", FacesContext.getCurrentInstance().getViewRoot().getViewId()); uiViewRoot.setViewId("/test2.xhtml"); uiViewRoot.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); FacesContext.getCurrentInstance().setViewRoot(uiViewRoot); Assert.assertEquals("/test2.xhtml", FacesContext.getCurrentInstance().getViewRoot().getViewId()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExternalContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getApplication()); Assert.assertNotNull(FacesContext.getCurrentInstance().getELContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getPartialViewContext()); Assert.assertNotNull(FacesContext.getCurrentInstance().getRenderKit()); Assert.assertNotNull(FacesContext.getCurrentInstance().getExceptionHandler()); Assert.assertNull(FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("test", "2"); Assert.assertEquals("2", FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("test")); Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap(); if (identityHashCode == null) { identityHashCode = System.identityHashCode(applicationMap); } else { Assert.assertSame(identityHashCode, System.identityHashCode(applicationMap)); } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc010/JsfContainerPerTestMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc010; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.faces.context.FacesContext; import java.util.Map; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class JsfContainerPerTestMethodTest { private Integer identityHashCode; @Test public void firstTest() { Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap(); if (identityHashCode == null) { identityHashCode = System.identityHashCode(applicationMap); } else { Assert.assertNotSame(identityHashCode, System.identityHashCode(applicationMap)); } } @Test public void secondTest() { Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap(); if (identityHashCode == null) { identityHashCode = System.identityHashCode(applicationMap); } else { Assert.assertNotSame(identityHashCode, System.identityHashCode(applicationMap)); } } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/DefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultTestService implements TestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestLabelX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import org.apache.deltaspike.testcontrol.api.TestControl; public class TestLabelX implements TestControl.Label { } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestServiceLabelX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @ApplicationScoped public class TestServiceLabelX implements TestService { @Override public String getValue() { return "result-x"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestServiceLabelY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @ApplicationScoped public class TestServiceLabelY implements TestService { @Override public String getValue() { return "result-y"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestServiceLabelYTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(activeAlternativeLabel = TestServiceLabelYTest.Y.class) public class TestServiceLabelYTest { @Inject private TestService testService; @Test public void resultY() { Assert.assertEquals("result-y", testService.getValue()); } class Y implements TestControl.Label { } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestServiceNoLabelTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class TestServiceNoLabelTest { @Inject private TestService testService; @Test public void noLabel() { Assert.assertEquals("default-result", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc014/TestServiceTestLabelXTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc014; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(activeAlternativeLabel = TestLabelX.class) public class TestServiceTestLabelXTest { @Inject private TestService testService; @Test public void resultX() { Assert.assertEquals("result-x", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc015/AlternativeServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc015; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class AlternativeServiceTest { @Inject private TestService testService; @Test public void defaultValue() { Assert.assertEquals("alternative-result", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc015/DefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc015; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultTestService implements TestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc015/LabeledServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc015; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; import jakarta.inject.Named; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(activeAlternativeLabel = LabeledServiceTest.Label.class) public class LabeledServiceTest { @Inject private TestService testService; @Test public void resultLbl() { Assert.assertEquals("result-lbl", testService.getValue()); } @Named("lbl") class Label implements TestControl.Label { } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc015/LabeledTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc015; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @ApplicationScoped public class LabeledTestService implements TestService { @Override public String getValue() { return "result-lbl"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc015/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc015; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/DefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultTestService implements TestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestLabel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @TestQualifierBinding @Retention(RUNTIME) @Target(TYPE) public @interface TestLabel { Type value(); enum Type { X, Y } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestQualifierBinding.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface TestQualifierBinding { } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestServiceLabelX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabel(TestLabel.Type.X) @ApplicationScoped public class TestServiceLabelX implements TestService { @Override public String getValue() { return "result-x"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestServiceLabelXTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestLabel(TestLabel.Type.X) public class TestServiceLabelXTest { @Inject private TestService testService; @Test public void resultX() { Assert.assertEquals("result-x", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestServiceLabelY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabel(TestLabel.Type.Y) @ApplicationScoped public class TestServiceLabelY implements TestService { @Override public String getValue() { return "result-y"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc016/TestServiceLabelYTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc016; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestLabel(TestLabel.Type.Y) public class TestServiceLabelYTest { @Inject private TestService testService; @Test public void resultY() { Assert.assertEquals("result-y", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc017/DefaultServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc017; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class DefaultServiceTest { @Inject private TestService testService; @Test public void defaultValue() { Assert.assertEquals("default-result", testService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc017/DefaultTestServiceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc017; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Produces; @ApplicationScoped public class DefaultTestServiceProducer { @Produces @ApplicationScoped protected TestService testService() { return new TestService() { @Override public String getValue() { return "default-result"; } }; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc017/LabeledServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc017; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(activeAlternativeLabel = LabeledServiceTest.Label.class) public class LabeledServiceTest { @Inject private TestService testService; @Test public void labeledValue() { Assert.assertEquals("labeled-result", testService.getValue()); } class Label implements TestControl.Label { } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc017/LabeledTestServiceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc017; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.Produces; @Alternative public class LabeledTestServiceProducer extends DefaultTestServiceProducer { @Produces @ApplicationScoped protected TestService testService() { return new TestService() { @Override public String getValue() { return "labeled-result"; } }; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc017/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc017; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/DefaultServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class DefaultServiceTest { @Inject private InterceptedTestService interceptedTestService; @Test public void defaultValue() { Assert.assertEquals("DEFAULT-RESULT", interceptedTestService.getValue()); } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/DefaultTestServiceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import static org.apache.deltaspike.test.testcontrol.uc018.TestServiceQualifier.Mode.DEFAULT; @ApplicationScoped public class DefaultTestServiceProducer implements InterceptedTestServiceProducer { @Produces @Default //optional @Dependent public InterceptedTestService createInterceptedTestService(@TestServiceQualifier(DEFAULT) InterceptedTestService interceptedTestService) { return interceptedTestService; //the exposed result is an intercepted instance } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/InterceptedDefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.enterprise.context.ApplicationScoped; import static org.apache.deltaspike.test.testcontrol.uc018.TestServiceQualifier.Mode.DEFAULT; @ApplicationScoped @TestUpperCaseInterceptor @TestServiceQualifier(DEFAULT) public class InterceptedDefaultTestService implements InterceptedTestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/InterceptedLabeledTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.enterprise.context.ApplicationScoped; import static org.apache.deltaspike.test.testcontrol.uc018.TestServiceQualifier.Mode.LABELED; @ApplicationScoped @TestUpperCaseInterceptor @TestServiceQualifier(LABELED) public class InterceptedLabeledTestService implements InterceptedTestService { @Override public String getValue() { return "labeled-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/InterceptedTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; public interface InterceptedTestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/InterceptedTestServiceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; public interface InterceptedTestServiceProducer { InterceptedTestService createInterceptedTestService(InterceptedTestService interceptedTestService); } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/LabeledServiceTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(activeAlternativeLabel = LabeledServiceTest.Label.class) public class LabeledServiceTest { @Inject private InterceptedTestService interceptedTestService; @Test public void labeledValue() { Assert.assertEquals("LABELED-RESULT", interceptedTestService.getValue()); } class Label implements TestControl.Label { } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/LabeledTestServiceProducer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Alternative; import jakarta.enterprise.inject.Default; import jakarta.enterprise.inject.Produces; import static org.apache.deltaspike.test.testcontrol.uc018.TestServiceQualifier.Mode.LABELED; @Alternative @ApplicationScoped public class LabeledTestServiceProducer implements InterceptedTestServiceProducer { @Produces @Default //optional @Dependent public InterceptedTestService createInterceptedTestService(@TestServiceQualifier(LABELED) InterceptedTestService interceptedTestService) { return interceptedTestService; //the exposed result is an intercepted instance } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/TestServiceQualifier.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.inject.Qualifier; import java.lang.annotation.*; @Qualifier @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.PARAMETER }) public @interface TestServiceQualifier { Mode value(); enum Mode { DEFAULT, LABELED } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/TestUpperCaseInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.*; @InterceptorBinding @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) public @interface TestUpperCaseInterceptor { } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/java/org/apache/deltaspike/test/testcontrol/uc018/TestUpperCaseInterceptorImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc018; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @TestUpperCaseInterceptor @Interceptor public class TestUpperCaseInterceptorImplementation implements Serializable { @AroundInvoke public Object executeInTransaction(InvocationContext invocationContext) throws Exception { Object result = invocationContext.proceed(); if (result instanceof String) { return ((String) result).toUpperCase(); } return result; } } ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.ExternalContainer ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.testcontrol.InternalMyFacesTestContainerAdapter ================================================ FILE: deltaspike/modules/test-control/impl/obsolete/src/test/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.junit.TestStatementDecoratorFactory ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #optional - just added to test possible side-effects org.apache.deltaspike.testcontrol.impl.transaction.TransactionStatementDecoratorFactory ================================================ FILE: deltaspike/modules/test-control/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules test-control-module-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.modules deltaspike-test-control-module-impl jar Apache DeltaSpike Test-Control-Module Impl org.apache.deltaspike.testcontrol.impl.* !org.apache.deltaspike.testcontrol.impl.*, * org.apache.deltaspike.modules deltaspike-test-control-module-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided org.apache.geronimo.specs geronimo-jpa_2.2_spec true junit junit provided jakarta.el jakarta.el-api provided org.apache.tomcat tomcat-servlet-api provided org.mockito mockito-all org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime OWB true org.apache.openwebbeans openwebbeans-impl test org.apache.openwebbeans openwebbeans-spi test org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} test Weld org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} test ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/AbstractMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol.api.junit.TestBaseConfig; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol.api.mock.TypedMock; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; public abstract class AbstractMockManager implements DynamicMockManager { private Map registeredMocks = new HashMap(); @Override public void addMock(Object mockInstance, Annotation... qualifiers) { //check if this method gets used without changing the default-config if (!TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS && !TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS) { throw new IllegalStateException("The support for mocked CDI-Beans is disabled " + "due to a reduced portability across different CDI-implementations. " + "Please set '" + TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS_KEY + "' and/or '" + TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS_KEY + "' to 'true' " + "(in 'META-INF/apache-deltaspike.properties') on your test-classpath."); } Class mockClass = mockInstance.getClass(); Class beanClass = mockClass.getSuperclass(); if (beanClass == null) { beanClass = mockClass; } if (Object.class.equals(beanClass)) { throw new IllegalArgumentException(mockInstance.getClass().getName() + " isn't a supported approach for mocking -> please extend from the original class."); } TypedMock typedMock = mockClass.getAnnotation(TypedMock.class); if (typedMock == null) { typedMock = beanClass.getAnnotation(TypedMock.class); } Class[] specifiedTypes = null; if (typedMock != null) { specifiedTypes = typedMock.value(); } else { Typed typed = mockClass.getAnnotation(Typed.class); if (typed == null || typed.value().length == 0) { typed = beanClass.getAnnotation(Typed.class); } if (typed != null && typed.value().length > 0) { specifiedTypes = typed.value(); } } if (specifiedTypes != null) { for (Class typedClass : specifiedTypes) { this.registeredMocks.put(new BeanCacheKey(typedClass, qualifiers), mockInstance); } } else { this.registeredMocks.put(new BeanCacheKey(beanClass, qualifiers), mockInstance); } } @Override public T getMock(Class beanClass, Annotation... qualifiers) { return (T)this.registeredMocks.get(new BeanCacheKey(beanClass, qualifiers)); } @Override public void reset() { this.registeredMocks.clear(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/BeanCacheKey.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import org.apache.deltaspike.core.util.ReflectionUtils; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Comparator; //class from OWB public class BeanCacheKey { private static final Comparator ANNOTATION_COMPARATOR = new AnnotationComparator(); private final Type type; private final Annotation qualifier; private final Annotation qualifiers[]; private final int hashCode; public BeanCacheKey(Type type, Annotation... qualifiers) { this.type = type; final int length = qualifiers != null ? qualifiers.length : 0; if (length == 0) { qualifier = null; this.qualifiers = null; } else if (length == 1) { qualifier = qualifiers[0]; this.qualifiers = null; } else { qualifier = null; // to save array creations, we only create an array, if we have more than one annotation this.qualifiers = new Annotation[length]; System.arraycopy(qualifiers, 0, this.qualifiers, 0, length); Arrays.sort(this.qualifiers, ANNOTATION_COMPARATOR); } // this class is directly used in ConcurrentHashMap.get() so simply init the hasCode here hashCode = computeHashCode(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } BeanCacheKey cacheKey = (BeanCacheKey) o; if (!type.equals(cacheKey.type)) { return false; } if (qualifier != null ? !qualifierEquals(qualifier, cacheKey.qualifier) : cacheKey.qualifier != null) { return false; } if (!qualifierArrayEquals(qualifiers, cacheKey.qualifiers)) { return false; } return true; } private boolean qualifierArrayEquals(Annotation[] qualifiers1, Annotation[] qualifiers2) { if (qualifiers1 == qualifiers2) { return true; } else if (qualifiers1 == null || qualifiers2 == null) { return false; } if (qualifiers1.length != qualifiers2.length) { return false; } for (int i = 0; i < qualifiers1.length; i++) { Annotation a1 = qualifiers1[i]; Annotation a2 = qualifiers2[i]; if (a1 == null ? a2 != null : !qualifierEquals(a1, a2)) { return false; } } return true; } @Override public int hashCode() { return hashCode; } /** * Compute the HashCode. This should be called only in the constructor. */ private int computeHashCode() { int computedHashCode = 31 * ReflectionUtils.calculateHashCodeOfType(type); if (qualifier != null) { computedHashCode = 31 * computedHashCode + getQualifierHashCode(qualifier); } if (qualifiers != null) { for (int i = 0; i < qualifiers.length; i++) { computedHashCode = 31 * computedHashCode + getQualifierHashCode(qualifiers[i]); } } return computedHashCode; } /** * Calculate the hashCode() of a qualifier, which ignores {@link jakarta.enterprise.util.Nonbinding} members. */ private int getQualifierHashCode(Annotation a) { return ReflectionUtils.calculateHashCodeOfAnnotation(a, true); } /** * Implements the equals() method for qualifiers, which ignores {@link jakarta.enterprise.util.Nonbinding} members. */ private boolean qualifierEquals(Annotation qualifier1, Annotation qualifier2) { return ANNOTATION_COMPARATOR.compare(qualifier1, qualifier2) == 0; } /** * for debugging ... */ @Override public String toString() { return "BeanCacheKey{" + "type=" + type + ", qualifiers=" + (qualifiers == null ? qualifier : Arrays.asList(qualifiers)) + ", hashCode=" + hashCode + '}'; } /** * to keep the annotations ordered. */ private static class AnnotationComparator implements Comparator { // Notice: Sorting is a bit costly, but the use of this code is very rar. @Override public int compare(Annotation annotation1, Annotation annotation2) { final Class type1 = annotation1.annotationType(); final Class type2 = annotation2.annotationType(); final int temp = type1.getName().compareTo(type2.getName()); if (temp != 0) { return temp; } final Method[] member1 = type1.getDeclaredMethods(); final Method[] member2 = type2.getDeclaredMethods(); // TBD: the order of the list of members seems to be deterministic int i = 0; int j = 0; final int length1 = member1.length; final int length2 = member2.length; // find next nonbinding for (;; i++, j++) { while (i < length1 && member1[i].isAnnotationPresent(Nonbinding.class)) { i++; } while (j < length2 && member2[j].isAnnotationPresent(Nonbinding.class)) { j++; } if (i >= length1 && j >= length2) { // both ended return 0; } else if (i >= length1) { // #1 ended return 1; } else if (j >= length2) { // #2 ended return -1; } else { // not ended int c = member1[i].getName().compareTo(member2[j].getName()); if (c != 0) { return c; } final Object value1 = ReflectionUtils.invokeMethod(annotation1, member1[i], Object.class, true); final Object value2 = ReflectionUtils.invokeMethod(annotation2, member2[j], Object.class, true); assert value1.getClass().equals(value2.getClass()); if (value1 instanceof Comparable) { c = ((Comparable)value1).compareTo(value2); if (c != 0) { return c; } } else if (value1.getClass().isArray()) { c = value1.getClass().getComponentType().getName() .compareTo(value2.getClass().getComponentType().getName()); if (c != 0) { return c; } final int length = Array.getLength(value1); c = length - Array.getLength(value2); if (c != 0) { return c; } for (int k = 0; k < length; k++) { c = ((Comparable)Array.get(value1, k)).compareTo(Array.get(value2, k)); if (c != 0) { return c; } } } else if (value1 instanceof Class) { c = ((Class)value1).getName().compareTo(((Class) value2).getName()); if (c != 0) { return c; } } else { // valid types for members are only Comparable, Arrays, or Class assert false; } } } } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/DefaultMockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import org.apache.deltaspike.testcontrol.api.junit.TestBaseConfig; import org.apache.deltaspike.testcontrol.spi.mock.MockFilter; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMember; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.lang.reflect.Member; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; public class DefaultMockFilter implements MockFilter { private static final Logger LOG = Logger.getLogger(DefaultMockFilter.class.getName()); private static final String DS_BASE_PACKAGE = "org.apache.deltaspike."; private static final String JAVA_BASE_PACKAGE = "java."; private static final String JAVAX_BASE_PACKAGE = "javax."; private static final String JAKARTA_BASE_PACKAGE = "jakarta."; private static final String EJB_BASE_PACKAGE = "javax.ejb."; private static final String OWB_BASE_PACKAGE = "org.apache.webbeans."; private static final String WELD_BASE_PACKAGE = "org.jboss.weld."; @Override public boolean isMockedImplementationSupported(BeanManager beanManager, Annotated annotated) { if (!isMockSupportEnabled(annotated)) { return false; } Class origin = null; if (annotated instanceof AnnotatedType) { origin = ((AnnotatedType)annotated).getJavaClass(); Set annotations = new HashSet(); annotations.addAll(annotated.getAnnotations()); for (AnnotatedMethod annotatedMethod : (Set)((AnnotatedType) annotated).getMethods()) { annotations.addAll(annotatedMethod.getAnnotations()); } if (isEjbOrAnnotatedTypeWithInterceptorAnnotation( beanManager, annotations, origin.getName())) { return false; } } else if (annotated instanceof AnnotatedMember) { Member member = ((AnnotatedMember)annotated).getJavaMember(); origin = member.getDeclaringClass(); if (isEjbOrAnnotatedTypeWithInterceptorAnnotation( beanManager, annotated.getAnnotations(), member.toString())) { return false; } } if (origin != null && origin.getPackage() == null) { LOG.warning("Please don't use the default-package for " + origin.getName()); return true; } return origin != null && !isInternalPackage(origin.getPackage().getName()); } protected boolean isMockSupportEnabled(Annotated annotated) { if ((annotated instanceof AnnotatedMethod || annotated instanceof AnnotatedField) && annotated.getAnnotation(Produces.class) != null) { return TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS; } else { return TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS; } } protected boolean isEjbOrAnnotatedTypeWithInterceptorAnnotation(BeanManager beanManager, Set annotations, String origin) { for (Annotation annotation : annotations) { if (annotation.annotationType().getName().startsWith(EJB_BASE_PACKAGE)) { return true; } if (isStandardAnnotation(annotation)) { continue; } if (beanManager.isInterceptorBinding(annotation.annotationType()) || (beanManager.isStereotype(annotation.annotationType()) && isStereotypeWithInterceptor(annotation, beanManager))) { LOG.warning("Skip mocking intercepted bean " + origin); return true; } } return false; } protected boolean isStereotypeWithInterceptor(Annotation stereotypeAnnotation, BeanManager beanManager) { for (Annotation annotation : stereotypeAnnotation.annotationType().getAnnotations()) { if (isStandardAnnotation(annotation)) { continue; } if (beanManager.isInterceptorBinding(annotation.annotationType()) || isStereotypeWithInterceptor(annotation, beanManager)) { return true; } } return false; } protected boolean isStandardAnnotation(Annotation annotation) { return annotation.annotationType().getName().startsWith(JAVA_BASE_PACKAGE) || annotation.annotationType().getName().startsWith(JAVAX_BASE_PACKAGE) || annotation.annotationType().getName().startsWith(JAKARTA_BASE_PACKAGE); } protected boolean isInternalPackage(String packageName) { return packageName.startsWith(OWB_BASE_PACKAGE) || packageName.startsWith(WELD_BASE_PACKAGE) || isDeltaSpikePackage(packageName); } protected boolean isDeltaSpikePackage(String packageName) { return packageName.startsWith(DS_BASE_PACKAGE); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/MockAwareInjectionTargetWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.InjectionTarget; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.Set; public class MockAwareInjectionTargetWrapper implements InjectionTarget { private BeanManager beanManager; private final InjectionTarget wrapped; private final List beanTypes; private final List qualifiers; public MockAwareInjectionTargetWrapper(BeanManager beanManager, InjectionTarget wrapped, List beanTypes, List qualifiers) { this.beanManager = beanManager; this.wrapped = wrapped; this.beanTypes = beanTypes; this.qualifiers = qualifiers; } @Override public T produce(CreationalContext creationalContext) { DynamicMockManager mockManager = BeanProvider.getContextualReference(this.beanManager, DynamicMockManager.class, false); for (Type beanType : this.beanTypes) { Object mockInstance = mockManager.getMock( (Class)beanType, this.qualifiers.toArray(new Annotation[this.qualifiers.size()])); if (mockInstance != null) { return (T)mockInstance; } } return wrapped.produce(creationalContext); } /* * generated */ @Override public void inject(T instance, CreationalContext ctx) { wrapped.inject(instance, ctx); } @Override public void postConstruct(T instance) { wrapped.postConstruct(instance); } @Override public void preDestroy(T instance) { wrapped.preDestroy(instance); } @Override public void dispose(T instance) { wrapped.dispose(instance); } @Override public Set getInjectionPoints() { return wrapped.getInjectionPoints(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/MockAwareProducerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.Producer; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.Set; public class MockAwareProducerWrapper implements Producer { private final BeanManager beanManager; private final Producer wrapped; private final List beanTypes; private final List qualifiers; public MockAwareProducerWrapper(BeanManager beanManager, Producer wrapped, List beanTypes, List qualifiers) { this.beanManager = beanManager; this.wrapped = wrapped; this.beanTypes = beanTypes; this.qualifiers = qualifiers; } @Override public T produce(CreationalContext creationalContext) { DynamicMockManager mockManager = BeanProvider.getContextualReference(this.beanManager, DynamicMockManager.class, false); for (Type beanType : this.beanTypes) { Object mockInstance = mockManager.getMock( (Class)beanType, this.qualifiers.toArray(new Annotation[this.qualifiers.size()])); if (mockInstance != null) { return (T)mockInstance; } } return wrapped.produce(creationalContext); } /* * generated */ @Override public void dispose(T instance) { wrapped.dispose(instance); } @Override public Set getInjectionPoints() { return wrapped.getInjectionPoints(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/MockExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.testcontrol.spi.mock.MockFilter; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AnnotatedMember; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.InjectionTarget; import jakarta.enterprise.inject.spi.ProcessInjectionTarget; import jakarta.enterprise.inject.spi.ProcessProducer; import jakarta.enterprise.inject.spi.Producer; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MockExtension implements Extension, Deactivatable { private Boolean isActivated = true; private List mockFilters; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); mockFilters = ServiceUtils.loadServiceImplementations(MockFilter.class); } public void onProcessInjectionTarget(@Observes ProcessInjectionTarget processInjectionTarget, BeanManager beanManager) { if (!isActivated) { return; } for (MockFilter mockFilter : mockFilters) { if (!mockFilter.isMockedImplementationSupported(beanManager, processInjectionTarget.getAnnotatedType())) { return; } } List qualifiers = new ArrayList(); for (Annotation annotation : processInjectionTarget.getAnnotatedType().getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } Typed typed = processInjectionTarget.getAnnotatedType().getAnnotation(Typed.class); List foundTypes = new ArrayList<>(); if (typed != null) { Collections.addAll(foundTypes, typed.value()); } else { foundTypes.addAll(extractTypes(processInjectionTarget.getAnnotatedType().getJavaClass())); } if (foundTypes.isEmpty()) { return; } final InjectionTarget originalInjectionTarget = processInjectionTarget.getInjectionTarget(); processInjectionTarget.setInjectionTarget(new MockAwareInjectionTargetWrapper( beanManager, originalInjectionTarget, foundTypes, qualifiers)); } public void onProcessProducer(@Observes ProcessProducer processProducer, BeanManager beanManager) { if (!isActivated) { return; } for (MockFilter mockFilter : mockFilters) { if (!mockFilter.isMockedImplementationSupported(beanManager, processProducer.getAnnotatedMember())) { return; } } final Producer originalProducer = processProducer.getProducer(); AnnotatedMember annotatedMember = processProducer.getAnnotatedMember(); List qualifiers = new ArrayList(); for (Annotation annotation : annotatedMember.getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } Typed typed = annotatedMember.getAnnotation(Typed.class); List foundTypes = new ArrayList(); if (typed != null) { Collections.addAll(foundTypes, typed.value()); } else if (annotatedMember.getBaseType() instanceof Class) { foundTypes.addAll(extractTypes((Class)annotatedMember.getBaseType())); } if (foundTypes.isEmpty()) { return; } processProducer.setProducer(new MockAwareProducerWrapper( beanManager, originalProducer, foundTypes, qualifiers)); } //logic from org.apache.deltaspike.core.util.bean.BeanBuilder protected List extractTypes(Class currentClass) { List result = new ArrayList(); for (Class c = currentClass; c != Object.class && c != null; c = c.getSuperclass()) { result.add(c); } Collections.addAll(result, currentClass.getInterfaces()); return result; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/SimpleApplicationMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol.api.mock.ApplicationMockManager; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @Typed(ApplicationMockManager.class) public class SimpleApplicationMockManager extends AbstractMockManager implements ApplicationMockManager { } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/mock/SimpleMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol.api.mock.ApplicationMockManager; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import java.lang.annotation.Annotation; @RequestScoped @Typed(DynamicMockManager.class) public class SimpleMockManager extends AbstractMockManager { @Inject private ApplicationMockManager applicationMockManager; @Override public T getMock(Class beanClass, Annotation... qualifiers) { T result = applicationMockManager.getMock(beanClass, qualifiers); if (result != null) { return result; } return super.getMock(beanClass, qualifiers); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/request/ContextControlDecorator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.request; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.spi.ExternalContainer; import jakarta.decorator.Decorator; import jakarta.decorator.Delegate; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import jakarta.inject.Singleton; import java.lang.annotation.Annotation; /** * Needed to allow the manual usage of * ContextControl#stopContext(RequestScoped.class) * and * ContextControl#startContext(RequestScoped.class) * within a test-method. * That can be useful in combination with the integration of myfaces-test for page-bean tests. */ @Decorator //don't use an abstract decorator to keep the compatibility with old version of owb/weld public class ContextControlDecorator implements ContextControl { @Inject @Delegate private ContextControl wrapped; @Override public void startContexts() { wrapped.startContexts(); if (isManualScopeHandling()) { for (ExternalContainer externalContainer : CdiTestRunner.getActiveExternalContainers()) { externalContainer.startScope(Singleton.class); externalContainer.startScope(ApplicationScoped.class); externalContainer.startScope(RequestScoped.class); externalContainer.startScope(SessionScoped.class); externalContainer.startScope(ConversationScoped.class); } } } @Override public void stopContexts() { if (isManualScopeHandling()) { for (ExternalContainer externalContainer : CdiTestRunner.getActiveExternalContainers()) { externalContainer.stopScope(ConversationScoped.class); externalContainer.stopScope(SessionScoped.class); externalContainer.stopScope(RequestScoped.class); externalContainer.stopScope(ApplicationScoped.class); externalContainer.stopScope(Singleton.class); } } wrapped.stopContexts(); } @Override public void startContext(Class scopeClass) { wrapped.startContext(scopeClass); if (isManuallyHandledRequest(scopeClass)) { for (ExternalContainer externalContainer : CdiTestRunner.getActiveExternalContainers()) { externalContainer.startScope(scopeClass); } } } @Override public void stopContext(Class scopeClass) { wrapped.stopContext(scopeClass); if (isManuallyHandledRequest(scopeClass)) { for (ExternalContainer externalContainer : CdiTestRunner.getActiveExternalContainers()) { externalContainer.stopScope(scopeClass); } } } private boolean isManuallyHandledRequest(Class scopeClass) { return RequestScoped.class.equals(scopeClass) && isManualScopeHandling(); } private boolean isManualScopeHandling() { return !Boolean.TRUE.equals(CdiTestRunner.isAutomaticScopeHandlingActive()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/java/org/apache/deltaspike/testcontrol/impl/validation/StandardContextTestControlValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol.impl.validation; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.spi.TestAware; import org.apache.deltaspike.testcontrol.spi.TestControlValidator; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; @Vetoed public class StandardContextTestControlValidator implements TestAware, TestControlValidator { private static Boolean customContextControlDetected; private static ThreadLocal currentTestClass = new ThreadLocal(); private static ThreadLocal currentTestMethod = new ThreadLocal(); @Override public void validate(TestControl testControl) { checkActiveContextControlImplementation(); List> scopeClasses = new ArrayList>(); Collections.addAll(scopeClasses, testControl.startScopes()); validateSupportedScopes(scopeClasses, currentTestClass.get(), currentTestMethod.get()); } private void checkActiveContextControlImplementation() { if (customContextControlDetected != null) { return; } customContextControlDetected = !CdiContainerLoader.getCdiContainer().getContextControl() .getClass().getName().startsWith("org.apache.deltaspike."); } private void validateSupportedScopes(List> scopeClasses, Class declaringClass, Method testMethod) { //skip validation in case of a custom context-control implementation (it might support more scopes) if (Boolean.TRUE.equals(customContextControlDetected)) { return; } for (Class scopeClass : scopeClasses) { if (!scopeClass.getName().startsWith("jakarta.enterprise.context.")) { throw new IllegalStateException("Please remove " + scopeClass.getName() + " at " + declaringClass + (testMethod != null ? "#" + testMethod.getName() : "") + " from @" + TestControl.class.getName() + ". @" + TestControl.class.getName() + " only supports standard Scope-Annotations provided by the CDI-Specification. " + "Other Contexts start automatically or need to get started with a specific Management-API. " + "Examples: " + "@TransactionScoped gets started automatically once the @Transactional-Interceptor is used. " + "Whereas @WindowScoped starts once WindowContext#activateWindow gets called."); } } } @Override public void setTestClass(Class testClass) { currentTestClass.set(testClass); if (testClass == null) { currentTestClass.remove(); } } @Override public void setTestMethod(Method testMethod) { currentTestMethod.set(testMethod); if (testMethod == null) { currentTestMethod.remove(); } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/main/resources/META-INF/apache-deltaspike_test-container.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) ================================================ FILE: deltaspike/modules/test-control/impl/src/main/resources/META-INF/beans.xml ================================================ org.apache.deltaspike.testcontrol.impl.request.ContextControlDecorator ================================================ FILE: deltaspike/modules/test-control/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol.impl.mock.MockExtension ================================================ FILE: deltaspike/modules/test-control/impl/src/main/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.TestControlValidator ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol.impl.validation.StandardContextTestControlValidator ================================================ FILE: deltaspike/modules/test-control/impl/src/main/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.mock.MockFilter ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol.impl.mock.DefaultMockFilter ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/CustomMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol.impl.mock.SimpleMockManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Alternative; import java.lang.annotation.Annotation; @Alternative @RequestScoped @Typed(DynamicMockManager.class) public class CustomMockManager extends SimpleMockManager { private static boolean isCalled; @Override public T getMock(Class beanClass, Annotation... qualifiers) { isCalled = true; return super.getMock(beanClass, qualifiers); } public static boolean isIsCalled() { return isCalled; } public static void resetInternals() { isCalled = false; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/InternalTestClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.testcontrol.impl.mock.DefaultMockFilter; //just needed because the internal test-packages need to be handled differently public class InternalTestClassDeactivator implements ClassDeactivator { @Override public Boolean isActivated(Class targetClass) { return !DefaultMockFilter.class.equals(targetClass); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/InternalTestMockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol; import org.apache.deltaspike.testcontrol.impl.mock.DefaultMockFilter; public class InternalTestMockFilter extends DefaultMockFilter { private static final String DS_TEST_BASE_PACKAGE = "org.apache.deltaspike.test.testcontrol.mock."; protected boolean isInternalPackage(String packageName) { return super.isInternalPackage(packageName) && (!packageName.startsWith(DS_TEST_BASE_PACKAGE) || packageName.equals(CustomMockManager.class.getPackage().getName())); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/InterceptedBeanClassLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped @TestInterceptor public class InterceptedBeanClassLevel { public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/InterceptedBeanMethodLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptedBeanMethodLevel { @TestInterceptor public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/InterceptedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class InterceptedBeanTest { @Inject private InterceptionResultStorage interceptionResultStorage; @Inject private InterceptedBeanClassLevel interceptedBeanClassLevel; @Inject private InterceptedBeanMethodLevel interceptedBeanMethodLevel; @Test public void classLevelInterception() { Assert.assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanClassLevel.test(); Assert.assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } @Test public void methodLevelInterception() { Assert.assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanMethodLevel.test(); Assert.assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/InterceptionResultStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptionResultStorage { private boolean intercepted; public void markAsIntercepted() { this.intercepted = true; } public boolean isInterceptionDetected() { return intercepted; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/TestInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @InterceptorBinding @Target({ METHOD, TYPE }) @Retention(RUNTIME) public @interface TestInterceptor { } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/mock/uc015/TestInterceptorImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.mock.uc015; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @TestInterceptor @Interceptor public class TestInterceptorImplementation implements Serializable { @Inject private InterceptionResultStorage interceptionResultStorage; @AroundInvoke public Object intercept(InvocationContext ctx) throws Exception { this.interceptionResultStorage.markAsIntercepted(); return ctx.proceed(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/shared/ApplicationScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.shared; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationScopedBean { private int count = 0; private static int instanceCount = 0; @PostConstruct protected void init() { instanceCount++; } public int getCount() { return count; } public void increaseCount() { this.count++; } public void resetCount() { this.count = 0; } public static int getInstanceCount() { return instanceCount; } public static void resetInstanceCount() { instanceCount = 0; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/shared/RequestScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.shared; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class RequestScopedBean { private int count = 0; private static int instanceCount = 0; @PostConstruct protected void init() { instanceCount++; } public int getCount() { return count; } public void increaseCount() { this.count++; } public static int getInstanceCount() { return instanceCount; } public static int resetInstanceCount() { return instanceCount = 0; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/shared/SessionScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.shared; import jakarta.enterprise.context.SessionScoped; import java.io.Serializable; @SessionScoped public class SessionScopedBean implements Serializable { private static final long serialVersionUID = -6055362670706159152L; private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/shared/TestUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.shared; import org.junit.Test; import java.lang.reflect.Method; public abstract class TestUtils { private TestUtils() { } public static int getTestMethodCount(Class testClass) { int result = 0; for (Method method : testClass.getDeclaredMethods()) { if (method.isAnnotationPresent(Test.class)) { result++; } } return result; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc001/RequestAndSessionScopePerTestMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc001; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import org.apache.deltaspike.test.testcontrol.shared.TestUtils; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) //starts container once and one session + request per test-method //implicitly annotated with @TestControl without the default-scope settings public class RequestAndSessionScopePerTestMethodTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test //implicitly annotated with @TestControl and its default-values public void firstTest() { applicationScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); } @Test //implicitly annotated with @TestControl and its default-values public void secondTest() { applicationScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); } @BeforeClass public static void resetSharedState() { BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); RequestScopedBean.resetInstanceCount(); } @AfterClass public static void finalCheckAndCleanup() { int testCount = TestUtils.getTestMethodCount(RequestAndSessionScopePerTestMethodTest.class); if (RequestScopedBean.getInstanceCount() != testCount) { throw new IllegalStateException("unexpected instance count"); } RequestScopedBean.resetInstanceCount(); if (BeanProvider.getContextualReference(ApplicationScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc002/SessionScopePerTestClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc002; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import org.apache.deltaspike.test.testcontrol.shared.TestUtils; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) //starts container and session once and one request per test-method @TestControl(startScopes = SessionScoped.class) public class SessionScopePerTestClassTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); } @Test public void secondTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); } @BeforeClass public static void resetSharedState() { BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); RequestScopedBean.resetInstanceCount(); } @AfterClass public static void finalCheckAndCleanup() { int testCount = TestUtils.getTestMethodCount(SessionScopePerTestClassTest.class); if (RequestScopedBean.getInstanceCount() != testCount) { throw new IllegalStateException("unexpected instance count"); } RequestScopedBean.resetInstanceCount(); if (BeanProvider.getContextualReference(ApplicationScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } if (BeanProvider.getContextualReference(SessionScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc003/RequestAndSessionScopePerTestMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc003; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) //starts container once and one session + request per test-method //implicitly annotated with @TestControl without the default-scope settings public class RequestAndSessionScopePerTestMethodTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test //implicitly annotated with @TestControl and its default-values public void firstTest() { applicationScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); } @Test //implicitly annotated with @TestControl and its default-values public void secondTest() { applicationScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); Assert.assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); Assert.assertEquals(1, sessionScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc003/SessionScopePerTestClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc003; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) //starts container and session once and one request per test-method @TestControl(startScopes = SessionScoped.class) public class SessionScopePerTestClassTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); } @Test public void secondTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc003/TestSuite.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc003; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestSuiteRunner; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestSuiteRunner.class) //starts container once (for the whole suite) @Suite.SuiteClasses({ RequestAndSessionScopePerTestMethodTest.class, SessionScopePerTestClassTest.class }) public class TestSuite { @BeforeClass public static void resetSharedState() { ApplicationScopedBean.resetInstanceCount(); } @AfterClass public static void finalCheckAndCleanup() { if (ApplicationScopedBean.getInstanceCount() != 1) { throw new IllegalStateException("unexpected count"); } ApplicationScopedBean.resetInstanceCount(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc004/ProjectStageTestControlTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc004; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.uc001.RequestAndSessionScopePerTestMethodTest; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl(projectStage = ProjectStage.Development.class) //can be a custom stage @Typed() //needed due to RequestAndSessionScopePerTestMethodTest public class ProjectStageTestControlTest extends RequestAndSessionScopePerTestMethodTest //just to inherit the tests - to check that @TestControl#projectStage doesn't influence the default handling { @Inject private ProjectStage projectStage; @Test public void firstProjectStageTest() { Assert.assertEquals(ProjectStage.Development, this.projectStage); } @Test @TestControl(projectStage = ProjectStage.UnitTest.class) //can be a custom stage - e.g. for a special test public void secondProjectStageTest() { Assert.assertEquals(ProjectStage.UnitTest, this.projectStage); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc007/BaseTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc007; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol.shared.SessionScopedBean; import jakarta.inject.Inject; public abstract class BaseTest { @Inject protected ApplicationScopedBean applicationScopedBean; @Inject protected SessionScopedBean sessionScopedBean; @Inject protected RequestScopedBean requestScopedBean; } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc007/ExtendedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc007; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class ExtendedTest extends BaseTest { @Test public void inheritedInjectionTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); Assert.assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(1, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc008/BeforeAndAfterInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc008; import junit.framework.Assert; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.test.testcontrol.shared.ApplicationScopedBean; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class BeforeAndAfterInjectionTest { @Inject private ApplicationScopedBean applicationScopedBean; private Integer foundValue; @Before public void before() { if (this.applicationScopedBean == null) { throw new IllegalStateException("injection failed"); } this.foundValue = this.applicationScopedBean.getCount(); } @Test public void injectionTest() { Assert.assertNotNull(this.applicationScopedBean); Assert.assertNotNull(this.foundValue); } @After public void after() { if (this.applicationScopedBean == null) { throw new IllegalStateException("injection failed"); } if (this.foundValue == null) { throw new IllegalStateException("different instance without initialized value found"); } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/InterceptedBeanClassLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped @TestInterceptor public class InterceptedBeanClassLevel { public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/InterceptedBeanMethodLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptedBeanMethodLevel { @TestInterceptor public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/InterceptedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class InterceptedBeanTest { @Inject private InterceptionResultStorage interceptionResultStorage; @Inject private InterceptedBeanClassLevel interceptedBeanClassLevel; @Inject private InterceptedBeanMethodLevel interceptedBeanMethodLevel; @Test public void classLevelInterception() { Assert.assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanClassLevel.test(); Assert.assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } @Test public void methodLevelInterception() { Assert.assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanMethodLevel.test(); Assert.assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/InterceptionResultStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptionResultStorage { private boolean intercepted; public void markAsIntercepted() { this.intercepted = true; } public boolean isInterceptionDetected() { return intercepted; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/TestInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @InterceptorBinding @Target({ METHOD, TYPE }) @Retention(RUNTIME) public @interface TestInterceptor { } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc011/TestInterceptorImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc011; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @TestInterceptor @Interceptor public class TestInterceptorImplementation implements Serializable { @Inject private InterceptionResultStorage interceptionResultStorage; @AroundInvoke public Object intercept(InvocationContext ctx) throws Exception { this.interceptionResultStorage.markAsIntercepted(); return ctx.proceed(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc012/ApplicationScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc012; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class ApplicationScopedBeanTest { @Inject private ApplicationScopedTestBean testBean; @Inject private ApplicationScopedTestBeanClient testBeanClient; @Test public void beanAccess() { this.testBean.setValue(0); Assert.assertEquals(1, this.testBeanClient.getNextValue()); Assert.assertEquals(1, this.testBean.getValue()); } @AfterClass public static void finalCheck() { int value = BeanProvider.getContextualReference(ApplicationScopedTestBean.class).getValue(); int nextValue = BeanProvider.getContextualReference(ApplicationScopedTestBeanClient.class).getNextValue(); if (value == 0) { throw new IllegalStateException("new application-scoped bean instance was created"); } if (nextValue == 1) { throw new IllegalStateException("new application-scoped bean instance was created"); } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc012/ApplicationScopedTestBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc012; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationScopedTestBean { private int value = 0; public void increaseValue() { this.value++; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc012/ApplicationScopedTestBeanClient.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc012; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class ApplicationScopedTestBeanClient { @Inject private ApplicationScopedTestBean testBean; public int getNextValue() { this.testBean.increaseValue(); return this.testBean.getValue(); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc013/ContainerConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc013; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.apache.deltaspike.testcontrol.api.junit.CdiTestSuiteRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) public class ContainerConfigTest { @Test @TestControl(projectStage = ProjectStage.UnitTest.class) //just for internal tests public void configForTestContainerStageUnitTest() { Assert.assertNotNull(CdiTestSuiteRunner.getTestContainerConfig()); Assert.assertEquals("jdbc:hsqldb:mem:demoDB", CdiTestSuiteRunner.getTestContainerConfig().getProperty("demoDatabase.JdbcUrl")); } @Test @TestControl(projectStage = ProjectStage.IntegrationTest.class) //just for internal tests public void configForTestContainerStageIntegrationTest() { Assert.assertNotNull(CdiTestSuiteRunner.getTestContainerConfig()); Assert.assertEquals("jdbc:hsqldb:file:demoDB", CdiTestSuiteRunner.getTestContainerConfig().getProperty("demoDatabase.JdbcUrl")); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/DefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultTestService implements TestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestBeanClassFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.testcontrol.api.TestControl; //!!!not!!! needed with cdi 1.1+ and @Priority (which is the target of this use-case) //only needed because our test-suite is based on cdi v1.0 //also useful to test DELTASPIKE-1337 public class TestBeanClassFilter implements ClassFilter { @Override public boolean isFiltered(Class targetClass) { if (!targetClass.getName().startsWith("org.apache.deltaspike.test.")) { return false; } String currentTestOrigin = ConfigResolver.getPropertyValue(TestControl.class.getName()); if (currentTestOrigin == null) //no known origin (no @TestControl is used) { //filter all classes which are located in packages using tests with class-filters //(since we test the feature with ambiguous beans which isn't valid without filtering) return getClass().getPackage().getName().equals(targetClass.getPackage().getName()); } else { Class currentOrigin = ClassUtils.tryToLoadClassForName(currentTestOrigin); //origin is in one of the packages for class-filtering tests if (getClass().getPackage().getName().equals(currentOrigin.getPackage().getName())) { TestControl testControl = currentOrigin.getAnnotation(TestControl.class); return ClassUtils.tryToInstantiateClass(testControl.classFilter()).isFiltered(targetClass); } return isInSamePackage(targetClass); } } private boolean isInSamePackage(Class targetClass) { return targetClass.getPackage().getName().equals(getClass().getPackage().getName()); } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestLabeled.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import org.apache.deltaspike.testcontrol.api.TestControl; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(TYPE) public @interface TestLabeled { Class value(); } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestLabeledAlternativeFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.testcontrol.api.TestControl; import jakarta.enterprise.inject.Alternative; public abstract class TestLabeledAlternativeFilter implements ClassFilter { private final Class activeLabel; protected TestLabeledAlternativeFilter(Class activeLabel) { this.activeLabel = activeLabel; } @Override public boolean isFiltered(Class targetClass) { if (!targetClass.isAnnotationPresent(Alternative.class)) { return false; } TestLabeled testLabeled = targetClass.getAnnotation(TestLabeled.class); if (testLabeled == null) { return false; } if (testLabeled.value().equals(activeLabel)) { return false; } return true; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestServiceLabelX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabeled(TestServiceLabelXTest.TestLabelX.class) @ApplicationScoped public class TestServiceLabelX implements TestService { @Override public String getValue() { return "result-x"; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestServiceLabelXTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl( activeAlternativeLabel = TestServiceLabelXTest.TestLabelX.class, classFilter = TestServiceLabelXTest.LabelXFilter.class) public class TestServiceLabelXTest { @Inject private TestService testService; @Test public void resultX() { Assert.assertEquals("result-x", testService.getValue()); } public static class TestLabelX implements TestControl.Label { } //replaces the text based config of labeled-alternatives public static class LabelXFilter extends TestLabeledAlternativeFilter { public LabelXFilter() { super(TestLabelX.class); } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestServiceLabelY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabeled(TestServiceLabelYTest.TestLabelY.class) @ApplicationScoped public class TestServiceLabelY implements TestService { @Override public String getValue() { return "result-y"; } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/java/org/apache/deltaspike/test/testcontrol/uc019/TestServiceLabelYTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol.uc019; import org.apache.deltaspike.test.category.SeCategory; import org.apache.deltaspike.testcontrol.api.TestControl; import org.apache.deltaspike.testcontrol.api.junit.CdiTestRunner; import org.junit.Assert; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import jakarta.inject.Inject; //Usually NOT needed! Currently only needed due to our arquillian-setup @Category(SeCategory.class) @RunWith(CdiTestRunner.class) @TestControl( activeAlternativeLabel = TestServiceLabelYTest.TestLabelY.class, classFilter = TestServiceLabelYTest.LabelYFilter.class) public class TestServiceLabelYTest { @Inject private TestService testService; @Test public void resultY() { Assert.assertEquals("result-y", testService.getValue()); } public static class TestLabelY implements TestControl.Label { } //replaces the text based config of labeled-alternatives public static class LabelYFilter extends TestLabeledAlternativeFilter { public LabelYFilter() { super(TestServiceLabelYTest.TestLabelY.class); } } } ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # deltaspike.testcontrol.mock-support.allow_mocked_beans=true deltaspike.testcontrol.mock-support.allow_mocked_producers=true org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.test.testcontrol.InternalTestClassDeactivator deltaspike.testcontrol.test-container.config-file.UnitTest=META-INF/test/dsTestContainerBootConfig.properties #only needed because our test-suite is based on cdi v1.0. with v1.1+ and @Priority (which is the target of this use-case) the following part isn't needed: org.apache.deltaspike.core.spi.filter.ClassFilter=org.apache.deltaspike.test.testcontrol.uc019.TestBeanClassFilter ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/apache-deltaspike_test-container.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) #just random config-entries demoDatabase.JdbcUrl=jdbc:hsqldb:file:demoDB ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/beans.xml ================================================ org.apache.deltaspike.test.testcontrol.uc011.TestInterceptorImplementation org.apache.deltaspike.test.testcontrol.mock.uc015.TestInterceptorImplementation org.apache.deltaspike.test.testcontrol.CustomMockManager org.apache.deltaspike.test.testcontrol.uc019.TestServiceLabelX org.apache.deltaspike.test.testcontrol.uc019.TestServiceLabelY ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.alternative.AlternativeBeanClassProvider ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.testcontrol.uc016.CustomAlternativeBeanClassProvider ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.mock.MockFilter ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.testcontrol.InternalTestMockFilter ================================================ FILE: deltaspike/modules/test-control/impl/src/test/resources/META-INF/test/dsTestContainerBootConfig.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) #just random config-entries demoDatabase.JdbcUrl=jdbc:hsqldb:mem:demoDB ================================================ FILE: deltaspike/modules/test-control/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT org.apache.deltaspike.modules test-control-module-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Test-Control-Module api impl ================================================ FILE: deltaspike/modules/test-control5/api/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules test-control5-module-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.modules deltaspike-test-control5-module-api jar Apache DeltaSpike Test-Control5-Module API (JUnit 5) org.apache.deltaspike.testcontrol5.* jakarta.enterprise.inject, !org.apache.deltaspike.testcontrol5.*, * org.apache.deltaspike.core deltaspike-core-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided org.junit.jupiter junit-jupiter-api ${junit5.version} provided ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/TestControl.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Optional control annotation for JUnit 5 unit-tests */ @Target({ TYPE, METHOD }) @Retention(RUNTIME) public @interface TestControl { /** * only supports contexts supported by ContextControl#startContext * defaults: session- and request-scope */ Class[] startScopes() default { }; //TODO discuss callbacks Class projectStage() default ProjectStage.UnitTest.class; /** * only supported on test-class-level */ Class logHandler() default ConsoleHandler.class; /** * Requires additional service-loader config * Currently only supported on class-level */ boolean startExternalContainers() default true; /** * allows to label alternative cdi-beans similar to global alternatives to bind them to 0-n tests */ Class activeAlternativeLabel() default Label.class; //with cdi 1.1+ it can be used to implement labeled-alternatives without text based config //(details see DELTASPIKE-1338) /** * low-level filter (mainly needed for special cases if labeled-alternatives aren't enough) * @return the class-filter class which should be used for the current test-class */ Class classFilter() default ClassFilter.class; interface Label { } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/junit/CdiTestExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.junit; import jakarta.inject.Named; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ExceptionUtils; import org.apache.deltaspike.core.util.ProjectStageProducer; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.literal.TestControlLiteral; import org.apache.deltaspike.testcontrol5.spi.ExternalContainer; import org.apache.deltaspike.testcontrol5.spi.TestAware; import org.apache.deltaspike.testcontrol5.spi.TestControlValidator; import org.apache.deltaspike.testcontrol5.spi.junit.TestStatementDecoratorFactory; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Singleton; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Stack; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; /** * A JUnit 5 extension to start up with a CDI or embedded JavaEE container. */ public class CdiTestExtension implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver { private static final Logger LOGGER = Logger.getLogger(CdiTestExtension.class.getName()); private static final String STORE_KEY_TEST_CONTEXT = "testContext"; private static final String STORE_KEY_INJECTED_FLAG = "testInjected"; private static final boolean USE_TEST_CLASS_AS_CDI_BEAN; private static final boolean ALLOW_INJECTION_POINT_MANIPULATION; static { USE_TEST_CLASS_AS_CDI_BEAN = TestBaseConfig.ContainerIntegration.USE_TEST_CLASS_AS_CDI_BEAN; ALLOW_INJECTION_POINT_MANIPULATION = TestBaseConfig.MockIntegration.ALLOW_MANUAL_INJECTION_POINT_MANIPULATION; } private List statementDecoratorFactories; protected static ExtensionContext.Store getStore(ExtensionContext extensionContext) { final ExtensionContext.Namespace namespace = ExtensionContext.Namespace.create(CdiTestExtension.class, extensionContext.getUniqueId()); return extensionContext.getStore(namespace); } protected ContainerAwareTestContext getClassTestContext(ExtensionContext extensionContext) { final ExtensionContext.Store store = getStore(extensionContext); return store.getOrComputeIfAbsent(STORE_KEY_TEST_CONTEXT, k -> { TestControl testControl = extensionContext.getTestClass() .map(cls -> cls.getAnnotation(TestControl.class)).orElse(null); ContainerAwareTestContext testContext = new ContainerAwareTestContext(testControl, null); Class logHandlerClass = testContext.getLogHandlerClass(); if (!Handler.class.equals(logHandlerClass)) { try { LOGGER.addHandler(logHandlerClass.newInstance()); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } } this.statementDecoratorFactories = ServiceUtils.loadServiceImplementations(TestStatementDecoratorFactory.class); Collections.sort(this.statementDecoratorFactories, (f1, f2) -> f1.getOrdinal() > f2.getOrdinal() ? 1 : -1); return testContext; }, ContainerAwareTestContext.class); } protected ContainerAwareTestContext getMethodTestContext(ExtensionContext methodExtensionContext) { final ExtensionContext.Store store = getStore(methodExtensionContext); return store.getOrComputeIfAbsent(STORE_KEY_TEST_CONTEXT, k -> { TestControl testControl = methodExtensionContext.getTestMethod() .map(cls -> cls.getAnnotation(TestControl.class)).orElse(null); ContainerAwareTestContext classTestContext = getClassTestContext(methodExtensionContext.getParent().orElse(null)); return new ContainerAwareTestContext(testControl, classTestContext); }, ContainerAwareTestContext.class); } @Override public void beforeEach(ExtensionContext extensionContext) throws Exception { ContainerAwareTestContext currentTestContext = getMethodTestContext(extensionContext); extensionContext.getTestMethod().ifPresent(method -> { try { currentTestContext.applyBeforeMethodConfig(method); } catch (Exception e) { throw ExceptionUtils.throwAsRuntimeException(e); } }); final ExtensionContext.Store store = getStore(extensionContext); final ConcurrentMap isInjectedMap = store.getOrComputeIfAbsent(STORE_KEY_INJECTED_FLAG, k -> new ConcurrentHashMap(), ConcurrentMap.class); final int classId = System.identityHashCode(extensionContext.getTestInstance()); if (!isInjectedMap.containsKey(classId)) { BeanProvider.injectFields(extensionContext.getTestInstance().get()); isInjectedMap.putIfAbsent(classId, Boolean.TRUE); } } @Override public void afterEach(ExtensionContext extensionContext) throws Exception { ContainerAwareTestContext currentTestContext = getMethodTestContext(extensionContext); if (currentTestContext != null) { currentTestContext.applyAfterMethodConfig(); } } @Override public void beforeAll(ExtensionContext extensionContext) throws Exception { getClassTestContext(extensionContext).applyBeforeClassConfig(extensionContext.getTestClass().orElseThrow()); } @Override public void afterAll(ExtensionContext extensionContext) throws Exception { final ContainerAwareTestContext testContext = getClassTestContext(extensionContext); if (testContext != null) { testContext.applyAfterClassConfig(); } // TODO destroy all injected beans // this might need a namespace storage in the context? } @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { return false; } @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { return null; } private class ContainerAwareTestContext { private ContainerAwareTestContext parent; private final ProjectStage projectStage; private final TestControl testControl; private ProjectStage previousProjectStage; private boolean containerStarted = false; private Stack> startedScopes = new Stack<>(); private List externalContainers; ContainerAwareTestContext(TestControl testControl, ContainerAwareTestContext parent) { this.parent = parent; Class foundProjectStageClass; if (testControl == null) { this.testControl = new TestControlLiteral(); if (parent != null) { foundProjectStageClass = parent.testControl.projectStage(); } else { foundProjectStageClass = this.testControl.projectStage(); } } else { this.testControl = testControl; foundProjectStageClass = this.testControl.projectStage(); } this.projectStage = ProjectStage.valueOf(foundProjectStageClass.getSimpleName()); ProjectStageProducer.setProjectStage(this.projectStage); } boolean isContainerStarted() { return this.containerStarted || (this.parent != null && this.parent.isContainerStarted()); } Class getLogHandlerClass() { return this.testControl.logHandler(); } void applyBeforeClassConfig(Class testClass) { CdiContainer container = CdiContainerLoader.getCdiContainer(); if (!isContainerStarted()) { // We are setting this system property to make the deployment for Weld "flat" // This (amongst other things) means that alternatives enabled via beans.xml will be // enabled globally // Beginning with Weld 2.x you could use Weld.property(), but here we depend on Weld 1.x API // Note that Weld 1 was "flat" anyway, so this property only affects newer versions of Weld // System.setProperty("org.jboss.weld.se.archive.isolation", "false"); // Weld 5.0: https://docs.jboss.org/weld/reference/5.0.0.Final/en-US/html_single/#_bean_archive_isolation System.setProperty("org.jboss.weld.environment.servlet.archive.isolation", "false"); String activeAlternativeLabel = checkForLabeledAlternativeConfig(testControl); initTestEnvConfig(testClass, activeAlternativeLabel, testControl); container.boot(CdiTestSuiteExtension.getTestContainerConfig()); setContainerStarted(); bootExternalContainers(testClass); } List> restrictedScopes = new ArrayList>(); restrictedScopes.add(ApplicationScoped.class); restrictedScopes.add(Singleton.class); if (this.parent == null && this.testControl.getClass().equals(TestControlLiteral.class)) { restrictedScopes.add(RequestScoped.class); restrictedScopes.add(SessionScoped.class); } startScopes(container, testClass, null, restrictedScopes.toArray(new Class[restrictedScopes.size()])); } private void bootExternalContainers(Class testClass) { if (!this.testControl.startExternalContainers()) { return; } if (this.externalContainers == null) { List configuredExternalContainers = ServiceUtils.loadServiceImplementations(ExternalContainer.class); Collections.sort(configuredExternalContainers, new Comparator() { @Override public int compare(ExternalContainer ec1, ExternalContainer ec2) { return ec1.getOrdinal() > ec2.getOrdinal() ? 1 : -1; } }); this.externalContainers = new ArrayList(configuredExternalContainers.size()); ExternalContainer externalContainerBean; for (ExternalContainer externalContainer : configuredExternalContainers) { externalContainerBean = BeanProvider.getContextualReference(externalContainer.getClass(), true); if (externalContainerBean != null) { this.externalContainers.add(externalContainerBean); } else { this.externalContainers.add(externalContainer); } } for (ExternalContainer externalContainer : this.externalContainers) { try { if (externalContainer instanceof TestAware) { ((TestAware) externalContainer).setTestClass(testClass); } externalContainer.boot(); } catch (RuntimeException e) { Logger.getLogger(CdiTestExtension.class.getName()).log(Level.WARNING, "booting " + externalContainer.getClass().getName() + " failed", e); } } } } void applyAfterClassConfig() { CdiContainer container = CdiContainerLoader.getCdiContainer(); stopStartedScopes(container); if (this.containerStarted) { if (CdiTestSuiteExtension.isStopContainerAllowed()) { shutdownExternalContainers(); container.shutdown(); CdiTestSuiteExtension.setContainerStarted(false); } } } private void shutdownExternalContainers() { if (this.externalContainers == null) { return; } for (ExternalContainer externalContainer : this.externalContainers) { try { externalContainer.shutdown(); } catch (RuntimeException e) { Logger.getLogger(CdiTestExtension.class.getName()).log(Level.WARNING, "shutting down " + externalContainer.getClass().getName() + " failed", e); } } } void applyBeforeMethodConfig(Method testMethod) { this.previousProjectStage = ProjectStageProducer.getInstance().getProjectStage(); ProjectStageProducer.setProjectStage(this.projectStage); setCurrentTestMethod(testMethod); startScopes(CdiContainerLoader.getCdiContainer(), testMethod.getDeclaringClass(), testMethod); } void applyAfterMethodConfig() { try { stopStartedScopes(CdiContainerLoader.getCdiContainer()); } finally { setCurrentTestMethod(null); ProjectStageProducer.setProjectStage(previousProjectStage); previousProjectStage = null; } } private String checkForLabeledAlternativeConfig(TestControl testControl) { String activeAlternativeLabel = ""; if (testControl != null) { Class activeTypedAlternativeLabel = testControl.activeAlternativeLabel(); if (!TestControl.Label.class.equals(activeTypedAlternativeLabel)) { Named labelName = activeTypedAlternativeLabel.getAnnotation(Named.class); if (labelName != null) { activeAlternativeLabel = labelName.value(); } else { String labelClassName = activeTypedAlternativeLabel.getSimpleName(); activeAlternativeLabel = labelClassName.substring(0, 1).toLowerCase(); if (labelClassName.length() > 1) { activeAlternativeLabel += labelClassName.substring(1); } } } } return activeAlternativeLabel; } private void initTestEnvConfig(Class testClass, String activeAlternativeLabel, TestControl testControl) { if (ClassDeactivationUtils.isActivated(TestConfigSource.class)) { TestConfigSource testConfigSource = null; for (ConfigSource configSource : ConfigResolver.getConfigSources()) { if (configSource instanceof TestConfigSource) { //if it happens: parallel test-execution can't be supported with labeled alternatives testConfigSource = (TestConfigSource) configSource; } } if (testConfigSource == null) { testConfigSource = new TestConfigSource(); ConfigResolver.addConfigSources(Arrays.asList(testConfigSource)); } //always set it even if it is empty (it might overrule the value of the prev. test testConfigSource.getProperties().put("activeAlternativeLabel", activeAlternativeLabel); testConfigSource.getProperties().put("activeAlternativeLabelSource", testClass.getName()); if (testControl != null) { testConfigSource.getProperties().put(TestControl.class.getName(), testClass.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), testControl.classFilter().getName()); } else { //reset it to avoid leaks between tests testConfigSource.getProperties().put(TestControl.class.getName(), TestControl.class.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), ClassFilter.class.getName()); } } else { throw new IllegalStateException("Alternative Environments require TestConfigSource to be active"); } } void setContainerStarted() { this.containerStarted = true; CdiTestSuiteExtension.setContainerStarted(true); } private void startScopes(CdiContainer container, Class testClass, Method testMethod, Class... restrictedScopes) { ContextControl contextControl = container.getContextControl(); List> scopeClasses = new ArrayList<>(); Collections.addAll(scopeClasses, this.testControl.startScopes()); if (scopeClasses.isEmpty()) { addScopesForDefaultBehavior(scopeClasses); } else { List testControlValidatorList = ServiceUtils.loadServiceImplementations(TestControlValidator.class); for (TestControlValidator testControlValidator : testControlValidatorList) { if (testControlValidator instanceof TestAware) { if (testMethod != null) { ((TestAware) testControlValidator).setTestMethod(testMethod); } ((TestAware) testControlValidator).setTestClass(testClass); } try { testControlValidator.validate(this.testControl); } finally { if (testControlValidator instanceof TestAware) { ((TestAware) testControlValidator).setTestClass(null); ((TestAware) testControlValidator).setTestMethod(null); } } } } for (Class scopeAnnotation : scopeClasses) { if (this.parent != null && this.parent.isScopeStarted(scopeAnnotation)) { continue; } if (isRestrictedScope(scopeAnnotation, restrictedScopes)) { continue; } try { contextControl.stopContext(scopeAnnotation); contextControl.startContext(scopeAnnotation); this.startedScopes.add(scopeAnnotation); onScopeStarted(scopeAnnotation); } catch (RuntimeException e) { Logger logger = Logger.getLogger(CdiTestExtension.class.getName()); logger.setLevel(Level.SEVERE); logger.log(Level.SEVERE, "failed to start scope @" + scopeAnnotation.getName(), e); } } } private void addScopesForDefaultBehavior(List> scopeClasses) { if (this.parent != null && !this.parent.isScopeStarted(RequestScoped.class)) { if (!scopeClasses.contains(RequestScoped.class)) { scopeClasses.add(RequestScoped.class); } } if (this.parent != null && !this.parent.isScopeStarted(SessionScoped.class)) { if (!scopeClasses.contains(SessionScoped.class)) { scopeClasses.add(SessionScoped.class); } } } private boolean isRestrictedScope(Class scopeAnnotation, Class[] restrictedScopes) { for (Class restrictedScope : restrictedScopes) { if (scopeAnnotation.equals(restrictedScope)) { return true; } } return false; } private boolean isScopeStarted(Class scopeAnnotation) { return this.startedScopes.contains(scopeAnnotation); } private void stopStartedScopes(CdiContainer container) { while (!this.startedScopes.empty()) { Class scopeAnnotation = this.startedScopes.pop(); try { container.getContextControl().stopContext(scopeAnnotation); onScopeStopped(scopeAnnotation); } catch (RuntimeException e) { Logger logger = Logger.getLogger(CdiTestExtension.class.getName()); logger.setLevel(Level.SEVERE); logger.log(Level.SEVERE, "failed to stop scope @" + scopeAnnotation.getName(), e); } } } private void onScopeStarted(Class scopeClass) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { externalContainer.startScope(scopeClass); } } private void onScopeStopped(Class scopeClass) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { externalContainer.stopScope(scopeClass); } } private List collectExternalContainers(ContainerAwareTestContext testContext) { List result = new ArrayList(); if (testContext.externalContainers != null) { result.addAll(testContext.externalContainers); } if (testContext.parent != null) { result.addAll(collectExternalContainers(testContext.parent)); } return result; } private void setCurrentTestMethod(Method testMethod) { List externalContainerList = collectExternalContainers(this); for (ExternalContainer externalContainer : externalContainerList) { if (externalContainer instanceof TestAware) { try { ((TestAware) externalContainer).setTestMethod(testMethod); } catch (Throwable t) { throw new RuntimeException(t.getMessage()); } } } } } public static Boolean isAutomaticScopeHandlingActive() { throw new UnsupportedOperationException("Not supported yet."); //X TODO return automaticScopeHandlingActive.get(); } public static List getActiveExternalContainers() { throw new UnsupportedOperationException("Not supported yet."); /*X TODO CdiTestExtension cdiTestExtension = currentTestExtension.get(); if (cdiTestExtension == null || cdiTestExtension.externalContainers == null) { return Collections.emptyList(); } return Collections.unmodifiableList(cdiTestExtension.externalContainers); */ } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/junit/CdiTestSuiteExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.junit; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.PropertyLoader; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.config.ConfigSource; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.junit.jupiter.api.extension.AfterAllCallback; import org.junit.jupiter.api.extension.BeforeAllCallback; import org.junit.jupiter.api.extension.ExtensionContext; import jakarta.inject.Named; import java.util.Arrays; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; //X TODO this is work in progress and not fully functional right now. public class CdiTestSuiteExtension extends CdiTestExtension implements BeforeAllCallback, AfterAllCallback { public static final String CUSTOM_TEST_CONTAINER_CONFIG_FILE_KEY = "deltaspike.testcontrol.test-container.config-file"; public static final String DEFAULT_TEST_CONTAINER_CONFIG_FILE_NAME = "META-INF/apache-deltaspike_test-container"; private static final boolean STOP_CONTAINER; private static final ThreadLocal IS_CDI_TEST_RUNNER_EXECUTION = new ThreadLocal<>(); private static volatile boolean containerStarted; private Class testSuiteClass; static { STOP_CONTAINER = TestBaseConfig.ContainerIntegration.STOP_CONTAINER; } @Override public void beforeAll(ExtensionContext extensionContext) throws Exception { this.testSuiteClass = extensionContext.getTestClass() .orElseThrow(() -> new IllegalStateException("no test-suite class found")); CdiContainer container = CdiContainerLoader.getCdiContainer(); if (!containerStarted) { applyTestSpecificMetaData(testSuiteClass); container.boot(getTestContainerConfig()); containerStarted = true; } } @Override public void afterAll(ExtensionContext extensionContext) throws Exception { // Cleanup if needed if (STOP_CONTAINER) { CdiContainer container = CdiContainerLoader.getCdiContainer(); container.shutdown(); containerStarted = false; } } public static boolean isContainerStarted() { return containerStarted; } static Boolean isStopContainerAllowed() { return STOP_CONTAINER; } static ThreadLocal getCdiTestRunnerExecutionRef() { return IS_CDI_TEST_RUNNER_EXECUTION; } static void setContainerStarted(boolean containerStarted) { CdiTestSuiteExtension.containerStarted = containerStarted; } public static Properties getTestContainerConfig() { String cdiTestRunnerConfig = ConfigResolver.getProjectStageAwarePropertyValue( CUSTOM_TEST_CONTAINER_CONFIG_FILE_KEY, DEFAULT_TEST_CONTAINER_CONFIG_FILE_NAME); return PropertyLoader.getProperties(cdiTestRunnerConfig); } static void applyTestSpecificMetaData(Class currentAnnotationSource) { TestControl testControl = currentAnnotationSource.getAnnotation(TestControl.class); String activeAlternativeLabel = checkForLabeledAlternativeConfig(testControl); initTestEnvConfig(currentAnnotationSource, activeAlternativeLabel, testControl); } private static String checkForLabeledAlternativeConfig(TestControl testControl) { String activeAlternativeLabel = ""; if (testControl != null) { Class activeTypedAlternativeLabel = testControl.activeAlternativeLabel(); if (!TestControl.Label.class.equals(activeTypedAlternativeLabel)) { Named labelName = activeTypedAlternativeLabel.getAnnotation(Named.class); if (labelName != null) { activeAlternativeLabel = labelName.value(); } else { String labelClassName = activeTypedAlternativeLabel.getSimpleName(); activeAlternativeLabel = labelClassName.substring(0, 1).toLowerCase(); if (labelClassName.length() > 1) { activeAlternativeLabel += labelClassName.substring(1); } } } } return activeAlternativeLabel; } private static void initTestEnvConfig(Class testClass, String activeAlternativeLabel, TestControl testControl) { if (ClassDeactivationUtils.isActivated(TestConfigSource.class)) { TestConfigSource testConfigSource = null; for (ConfigSource configSource : ConfigResolver.getConfigSources()) { if (configSource instanceof TestConfigSource) { testConfigSource = (TestConfigSource) configSource; } } if (testConfigSource == null) { testConfigSource = new TestConfigSource(); ConfigResolver.addConfigSources(Arrays.asList(testConfigSource)); } testConfigSource.getProperties().put("activeAlternativeLabel", activeAlternativeLabel); testConfigSource.getProperties().put("activeAlternativeLabelSource", testClass.getName()); if (testControl != null) { testConfigSource.getProperties().put(TestControl.class.getName(), testClass.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), testControl.classFilter().getName()); } else { testConfigSource.getProperties().put(TestControl.class.getName(), TestControl.class.getName()); testConfigSource.getProperties().put(ClassFilter.class.getName(), ClassFilter.class.getName()); } } else { System.setProperty("activeAlternativeLabel", activeAlternativeLabel); System.setProperty("activeAlternativeLabelSource", testClass.getName()); if (testControl != null) { System.setProperty(TestControl.class.getName(), testClass.getName()); System.setProperty(ClassFilter.class.getName(), testControl.classFilter().getName()); } else { System.setProperty(TestControl.class.getName(), TestControl.class.getName()); System.setProperty(ClassFilter.class.getName(), ClassFilter.class.getName()); } } } public static class TestConfigSource implements ConfigSource, Deactivatable { private Map testConfig = new ConcurrentHashMap(); @Override public int getOrdinal() { return Integer.MIN_VALUE; } @Override public Map getProperties() { return testConfig; } @Override public String getPropertyValue(String key) { return testConfig.get(key); } @Override public String getConfigName() { return "ds-test5-config"; } @Override public boolean isScannable() { return true; } } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/junit/TestBaseConfig.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.junit; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.api.config.base.DeltaSpikeBaseConfig; public interface TestBaseConfig extends DeltaSpikeBaseConfig { interface ContainerIntegration { //default is false to improve the compatibility with @Before and @After Boolean USE_TEST_CLASS_AS_CDI_BEAN = ConfigResolver.resolve("deltaspike.testcontrol5.use_test_class_as_cdi_bean") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); Boolean STOP_CONTAINER = ConfigResolver.resolve("deltaspike.testcontrol5.stop_container") .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.TRUE) .getValue(); } interface MockIntegration { String ALLOW_MOCKED_BEANS_KEY = "deltaspike.testcontrol5.mock-support.allow_mocked_beans"; String ALLOW_MOCKED_PRODUCERS_KEY = "deltaspike.testcontrol5.mock-support.allow_mocked_producers"; String ALLOW_MANUAL_INJECTION_POINT_MANIPULATION_KEY = "deltaspike.testcontrol5.mock-support.allow_manual_injection-point_manipulation"; Boolean ALLOW_MOCKED_BEANS = ConfigResolver.resolve(ALLOW_MOCKED_BEANS_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); Boolean ALLOW_MOCKED_PRODUCERS = ConfigResolver.resolve(ALLOW_MOCKED_PRODUCERS_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); //if enabled it's possible to change the value of injection-points after the injection-process and //before test-execution. that allows to replace injection-points (e.g. with a mock) conditionally //via a test-rule or @Before Boolean ALLOW_MANUAL_INJECTION_POINT_MANIPULATION = ConfigResolver.resolve(ALLOW_MANUAL_INJECTION_POINT_MANIPULATION_KEY) .as(Boolean.class) .withCurrentProjectStage(true) .withDefault(Boolean.FALSE) .getValue(); } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/junit/TestConfigSource.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.junit; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.spi.config.ConfigSource; //config-sources are already stored per classloader //keep it public to allow type-safe deactivation (if needed) public class TestConfigSource implements ConfigSource, Deactivatable { private Map testConfig = new ConcurrentHashMap(); @Override public int getOrdinal() { return Integer.MIN_VALUE; } @Override public Map getProperties() { return testConfig; } @Override public String getPropertyValue(String key) { return testConfig.get(key); } @Override public String getConfigName() { return "ds-test-config"; } @Override public boolean isScannable() { return true; } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/literal/TestControlLiteral.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.literal; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.core.util.metadata.AnnotationInstanceProvider; import org.apache.deltaspike.testcontrol5.api.TestControl; import jakarta.enterprise.util.AnnotationLiteral; import java.lang.annotation.Annotation; import java.util.logging.Handler; public class TestControlLiteral extends AnnotationLiteral implements TestControl { private static final long serialVersionUID = 6684011035751678259L; private final TestControl defaultInstance; public TestControlLiteral() { this.defaultInstance = AnnotationInstanceProvider.of(TestControl.class); } @Override public Class[] startScopes() { return defaultInstance.startScopes(); } @Override public Class projectStage() { return defaultInstance.projectStage(); } @Override public Class logHandler() { return defaultInstance.logHandler(); } @Override public boolean startExternalContainers() { return defaultInstance.startExternalContainers(); } @Override public Class activeAlternativeLabel() { return defaultInstance.activeAlternativeLabel(); } @Override public Class classFilter() { return defaultInstance.classFilter(); } } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/mock/ApplicationMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.mock; import java.lang.annotation.Annotation; public interface ApplicationMockManager { void addMock(Object mockInstance, Annotation... qualifiers); T getMock(Class beanClass, Annotation... qualifiers); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/mock/DynamicMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.mock; public interface DynamicMockManager extends ApplicationMockManager { void reset(); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/api/mock/TypedMock.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.api.mock; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target({ FIELD, METHOD, TYPE }) @Retention(RUNTIME) public @interface TypedMock { Class[] value() default { }; } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/spi/ExternalContainer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.spi; import java.lang.annotation.Annotation; public interface ExternalContainer { void boot(); void shutdown(); int getOrdinal(); void startScope(Class scopeClass); void stopScope(Class scopeClass); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/spi/TestAware.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.spi; import java.lang.reflect.Method; public interface TestAware { void setTestClass(Class testClass); void setTestMethod(Method testMethod); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/spi/TestControlValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.spi; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.testcontrol5.api.TestControl; public interface TestControlValidator extends Deactivatable { void validate(TestControl testControl); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/spi/junit/TestStatementDecoratorFactory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.spi.junit; import org.junit.jupiter.api.extension.ExtensionContext; public interface TestStatementDecoratorFactory { ExtensionContext createContext(ExtensionContext extensionContext); int getOrdinal(); } ================================================ FILE: deltaspike/modules/test-control5/api/src/main/java/org/apache/deltaspike/testcontrol5/spi/mock/MockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.spi.mock; import org.apache.deltaspike.core.spi.activation.Deactivatable; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.BeanManager; public interface MockFilter extends Deactivatable { boolean isMockedImplementationSupported(BeanManager beanManager, Annotated annotated); } ================================================ FILE: deltaspike/modules/test-control5/impl/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules test-control5-module-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.modules deltaspike-test-control5-module-impl jar Apache DeltaSpike Test-Control5-Module Impl (JUnit 5) org.apache.deltaspike.testcontrol5.impl.* !org.apache.deltaspike.testcontrol5.impl.*, * org.junit junit-bom ${junit5.version} pom import org.apache.deltaspike.modules deltaspike-test-control5-module-api ${project.version} org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${project.version} provided org.apache.geronimo.specs geronimo-jpa_2.2_spec true org.junit.jupiter junit-jupiter-api compile org.junit.jupiter junit-jupiter test org.junit.platform junit-platform-launcher test jakarta.el jakarta.el-api provided org.apache.tomcat tomcat-servlet-api provided org.mockito mockito-core org.apache.deltaspike.core deltaspike-core-impl ${project.version} runtime org.junit.platform junit-platform-suite-engine test OWB true org.apache.openwebbeans openwebbeans-impl test org.apache.openwebbeans openwebbeans-spi test org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${project.version} test org.apache.maven.plugins maven-surefire-plugin org.apache.maven.surefire surefire-junit-platform ${maven.surefire.plugin.version} Weld org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${project.version} test org.apache.maven.plugins maven-surefire-plugin org.apache.maven.surefire surefire-junit-platform ${maven.surefire.plugin.version} tomee-build-managed wildfly-build-managed ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/AbstractMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol5.api.junit.TestBaseConfig; import org.apache.deltaspike.testcontrol5.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol5.api.mock.TypedMock; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.Map; public abstract class AbstractMockManager implements DynamicMockManager { private Map registeredMocks = new HashMap(); @Override public void addMock(Object mockInstance, Annotation... qualifiers) { if (!TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS && !TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS) { throw new IllegalStateException("The support for mocked CDI-Beans is disabled " + "due to a reduced portability across different CDI-implementations. " + "Please set '" + TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS_KEY + "' and/or '" + TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS_KEY + "' to 'true' " + "(in 'META-INF/apache-deltaspike.properties') on your test-classpath."); } Class mockClass = mockInstance.getClass(); Class beanClass = mockClass.getSuperclass(); if (beanClass == null) { beanClass = mockClass; } if (Object.class.equals(beanClass)) { throw new IllegalArgumentException(mockInstance.getClass().getName() + " isn't a supported approach for mocking -> please extend from the original class."); } TypedMock typedMock = mockClass.getAnnotation(TypedMock.class); if (typedMock == null) { typedMock = beanClass.getAnnotation(TypedMock.class); } Class[] specifiedTypes = null; if (typedMock != null) { specifiedTypes = typedMock.value(); } else { Typed typed = mockClass.getAnnotation(Typed.class); if (typed == null || typed.value().length == 0) { typed = beanClass.getAnnotation(Typed.class); } if (typed != null && typed.value().length > 0) { specifiedTypes = typed.value(); } } if (specifiedTypes != null) { for (Class typedClass : specifiedTypes) { this.registeredMocks.put(new BeanCacheKey(typedClass, qualifiers), mockInstance); } } else { this.registeredMocks.put(new BeanCacheKey(beanClass, qualifiers), mockInstance); } } @Override public T getMock(Class beanClass, Annotation... qualifiers) { return (T)this.registeredMocks.get(new BeanCacheKey(beanClass, qualifiers)); } @Override public void reset() { this.registeredMocks.clear(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/BeanCacheKey.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import org.apache.deltaspike.core.util.ReflectionUtils; import jakarta.enterprise.util.Nonbinding; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Comparator; public class BeanCacheKey { private static final Comparator ANNOTATION_COMPARATOR = new AnnotationComparator(); private final Type type; private final Annotation qualifier; private final Annotation qualifiers[]; private final int hashCode; public BeanCacheKey(Type type, Annotation... qualifiers) { this.type = type; final int length = qualifiers != null ? qualifiers.length : 0; if (length == 0) { qualifier = null; this.qualifiers = null; } else if (length == 1) { qualifier = qualifiers[0]; this.qualifiers = null; } else { qualifier = null; this.qualifiers = new Annotation[length]; System.arraycopy(qualifiers, 0, this.qualifiers, 0, length); Arrays.sort(this.qualifiers, ANNOTATION_COMPARATOR); } hashCode = computeHashCode(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } BeanCacheKey cacheKey = (BeanCacheKey) o; if (!type.equals(cacheKey.type)) { return false; } if (qualifier != null ? !qualifierEquals(qualifier, cacheKey.qualifier) : cacheKey.qualifier != null) { return false; } if (!qualifierArrayEquals(qualifiers, cacheKey.qualifiers)) { return false; } return true; } private boolean qualifierArrayEquals(Annotation[] qualifiers1, Annotation[] qualifiers2) { if (qualifiers1 == qualifiers2) { return true; } else if (qualifiers1 == null || qualifiers2 == null) { return false; } if (qualifiers1.length != qualifiers2.length) { return false; } for (int i = 0; i < qualifiers1.length; i++) { Annotation a1 = qualifiers1[i]; Annotation a2 = qualifiers2[i]; if (a1 == null ? a2 != null : !qualifierEquals(a1, a2)) { return false; } } return true; } @Override public int hashCode() { return hashCode; } private int computeHashCode() { int computedHashCode = 31 * ReflectionUtils.calculateHashCodeOfType(type); if (qualifier != null) { computedHashCode = 31 * computedHashCode + getQualifierHashCode(qualifier); } if (qualifiers != null) { for (int i = 0; i < qualifiers.length; i++) { computedHashCode = 31 * computedHashCode + getQualifierHashCode(qualifiers[i]); } } return computedHashCode; } private int getQualifierHashCode(Annotation a) { return ReflectionUtils.calculateHashCodeOfAnnotation(a, true); } private boolean qualifierEquals(Annotation qualifier1, Annotation qualifier2) { return ANNOTATION_COMPARATOR.compare(qualifier1, qualifier2) == 0; } @Override public String toString() { return "BeanCacheKey{" + "type=" + type + ", qualifiers=" + (qualifiers == null ? qualifier : Arrays.asList(qualifiers)) + ", hashCode=" + hashCode + '}'; } private static class AnnotationComparator implements Comparator { @Override public int compare(Annotation annotation1, Annotation annotation2) { final Class type1 = annotation1.annotationType(); final Class type2 = annotation2.annotationType(); final int temp = type1.getName().compareTo(type2.getName()); if (temp != 0) { return temp; } final Method[] member1 = type1.getDeclaredMethods(); final Method[] member2 = type2.getDeclaredMethods(); int i = 0; int j = 0; final int length1 = member1.length; final int length2 = member2.length; for (;; i++, j++) { while (i < length1 && member1[i].isAnnotationPresent(Nonbinding.class)) { i++; } while (j < length2 && member2[j].isAnnotationPresent(Nonbinding.class)) { j++; } if (i >= length1 && j >= length2) { return 0; } else if (i >= length1) { return 1; } else if (j >= length2) { return -1; } else { int c = member1[i].getName().compareTo(member2[j].getName()); if (c != 0) { return c; } final Object value1 = ReflectionUtils.invokeMethod(annotation1, member1[i], Object.class, true); final Object value2 = ReflectionUtils.invokeMethod(annotation2, member2[j], Object.class, true); assert value1.getClass().equals(value2.getClass()); if (value1 instanceof Comparable) { c = ((Comparable)value1).compareTo(value2); if (c != 0) { return c; } } else if (value1.getClass().isArray()) { c = value1.getClass().getComponentType().getName() .compareTo(value2.getClass().getComponentType().getName()); if (c != 0) { return c; } final int length = Array.getLength(value1); c = length - Array.getLength(value2); if (c != 0) { return c; } for (int k = 0; k < length; k++) { c = ((Comparable)Array.get(value1, k)).compareTo(Array.get(value2, k)); if (c != 0) { return c; } } } else if (value1 instanceof Class) { c = ((Class)value1).getName().compareTo(((Class) value2).getName()); if (c != 0) { return c; } } else { assert false; } } } } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/DefaultMockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import org.apache.deltaspike.testcontrol5.api.junit.TestBaseConfig; import org.apache.deltaspike.testcontrol5.spi.mock.MockFilter; import jakarta.enterprise.inject.Produces; import jakarta.enterprise.inject.spi.Annotated; import jakarta.enterprise.inject.spi.AnnotatedField; import jakarta.enterprise.inject.spi.AnnotatedMember; import jakarta.enterprise.inject.spi.AnnotatedMethod; import jakarta.enterprise.inject.spi.AnnotatedType; import jakarta.enterprise.inject.spi.BeanManager; import java.lang.annotation.Annotation; import java.lang.reflect.Member; import java.util.HashSet; import java.util.Set; import java.util.logging.Logger; public class DefaultMockFilter implements MockFilter { private static final Logger LOG = Logger.getLogger(DefaultMockFilter.class.getName()); private static final String DS_BASE_PACKAGE = "org.apache.deltaspike."; private static final String JAVA_BASE_PACKAGE = "java."; private static final String JAVAX_BASE_PACKAGE = "javax."; private static final String JAKARTA_BASE_PACKAGE = "jakarta."; private static final String EJB_BASE_PACKAGE = "javax.ejb."; private static final String OWB_BASE_PACKAGE = "org.apache.webbeans."; private static final String WELD_BASE_PACKAGE = "org.jboss.weld."; @Override public boolean isMockedImplementationSupported(BeanManager beanManager, Annotated annotated) { if (!isMockSupportEnabled(annotated)) { return false; } Class origin = null; if (annotated instanceof AnnotatedType) { origin = ((AnnotatedType)annotated).getJavaClass(); Set annotations = new HashSet(); annotations.addAll(annotated.getAnnotations()); for (AnnotatedMethod annotatedMethod : (Set)((AnnotatedType) annotated).getMethods()) { annotations.addAll(annotatedMethod.getAnnotations()); } if (isEjbOrAnnotatedTypeWithInterceptorAnnotation( beanManager, annotations, origin.getName())) { return false; } } else if (annotated instanceof AnnotatedMember) { Member member = ((AnnotatedMember)annotated).getJavaMember(); origin = member.getDeclaringClass(); if (isEjbOrAnnotatedTypeWithInterceptorAnnotation( beanManager, annotated.getAnnotations(), member.toString())) { return false; } } if (origin != null && origin.getPackage() == null) { LOG.warning("Please don't use the default-package for " + origin.getName()); return true; } return origin != null && !isInternalPackage(origin.getPackage().getName()); } protected boolean isMockSupportEnabled(Annotated annotated) { if ((annotated instanceof AnnotatedMethod || annotated instanceof AnnotatedField) && annotated.getAnnotation(Produces.class) != null) { return TestBaseConfig.MockIntegration.ALLOW_MOCKED_PRODUCERS; } else { return TestBaseConfig.MockIntegration.ALLOW_MOCKED_BEANS; } } protected boolean isEjbOrAnnotatedTypeWithInterceptorAnnotation(BeanManager beanManager, Set annotations, String origin) { for (Annotation annotation : annotations) { if (annotation.annotationType().getName().startsWith(EJB_BASE_PACKAGE)) { return true; } if (isStandardAnnotation(annotation)) { continue; } if (beanManager.isInterceptorBinding(annotation.annotationType()) || (beanManager.isStereotype(annotation.annotationType()) && isStereotypeWithInterceptor(annotation, beanManager))) { LOG.warning("Skip mocking intercepted bean " + origin); return true; } } return false; } protected boolean isStereotypeWithInterceptor(Annotation stereotypeAnnotation, BeanManager beanManager) { for (Annotation annotation : stereotypeAnnotation.annotationType().getAnnotations()) { if (isStandardAnnotation(annotation)) { continue; } if (beanManager.isInterceptorBinding(annotation.annotationType()) || isStereotypeWithInterceptor(annotation, beanManager)) { return true; } } return false; } protected boolean isStandardAnnotation(Annotation annotation) { return annotation.annotationType().getName().startsWith(JAVA_BASE_PACKAGE) || annotation.annotationType().getName().startsWith(JAVAX_BASE_PACKAGE) || annotation.annotationType().getName().startsWith(JAKARTA_BASE_PACKAGE); } protected boolean isInternalPackage(String packageName) { return packageName.startsWith(OWB_BASE_PACKAGE) || packageName.startsWith(WELD_BASE_PACKAGE) || isDeltaSpikePackage(packageName); } protected boolean isDeltaSpikePackage(String packageName) { return packageName.startsWith(DS_BASE_PACKAGE); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/MockAwareInjectionTargetWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.testcontrol5.api.mock.DynamicMockManager; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.InjectionTarget; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.Set; public class MockAwareInjectionTargetWrapper implements InjectionTarget { private BeanManager beanManager; private final InjectionTarget wrapped; private final List beanTypes; private final List qualifiers; public MockAwareInjectionTargetWrapper(BeanManager beanManager, InjectionTarget wrapped, List beanTypes, List qualifiers) { this.beanManager = beanManager; this.wrapped = wrapped; this.beanTypes = beanTypes; this.qualifiers = qualifiers; } @Override public T produce(CreationalContext creationalContext) { DynamicMockManager mockManager = BeanProvider.getContextualReference(this.beanManager, DynamicMockManager.class, false); for (Type beanType : this.beanTypes) { Object mockInstance = mockManager.getMock( (Class)beanType, this.qualifiers.toArray(new Annotation[this.qualifiers.size()])); if (mockInstance != null) { return (T)mockInstance; } } return wrapped.produce(creationalContext); } @Override public void inject(T instance, CreationalContext ctx) { wrapped.inject(instance, ctx); } @Override public void postConstruct(T instance) { wrapped.postConstruct(instance); } @Override public void preDestroy(T instance) { wrapped.preDestroy(instance); } @Override public void dispose(T instance) { wrapped.dispose(instance); } @Override public Set getInjectionPoints() { return wrapped.getInjectionPoints(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/MockAwareProducerWrapper.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.testcontrol5.api.mock.DynamicMockManager; import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.InjectionPoint; import jakarta.enterprise.inject.spi.Producer; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.List; import java.util.Set; public class MockAwareProducerWrapper implements Producer { private final BeanManager beanManager; private final Producer wrapped; private final List beanTypes; private final List qualifiers; public MockAwareProducerWrapper(BeanManager beanManager, Producer wrapped, List beanTypes, List qualifiers) { this.beanManager = beanManager; this.wrapped = wrapped; this.beanTypes = beanTypes; this.qualifiers = qualifiers; } @Override public T produce(CreationalContext creationalContext) { DynamicMockManager mockManager = BeanProvider.getContextualReference(this.beanManager, DynamicMockManager.class, false); for (Type beanType : this.beanTypes) { Object mockInstance = mockManager.getMock( (Class)beanType, this.qualifiers.toArray(new Annotation[this.qualifiers.size()])); if (mockInstance != null) { return (T)mockInstance; } } return wrapped.produce(creationalContext); } @Override public void dispose(T instance) { wrapped.dispose(instance); } @Override public Set getInjectionPoints() { return wrapped.getInjectionPoints(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/MockExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.core.util.ClassDeactivationUtils; import org.apache.deltaspike.core.util.ServiceUtils; import org.apache.deltaspike.testcontrol5.spi.mock.MockFilter; import jakarta.enterprise.event.Observes; import jakarta.enterprise.inject.spi.AnnotatedMember; import jakarta.enterprise.inject.spi.BeanManager; import jakarta.enterprise.inject.spi.BeforeBeanDiscovery; import jakarta.enterprise.inject.spi.Extension; import jakarta.enterprise.inject.spi.InjectionTarget; import jakarta.enterprise.inject.spi.ProcessInjectionTarget; import jakarta.enterprise.inject.spi.ProcessProducer; import jakarta.enterprise.inject.spi.Producer; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MockExtension implements Extension, Deactivatable { private Boolean isActivated = true; private List mockFilters; protected void init(@Observes BeforeBeanDiscovery beforeBeanDiscovery) { isActivated = ClassDeactivationUtils.isActivated(getClass()); mockFilters = ServiceUtils.loadServiceImplementations(MockFilter.class); } public void onProcessInjectionTarget(@Observes ProcessInjectionTarget processInjectionTarget, BeanManager beanManager) { if (!isActivated) { return; } for (MockFilter mockFilter : mockFilters) { if (!mockFilter.isMockedImplementationSupported(beanManager, processInjectionTarget.getAnnotatedType())) { return; } } List qualifiers = new ArrayList(); for (Annotation annotation : processInjectionTarget.getAnnotatedType().getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } Typed typed = processInjectionTarget.getAnnotatedType().getAnnotation(Typed.class); List foundTypes = new ArrayList<>(); if (typed != null) { Collections.addAll(foundTypes, typed.value()); } else { foundTypes.addAll(extractTypes(processInjectionTarget.getAnnotatedType().getJavaClass())); } if (foundTypes.isEmpty()) { return; } final InjectionTarget originalInjectionTarget = processInjectionTarget.getInjectionTarget(); processInjectionTarget.setInjectionTarget(new MockAwareInjectionTargetWrapper( beanManager, originalInjectionTarget, foundTypes, qualifiers)); } public void onProcessProducer(@Observes ProcessProducer processProducer, BeanManager beanManager) { if (!isActivated) { return; } for (MockFilter mockFilter : mockFilters) { if (!mockFilter.isMockedImplementationSupported(beanManager, processProducer.getAnnotatedMember())) { return; } } final Producer originalProducer = processProducer.getProducer(); AnnotatedMember annotatedMember = processProducer.getAnnotatedMember(); List qualifiers = new ArrayList(); for (Annotation annotation : annotatedMember.getAnnotations()) { if (beanManager.isQualifier(annotation.annotationType())) { qualifiers.add(annotation); } } Typed typed = annotatedMember.getAnnotation(Typed.class); List foundTypes = new ArrayList(); if (typed != null) { Collections.addAll(foundTypes, typed.value()); } else if (annotatedMember.getBaseType() instanceof Class) { foundTypes.addAll(extractTypes((Class)annotatedMember.getBaseType())); } if (foundTypes.isEmpty()) { return; } processProducer.setProducer(new MockAwareProducerWrapper( beanManager, originalProducer, foundTypes, qualifiers)); } protected List extractTypes(Class currentClass) { List result = new ArrayList(); for (Class c = currentClass; c != Object.class && c != null; c = c.getSuperclass()) { result.add(c); } Collections.addAll(result, currentClass.getInterfaces()); return result; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/SimpleApplicationMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol5.api.mock.ApplicationMockManager; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @Typed(ApplicationMockManager.class) public class SimpleApplicationMockManager extends AbstractMockManager implements ApplicationMockManager { } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/mock/SimpleMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.mock; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol5.api.mock.ApplicationMockManager; import org.apache.deltaspike.testcontrol5.api.mock.DynamicMockManager; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Inject; import java.lang.annotation.Annotation; @RequestScoped @Typed(DynamicMockManager.class) public class SimpleMockManager extends AbstractMockManager { @Inject private ApplicationMockManager applicationMockManager; @Override public T getMock(Class beanClass, Annotation... qualifiers) { T result = applicationMockManager.getMock(beanClass, qualifiers); if (result != null) { return result; } return super.getMock(beanClass, qualifiers); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/request/ContextControlDecorator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.request; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.apache.deltaspike.testcontrol5.spi.ExternalContainer; import jakarta.decorator.Decorator; import jakarta.decorator.Delegate; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ConversationScoped; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import jakarta.inject.Singleton; import java.lang.annotation.Annotation; @Decorator public class ContextControlDecorator implements ContextControl { @Inject @Delegate private ContextControl wrapped; @Override public void startContexts() { wrapped.startContexts(); if (isManualScopeHandling()) { for (ExternalContainer externalContainer : CdiTestExtension.getActiveExternalContainers()) { externalContainer.startScope(Singleton.class); externalContainer.startScope(ApplicationScoped.class); externalContainer.startScope(RequestScoped.class); externalContainer.startScope(SessionScoped.class); externalContainer.startScope(ConversationScoped.class); } } } @Override public void stopContexts() { if (isManualScopeHandling()) { for (ExternalContainer externalContainer : CdiTestExtension.getActiveExternalContainers()) { externalContainer.stopScope(ConversationScoped.class); externalContainer.stopScope(SessionScoped.class); externalContainer.stopScope(RequestScoped.class); externalContainer.stopScope(ApplicationScoped.class); externalContainer.stopScope(Singleton.class); } } wrapped.stopContexts(); } @Override public void startContext(Class scopeClass) { wrapped.startContext(scopeClass); if (isManuallyHandledRequest(scopeClass)) { for (ExternalContainer externalContainer : CdiTestExtension.getActiveExternalContainers()) { externalContainer.startScope(scopeClass); } } } @Override public void stopContext(Class scopeClass) { wrapped.stopContext(scopeClass); if (isManuallyHandledRequest(scopeClass)) { for (ExternalContainer externalContainer : CdiTestExtension.getActiveExternalContainers()) { externalContainer.stopScope(scopeClass); } } } private boolean isManuallyHandledRequest(Class scopeClass) { return RequestScoped.class.equals(scopeClass) && isManualScopeHandling(); } private boolean isManualScopeHandling() { return !Boolean.TRUE.equals(CdiTestExtension.isAutomaticScopeHandlingActive()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/java/org/apache/deltaspike/testcontrol5/impl/validation/StandardContextTestControlValidator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.testcontrol5.impl.validation; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.spi.TestAware; import org.apache.deltaspike.testcontrol5.spi.TestControlValidator; import jakarta.enterprise.inject.Vetoed; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; @Vetoed public class StandardContextTestControlValidator implements TestAware, TestControlValidator { private static Boolean customContextControlDetected; private static ThreadLocal currentTestClass = new ThreadLocal(); private static ThreadLocal currentTestMethod = new ThreadLocal(); @Override public void validate(TestControl testControl) { checkActiveContextControlImplementation(); List> scopeClasses = new ArrayList>(); Collections.addAll(scopeClasses, testControl.startScopes()); validateSupportedScopes(scopeClasses, currentTestClass.get(), currentTestMethod.get()); } private void checkActiveContextControlImplementation() { if (customContextControlDetected != null) { return; } customContextControlDetected = !CdiContainerLoader.getCdiContainer().getContextControl() .getClass().getName().startsWith("org.apache.deltaspike."); } private void validateSupportedScopes(List> scopeClasses, Class declaringClass, Method testMethod) { if (Boolean.TRUE.equals(customContextControlDetected)) { return; } for (Class scopeClass : scopeClasses) { if (!scopeClass.getName().startsWith("jakarta.enterprise.context.")) { throw new IllegalStateException("Please remove " + scopeClass.getName() + " at " + declaringClass + (testMethod != null ? "#" + testMethod.getName() : "") + " from @" + TestControl.class.getName() + ". @" + TestControl.class.getName() + " only supports standard Scope-Annotations provided by the CDI-Specification. " + "Other Contexts start automatically or need to get started with a specific Management-API. " + "Examples: " + "@TransactionScoped gets started automatically once the @Transactional-Interceptor is used. " + "Whereas @WindowScoped starts once WindowContext#activateWindow gets called."); } } } @Override public void setTestClass(Class testClass) { currentTestClass.set(testClass); if (testClass == null) { currentTestClass.remove(); } } @Override public void setTestMethod(Method testMethod) { currentTestMethod.set(testMethod); if (testMethod == null) { currentTestMethod.remove(); } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/resources/META-INF/apache-deltaspike_test-container.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/resources/META-INF/beans.xml ================================================ ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol5.impl.mock.MockExtension ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.TestControlValidator ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol5.impl.validation.StandardContextTestControlValidator ================================================ FILE: deltaspike/modules/test-control5/impl/src/main/resources/META-INF/services/org.apache.deltaspike.testcontrol.spi.mock.MockFilter ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.testcontrol5.impl.mock.DefaultMockFilter ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/CustomMockManager.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5; import jakarta.annotation.Priority; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.testcontrol5.api.mock.DynamicMockManager; import org.apache.deltaspike.testcontrol5.impl.mock.SimpleMockManager; import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Alternative; import java.lang.annotation.Annotation; @Alternative @RequestScoped @Typed(DynamicMockManager.class) @Priority(1000) public class CustomMockManager extends SimpleMockManager { private static boolean isCalled; @Override public T getMock(Class beanClass, Annotation... qualifiers) { isCalled = true; return super.getMock(beanClass, qualifiers); } public static boolean isIsCalled() { return isCalled; } public static void resetInternals() { isCalled = false; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/InternalTestClassDeactivator.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5; import org.apache.deltaspike.core.spi.activation.ClassDeactivator; import org.apache.deltaspike.core.spi.activation.Deactivatable; import org.apache.deltaspike.testcontrol5.impl.mock.DefaultMockFilter; //just needed because the internal test-packages need to be handled differently public class InternalTestClassDeactivator implements ClassDeactivator { @Override public Boolean isActivated(Class targetClass) { return !DefaultMockFilter.class.equals(targetClass); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/InternalTestMockFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5; import org.apache.deltaspike.testcontrol5.impl.mock.DefaultMockFilter; public class InternalTestMockFilter extends DefaultMockFilter { private static final String DS_TEST_BASE_PACKAGE = "org.apache.deltaspike.test.testcontrol.mock."; protected boolean isInternalPackage(String packageName) { return super.isInternalPackage(packageName) && (!packageName.startsWith(DS_TEST_BASE_PACKAGE) || packageName.equals(CustomMockManager.class.getPackage().getName())); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/InterceptedBeanClassLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped @TestInterceptor public class InterceptedBeanClassLevel { public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/InterceptedBeanMethodLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptedBeanMethodLevel { @TestInterceptor public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/InterceptedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class InterceptedBeanTest { @Inject private InterceptionResultStorage interceptionResultStorage; @Inject private InterceptedBeanClassLevel interceptedBeanClassLevel; @Inject private InterceptedBeanMethodLevel interceptedBeanMethodLevel; @Test public void classLevelInterception() { assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanClassLevel.test(); assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } @Test public void methodLevelInterception() { assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanMethodLevel.test(); assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/InterceptionResultStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptionResultStorage { private boolean intercepted; public void markAsIntercepted() { this.intercepted = true; } public boolean isInterceptionDetected() { return intercepted; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/TestInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @InterceptorBinding @Target({ METHOD, TYPE }) @Retention(RUNTIME) public @interface TestInterceptor { } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/mock/uc015/TestInterceptorImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.mock.uc015; import jakarta.annotation.Priority; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @TestInterceptor @Interceptor @Priority(1000) public class TestInterceptorImplementation implements Serializable { @Inject private InterceptionResultStorage interceptionResultStorage; @AroundInvoke public Object intercept(InvocationContext ctx) throws Exception { this.interceptionResultStorage.markAsIntercepted(); return ctx.proceed(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/shared/ApplicationScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.shared; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationScopedBean { private int count = 0; private static int instanceCount = 0; @PostConstruct protected void init() { instanceCount++; } public int getCount() { return count; } public void increaseCount() { this.count++; } public void resetCount() { this.count = 0; } public static int getInstanceCount() { return instanceCount; } public static void resetInstanceCount() { instanceCount = 0; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/shared/RequestScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.shared; import jakarta.annotation.PostConstruct; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class RequestScopedBean { private int count = 0; private static int instanceCount = 0; @PostConstruct protected void init() { instanceCount++; } public int getCount() { return count; } public void increaseCount() { this.count++; } public static int getInstanceCount() { return instanceCount; } public static int resetInstanceCount() { return instanceCount = 0; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/shared/SessionScopedBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.shared; import jakarta.enterprise.context.SessionScoped; import java.io.Serializable; @SessionScoped public class SessionScopedBean implements Serializable { private static final long serialVersionUID = -6055362670706159152L; private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/shared/TestUtils.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.shared; import org.junit.jupiter.api.Test; import java.lang.reflect.Method; public abstract class TestUtils { private TestUtils() { } public static int getTestMethodCount(Class testClass) { int result = 0; for (Method method : testClass.getDeclaredMethods()) { if (method.isAnnotationPresent(Test.class)) { result++; } } return result; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc001/RequestAndSessionScopePerTestMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc001; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.SessionScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.TestUtils; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @ExtendWith(CdiTestExtension.class) //starts container once and one session + request per test-method //implicitly annotated with @TestControl without the default-scope settings public class RequestAndSessionScopePerTestMethodTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test //implicitly annotated with @TestControl and its default-values public void firstTest() { applicationScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); assertEquals(1, sessionScopedBean.getCount()); } @Test //implicitly annotated with @TestControl and its default-values public void secondTest() { applicationScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); assertEquals(1, sessionScopedBean.getCount()); } @BeforeAll public static void resetSharedState() { BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); RequestScopedBean.resetInstanceCount(); } @AfterAll public static void finalCheckAndCleanup() { int testCount = TestUtils.getTestMethodCount(RequestAndSessionScopePerTestMethodTest.class); if (RequestScopedBean.getInstanceCount() != testCount) { throw new IllegalStateException("unexpected instance count"); } RequestScopedBean.resetInstanceCount(); if (BeanProvider.getContextualReference(ApplicationScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc002/SessionScopePerTestClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc002; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.SessionScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.TestUtils; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) //starts container and session once and one request per test-method @TestControl(startScopes = SessionScoped.class) public class SessionScopePerTestClassTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); } @Test public void secondTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); } @BeforeAll public static void resetSharedState() { BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); RequestScopedBean.resetInstanceCount(); } @AfterAll public static void finalCheckAndCleanup() { int testCount = TestUtils.getTestMethodCount(SessionScopePerTestClassTest.class); if (RequestScopedBean.getInstanceCount() != testCount) { throw new IllegalStateException("unexpected instance count"); } RequestScopedBean.resetInstanceCount(); if (BeanProvider.getContextualReference(ApplicationScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } if (BeanProvider.getContextualReference(SessionScopedBean.class).getCount() != testCount) { throw new IllegalStateException("unexpected count"); } BeanProvider.getContextualReference(ApplicationScopedBean.class).resetCount(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc003/RequestAndSessionScopePerTestMethodTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc003; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestSuiteExtension; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestSuiteExtension.class) //starts container once and one session + request per test-method @Disabled //X TODO Disabled for now. We need to define how the test suites in Junit5 work with CDI //implicitly annotated with @TestControl without the default-scope settings public class RequestAndSessionScopePerTestMethodTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test //implicitly annotated with @TestControl and its default-values public void firstTest() { applicationScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); assertEquals(1, sessionScopedBean.getCount()); } @Test //implicitly annotated with @TestControl and its default-values public void secondTest() { applicationScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); assertEquals(0, sessionScopedBean.getCount()); sessionScopedBean.increaseCount(); assertEquals(1, sessionScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc003/SessionScopePerTestClassTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc003; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.SessionScopedBean; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestSuiteExtension; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestSuiteExtension.class) //starts container and session once and one request per test-method @Disabled //X TODO Disabled for now. We need to define how the test suites in Junit5 work with CDI @TestControl(startScopes = SessionScoped.class) public class SessionScopePerTestClassTest { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; @Test public void firstTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); } @Test public void secondTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc003/TestSuite.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc003; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestSuiteExtension; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.platform.suite.api.SelectClasses; import org.junit.platform.suite.api.Suite; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") /** * JUnit 5 replacement for the JUnit 4 Suite. * Each test class with @ExtendWith(CdiTestExtension.class) shares the same CDI container. */ @Suite @SelectClasses({ RequestAndSessionScopePerTestMethodTest.class, SessionScopePerTestClassTest.class }) @ExtendWith(CdiTestSuiteExtension.class) //starts container and session once and one request per test-method @Disabled //X TODO Disabled for now. We need to define how the test suites in Junit5 work with CDI public class TestSuite { @BeforeClass public static void resetSharedState() { ApplicationScopedBean.resetInstanceCount(); } @AfterClass public static void finalCheckAndCleanup() { if (ApplicationScopedBean.getInstanceCount() != 1) { throw new IllegalStateException("unexpected count"); } ApplicationScopedBean.resetInstanceCount(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc004/ProjectStageTestControlTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc004; import jakarta.enterprise.inject.Typed; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.test.testcontrol5.uc001.RequestAndSessionScopePerTestMethodTest; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) @TestControl(projectStage = ProjectStage.Development.class) //can be a custom stage @Typed() //needed due to RequestAndSessionScopePerTestMethodTest public class ProjectStageTestControlTest extends RequestAndSessionScopePerTestMethodTest //just to inherit the tests - to check that @TestControl#projectStage doesn't influence the default handling { @Inject private ProjectStage projectStage; @Test public void firstProjectStageTest() { assertEquals(ProjectStage.Development, this.projectStage); } @Test @TestControl(projectStage = ProjectStage.UnitTest.class) //can be a custom stage - e.g. for a special test public void secondProjectStageTest() { assertEquals(ProjectStage.UnitTest, this.projectStage); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc007/BaseTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc007; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.RequestScopedBean; import org.apache.deltaspike.test.testcontrol5.shared.SessionScopedBean; import jakarta.inject.Inject; public abstract class BaseTest { @Inject protected ApplicationScopedBean applicationScopedBean; @Inject protected SessionScopedBean sessionScopedBean; @Inject protected RequestScopedBean requestScopedBean; } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc007/ExtendedTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc007; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class ExtendedTest extends BaseTest { @Test public void inheritedInjectionTest() { applicationScopedBean.increaseCount(); sessionScopedBean.increaseCount(); assertEquals(0, requestScopedBean.getCount()); requestScopedBean.increaseCount(); assertEquals(1, requestScopedBean.getCount()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc008/BeforeAndAfterInjectionTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc008; import org.apache.deltaspike.test.testcontrol5.shared.ApplicationScopedBean; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertNotNull; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class BeforeAndAfterInjectionTest { @Inject private ApplicationScopedBean applicationScopedBean; private Integer foundValue; @BeforeEach public void before() { if (this.applicationScopedBean == null) { throw new IllegalStateException("injection failed"); } this.foundValue = this.applicationScopedBean.getCount(); } @Test public void injectionTest() { assertNotNull(this.applicationScopedBean); assertNotNull(this.foundValue); } @AfterEach public void after() { if (this.applicationScopedBean == null) { throw new IllegalStateException("injection failed"); } if (this.foundValue == null) { throw new IllegalStateException("different instance without initialized value found"); } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/InterceptedBeanClassLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped @TestInterceptor public class InterceptedBeanClassLevel { public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/InterceptedBeanMethodLevel.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptedBeanMethodLevel { @TestInterceptor public void test() { //do nothing - any method is fine } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/InterceptedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class InterceptedBeanTest { @Inject private InterceptionResultStorage interceptionResultStorage; @Inject private InterceptedBeanClassLevel interceptedBeanClassLevel; @Inject private InterceptedBeanMethodLevel interceptedBeanMethodLevel; @Test public void classLevelInterception() { assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanClassLevel.test(); assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } @Test public void methodLevelInterception() { assertFalse(this.interceptionResultStorage.isInterceptionDetected()); this.interceptedBeanMethodLevel.test(); assertTrue(this.interceptionResultStorage.isInterceptionDetected()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/InterceptionResultStorage.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import jakarta.enterprise.context.RequestScoped; @RequestScoped public class InterceptionResultStorage { private boolean intercepted; public void markAsIntercepted() { this.intercepted = true; } public boolean isInterceptionDetected() { return intercepted; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/TestInterceptor.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import jakarta.interceptor.InterceptorBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @InterceptorBinding @Target({ METHOD, TYPE }) @Retention(RUNTIME) public @interface TestInterceptor { } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc011/TestInterceptorImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc011; import jakarta.annotation.Priority; import jakarta.inject.Inject; import jakarta.interceptor.AroundInvoke; import jakarta.interceptor.Interceptor; import jakarta.interceptor.InvocationContext; import java.io.Serializable; @TestInterceptor @Interceptor @Priority(1000) public class TestInterceptorImplementation implements Serializable { @Inject private InterceptionResultStorage interceptionResultStorage; @AroundInvoke public Object intercept(InvocationContext ctx) throws Exception { this.interceptionResultStorage.markAsIntercepted(); return ctx.proceed(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc012/ApplicationScopedBeanTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc012; import org.apache.deltaspike.core.api.provider.BeanProvider; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class ApplicationScopedBeanTest { @Inject private ApplicationScopedTestBean testBean; @Inject private ApplicationScopedTestBeanClient testBeanClient; @Test public void beanAccess() { this.testBean.setValue(0); assertEquals(1, this.testBeanClient.getNextValue()); assertEquals(1, this.testBean.getValue()); } @AfterAll public static void finalCheck() { int value = BeanProvider.getContextualReference(ApplicationScopedTestBean.class).getValue(); int nextValue = BeanProvider.getContextualReference(ApplicationScopedTestBeanClient.class).getNextValue(); if (value == 0) { throw new IllegalStateException("new application-scoped bean instance was created"); } if (nextValue == 1) { throw new IllegalStateException("new application-scoped bean instance was created"); } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc012/ApplicationScopedTestBean.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc012; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ApplicationScopedTestBean { private int value = 0; public void increaseValue() { this.value++; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc012/ApplicationScopedTestBeanClient.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc012; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @ApplicationScoped public class ApplicationScopedTestBeanClient { @Inject private ApplicationScopedTestBean testBean; public int getNextValue() { this.testBean.increaseValue(); return this.testBean.getValue(); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc013/ContainerConfigTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc013; import org.apache.deltaspike.core.api.projectstage.ProjectStage; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestSuiteExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) public class ContainerConfigTest { @Test @TestControl(projectStage = ProjectStage.UnitTest.class) //just for internal tests public void configForTestContainerStageUnitTest() { assertNotNull(CdiTestSuiteExtension.getTestContainerConfig()); assertEquals("jdbc:hsqldb:mem:demoDB", CdiTestSuiteExtension.getTestContainerConfig().getProperty("demoDatabase.JdbcUrl")); } @Test @TestControl(projectStage = ProjectStage.IntegrationTest.class) //just for internal tests public void configForTestContainerStageIntegrationTest() { assertNotNull(CdiTestSuiteExtension.getTestContainerConfig()); assertEquals("jdbc:hsqldb:file:demoDB", CdiTestSuiteExtension.getTestContainerConfig().getProperty("demoDatabase.JdbcUrl")); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/DefaultTestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class DefaultTestService implements TestService { @Override public String getValue() { return "default-result"; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestBeanClassFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import org.apache.deltaspike.core.api.config.ConfigResolver; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.core.util.ClassUtils; import org.apache.deltaspike.testcontrol5.api.TestControl; //!!!not!!! needed with cdi 1.1+ and @Priority (which is the target of this use-case) //only needed because our test-suite is based on cdi v1.0 //also useful to test DELTASPIKE-1337 public class TestBeanClassFilter implements ClassFilter { @Override public boolean isFiltered(Class targetClass) { if (!targetClass.getName().startsWith("org.apache.deltaspike.test.")) { return false; } String currentTestOrigin = ConfigResolver.getPropertyValue(TestControl.class.getName()); if (currentTestOrigin == null) //no known origin (no @TestControl is used) { //filter all classes which are located in packages using tests with class-filters //(since we test the feature with ambiguous beans which isn't valid without filtering) return getClass().getPackage().getName().equals(targetClass.getPackage().getName()); } else { Class currentOrigin = ClassUtils.tryToLoadClassForName(currentTestOrigin); //origin is in one of the packages for class-filtering tests if (getClass().getPackage().getName().equals(currentOrigin.getPackage().getName())) { TestControl testControl = currentOrigin.getAnnotation(TestControl.class); return ClassUtils.tryToInstantiateClass(testControl.classFilter()).isFiltered(targetClass); } return isInSamePackage(targetClass); } } private boolean isInSamePackage(Class targetClass) { return targetClass.getPackage().getName().equals(getClass().getPackage().getName()); } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestLabeled.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import org.apache.deltaspike.testcontrol5.api.TestControl; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target(TYPE) public @interface TestLabeled { Class value(); } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestLabeledAlternativeFilter.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import org.apache.deltaspike.core.spi.filter.ClassFilter; import org.apache.deltaspike.testcontrol5.api.TestControl; import jakarta.enterprise.inject.Alternative; public abstract class TestLabeledAlternativeFilter implements ClassFilter { private final Class activeLabel; protected TestLabeledAlternativeFilter(Class activeLabel) { this.activeLabel = activeLabel; } @Override public boolean isFiltered(Class targetClass) { if (!targetClass.isAnnotationPresent(Alternative.class)) { return false; } TestLabeled testLabeled = targetClass.getAnnotation(TestLabeled.class); if (testLabeled == null) { return false; } if (testLabeled.value().equals(activeLabel)) { return false; } return true; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestService.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; public interface TestService { String getValue(); } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestServiceLabelX.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabeled(TestServiceLabelXTest.TestLabelX.class) @ApplicationScoped public class TestServiceLabelX implements TestService { @Override public String getValue() { return "result-x"; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestServiceLabelXTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) @TestControl( activeAlternativeLabel = TestServiceLabelXTest.TestLabelX.class, classFilter = TestServiceLabelXTest.LabelXFilter.class) public class TestServiceLabelXTest { @Inject private TestService testService; @Test public void resultX() { assertEquals("result-x", testService.getValue()); } public static class TestLabelX implements TestControl.Label { } //replaces the text based config of labeled-alternatives public static class LabelXFilter extends TestLabeledAlternativeFilter { public LabelXFilter() { super(TestLabelX.class); } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestServiceLabelY.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.inject.Alternative; @Alternative @TestLabeled(TestServiceLabelYTest.TestLabelY.class) @ApplicationScoped public class TestServiceLabelY implements TestService { @Override public String getValue() { return "result-y"; } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/java/org/apache/deltaspike/test/testcontrol5/uc019/TestServiceLabelYTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.testcontrol5.uc019; import org.apache.deltaspike.testcontrol5.api.TestControl; import org.apache.deltaspike.testcontrol5.api.junit.CdiTestExtension; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import jakarta.inject.Inject; import static org.junit.jupiter.api.Assertions.assertEquals; //Usually NOT needed! Currently only needed due to our arquillian-setup @Tag("SeCategory") @ExtendWith(CdiTestExtension.class) @TestControl( activeAlternativeLabel = TestServiceLabelYTest.TestLabelY.class, classFilter = TestServiceLabelYTest.LabelYFilter.class) public class TestServiceLabelYTest { @Inject private TestService testService; @Test public void resultY() { assertEquals("result-y", testService.getValue()); } public static class TestLabelY implements TestControl.Label { } //replaces the text based config of labeled-alternatives public static class LabelYFilter extends TestLabeledAlternativeFilter { public LabelYFilter() { super(TestLabelY.class); } } } ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/apache-deltaspike.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # deltaspike.testcontrol.mock-support.allow_mocked_beans=true deltaspike.testcontrol.mock-support.allow_mocked_producers=true org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.test.testcontrol5.InternalTestClassDeactivator deltaspike.testcontrol.test-container.config-file.UnitTest=META-INF/test/dsTestContainerBootConfig.properties #only needed because our test-suite is based on cdi v1.0. with v1.1+ and @Priority (which is the target of this use-case) the following part isn't needed: org.apache.deltaspike.core.spi.filter.ClassFilter=org.apache.deltaspike.test.testcontrol5.uc019.TestBeanClassFilter ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/apache-deltaspike_test-container.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) #just random config-entries demoDatabase.JdbcUrl=jdbc:hsqldb:file:demoDB ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/beans.xml ================================================ org.apache.deltaspike.test.testcontrol5.uc019.TestServiceLabelX org.apache.deltaspike.test.testcontrol5.uc019.TestServiceLabelY ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/services/org.apache.deltaspike.core.spi.alternative.AlternativeBeanClassProvider ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.testcontrol.uc016.CustomAlternativeBeanClassProvider ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/services/org.apache.deltaspike.testcontrol5.spi.mock.MockFilter ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.testcontrol5.InternalTestMockFilter ================================================ FILE: deltaspike/modules/test-control5/impl/src/test/resources/META-INF/test/dsTestContainerBootConfig.properties ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #can be used to configure the underlying test-container #(currently the only container supported by deltaspike #(out-of-the-box) which supports that config is openejb-embedded) #just random config-entries demoDatabase.JdbcUrl=jdbc:hsqldb:mem:demoDB ================================================ FILE: deltaspike/modules/test-control5/pom.xml ================================================ 4.0.0 org.apache.deltaspike.modules modules-project 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike.modules test-control5-module-project pom Apache DeltaSpike Test-Control5-Module (JUnit 5) api impl ================================================ FILE: deltaspike/parent/code/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent 2.0.2-SNAPSHOT ../pom.xml parent-code pom Apache DeltaSpike Code Parent Apache DeltaSpike Parent for container projects ${java.io.tmpdir}/deltaspike-arquillian-containers 31.0.0.Final 2.0.11 5.0.1.Final 6.2024.2 org.jboss.arquillian arquillian-bom ${arquillian.version} import pom jakarta.annotation jakarta.annotation-api ${jakarta.annotation-api.version} provided jakarta.inject jakarta.inject-api ${jakarta.atinject-api.version} provided jakarta.enterprise jakarta.enterprise.cdi-api ${jakarta.cdi-api.version} provided jakarta.interceptor jakarta.interceptor-api ${jakarta.interceptor-api.version} provided jakarta.el jakarta.el-api ${jakarta.el-api.version} provided jakarta.transaction jakarta.transaction-api ${jakarta.transaction-api.version} provided org.apache.tomcat tomcat-servlet-api ${tomcat.version} provided org.apache.geronimo.specs geronimo-jpa_2.2_spec 1.1 provided org.apache.openwebbeans openwebbeans-impl ${owb.version} provided org.apache.openwebbeans openwebbeans-spi ${owb.version} provided org.apache.openwebbeans.arquillian owb-arquillian-standalone ${owb.version} test org.jboss.arquillian.testenricher arquillian-testenricher-cdi-jakarta ${arquillian.version} test org.apache.deltaspike.test test-utils ${project.version} test org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} UnitTest ${cdicontainer.version} org.apache.maven.plugins maven-jar-plugin test-jar JBossArchive JBoss-Archive JBoss Archive https://repository.jboss.org/nexus/content/groups/public JBossSnapshots JBoss-Snapshots JBoss Snapshots https://repository.jboss.org/nexus/content/repositories/snapshots/ OWB true owb-${owb.version} apache-snapshot-repository https://repository.apache.org/snapshots/ false true org.apache.maven.plugins maven-surefire-plugin ${cdicontainer.version} org.apache.deltaspike.test.category.WebProfileCategory, org.apache.deltaspike.test.category.WebEEProfileCategory, org.apache.deltaspike.test.category.FullProfileCategory, org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory jakarta.annotation jakarta.annotation-api ${jakarta.annotation-api.version} provided jakarta.inject jakarta.inject-api ${jakarta.atinject-api.version} provided jakarta.enterprise jakarta.enterprise.cdi-api ${jakarta.cdi-api.version} provided jakarta.interceptor jakarta.interceptor-api ${jakarta.interceptor-api.version} provided jakarta.el jakarta.el-api ${jakarta.el-api.version} provided jakarta.transaction jakarta.transaction-api ${jakarta.transaction-api.version} provided org.apache.tomcat tomcat-servlet-api ${tomcat.version} provided org.apache.geronimo.specs geronimo-jpa_2.2_spec 1.1 provided org.apache.openwebbeans openwebbeans-impl ${owb.version} provided org.apache.openwebbeans openwebbeans-spi ${owb.version} provided org.apache.openwebbeans.arquillian owb-arquillian-standalone ${owb.version} test org.jboss.arquillian.testenricher arquillian-testenricher-cdi-jakarta ${arquillian.version} test Weld false 5.1.2.Final weld-${weld.version} org.jboss.weld weld-core-bom ${weld.version} pom import org.jboss.weld weld-core-impl org.jboss.weld.module weld-ejb org.jboss.weld.module weld-jsf org.jboss.weld.module weld-jta org.jboss.weld.module weld-web org.jboss.weld.servlet weld-servlet-shaded org.jboss.weld.servlet weld-servlet-core org.jboss.weld.se weld-se-shaded org.jboss.weld.se weld-se-core org.jboss.weld weld-api org.jboss.weld weld-spi jakarta.el jakarta.el-api ${jakarta.el-api.version} test jakarta.transaction jakarta.transaction-api ${jakarta.transaction-api.version} test jakarta.interceptor jakarta.interceptor-api ${jakarta.interceptor-api.version} org.slf4j slf4j-simple ${weld.sfl4j} test org.hibernate hibernate-validator 8.0.0.Final test org.jboss.arquillian.container arquillian-weld-embedded ${arquillian-weld.version} test maven-surefire-plugin ${cdicontainer.version} org.apache.deltaspike.test.category.WebProfileCategory, org.apache.deltaspike.test.category.WebEEProfileCategory, org.apache.deltaspike.test.category.FullProfileCategory, org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory tomee-build-managed 10.0 4.0.3 owb-${owb.version} org.apache.tomee jakartaee-api ${jakartaeeapi.version} provided org.apache.tomee apache-tomee webprofile ${tomee.version} test zip org.apache.tomee arquillian-tomee-remote ${tomee.version} commons-logging commons-logging 1.1.1 test org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} ${tomee.version} tomee-build-managed UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.WebEEProfileCategory, org.apache.deltaspike.test.category.SeCategory wildfly-managed 5.1.2.Final weld-${weld.version} org.jboss.weld weld-core-impl ${weld.version} provided org.wildfly.arquillian wildfly-arquillian-container-managed ${wildfly.arquillian.version} test org.jboss.arquillian.protocol arquillian-protocol-servlet-jakarta ${arquillian.version} test org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} wildfly-managed arquillian-jboss.xml UnitTest ${cdicontainer.version} ${jacoco.agent} org.apache.deltaspike.test.category.FullProfileCategory, org.apache.deltaspike.test.category.SeCategory wildfly-build-managed 5.1.2.Final weld-${weld.version} org.jboss.weld weld-core-impl ${weld.version} provided org.wildfly.arquillian wildfly-arquillian-container-managed ${wildfly.arquillian.version} test org.jboss.arquillian.protocol arquillian-protocol-servlet-jakarta ${arquillian.version} test jakarta.servlet jakarta.servlet-api ${jakarta.servlet-api.version} org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} wildfly-build-managed arquillian-jboss.xml ${container.unpack.directory}/wildfly-${wildfly.version} UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.EnterpriseArchiveProfileCategory, org.apache.deltaspike.test.category.FullProfileCategory, org.apache.deltaspike.test.category.SeCategory org.apache.maven.plugins maven-dependency-plugin unpack-wf process-test-classes unpack org.wildfly wildfly-dist ${wildfly.version} ${container.unpack.directory} zip false wildfly-remote weld-${weld.version} org.jboss.weld weld-core-impl ${weld.version} provided org.wildfly.arquillian wildfly-arquillian-container-remote ${wildfly.arquillian.version} test org.jboss.arquillian.protocol arquillian-protocol-servlet-jakarta ${arquillian.version} test org.apache.maven.plugins maven-surefire-plugin ${maven.surefire.plugin.version} wildfly-remote arquillian-jboss.xml UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.FullProfileCategory, org.apache.deltaspike.test.category.SeCategory payara-embedded 5.0.1.Final weld-${weld.version} org.jboss.weld weld-core-impl ${weld.version} provided fish.payara.extras payara-embedded-all ${payara.version} test fish.payara.arquillian arquillian-payara-server-embedded 3.0.alpha8 test org.apache.maven.plugins maven-surefire-plugin payara-build-managed UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.SeCategory payara-build-managed 5.0.1.Final weld-${weld.version} org.jboss.weld weld-core-impl ${weld.version} provided jakarta.servlet jakarta.servlet-api ${jakarta.servlet-api.version} fish.payara.arquillian arquillian-payara-server-managed 3.0.alpha8 test org.apache.maven.plugins maven-surefire-plugin payara-build-managed ${container.unpack.directory}/payara6 UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.SeCategory org.apache.maven.plugins maven-dependency-plugin unpack-payara generate-test-resources unpack fish.payara.distributions payara ${payara.version} ${container.unpack.directory} zip false org.apache.maven.plugins maven-antrun-plugin prepare-payara process-test-resources run glassfish-build-managed 5.1.2.Final weld-${weld.version} 7.0.13 org.jboss.weld weld-core-impl ${weld.version} provided jakarta.servlet jakarta.servlet-api ${jakarta.servlet-api.version} org.omnifaces.arquillian arquillian-glassfish-server-managed 1.4 test org.apache.maven.plugins maven-surefire-plugin glassfish-build-managed ${container.unpack.directory}/glassfish7 UnitTest ${cdicontainer.version} org.apache.deltaspike.test.category.SeCategory org.apache.maven.plugins maven-dependency-plugin unpack-glassfish generate-test-resources unpack org.glassfish.main.distributions glassfish ${glassfish.version} ${container.unpack.directory} zip false org.apache.maven.plugins maven-antrun-plugin prepare-glassfish process-test-resources run ================================================ FILE: deltaspike/parent/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike-project 2.0.2-SNAPSHOT ../pom.xml parent pom Apache DeltaSpike Parent Apache DeltaSpike Parent jira https://issues.apache.org/jira/browse/DELTASPIKE cjenkins http://builds.apache.org/ 2011 11 4.0.3 5.1.7.Final 10.1.5 10.0.1 ${owb.version} ${owb.version} 4.13.2 5.14.4 1.8.0.Final 4.0.2 10.1.13 9.9.1 3.5.5 3.5.0 3.1.2 2.4 2.16 3.10.1 3.2.0 3.0 1.3 0.7.4.201502262128 4.0.0.Final version="[$(version;==;${deltaspike.osgi.version.clean}),$(version;=+;${deltaspike.osgi.version.clean}))" version="[$(version;===;${deltaspike.osgi.version.clean}),$(version;==+;${deltaspike.osgi.version.clean}))" [$(version;==;$(@)),$(version;+;$(@))) org.springframework.*;version="[3,4)", !${deltaspike.osgi.export.pkg}, org.apache.deltaspike.*;${deltaspike.osgi.import.deltaspike.version}, ${deltaspike.osgi.import.before.defaults}, ${deltaspike.osgi.import.defaults}, ${deltaspike.osgi.import.additional}, * false !* ${deltaspike.osgi.export.pkg};${deltaspike.osgi.version} version=${project.version} -split-package:=first ${deltaspike.osgi.import.pkg} ${project.groupId}.${project.artifactId} false 2.0.0 4.0.0 2.0.0 2.0.0 5.0.0 3.1.0 2.0.0 6.0.0 coverage org.jboss.arquillian.extension arquillian-jacoco 1.0.0.Alpha7 test org.jacoco org.jacoco.core ${jacoco.version} test org.jacoco jacoco-maven-plugin ${jacoco.version} jacoco.agent prepare-agent report post-integration-test report jdk17+ [17,) org.apache.maven.plugins maven-surefire-plugin --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.rmi/sun.rmi.transport=ALL-UNNAMED code gpetracek Gerhard Petracek gpetracek@apache.org IRIAN.at, Austria http://www.irian.at/ PMC +1 lightguardjp Jason Porter lightguardjp@apache.org PMC -7 mbenson Matt Benson mbenson@apache.org PMC -6 struberg Mark Struberg struberg@apache.org PMC VP +1 arne Arne Limburg arne@apache.org PMC +1 rdebusscher Rudy De Busscher rdebusscher@apache.org C4J, Belgium PMC +1 chkal Christian Kaltepoth chkal@apache.org PMC +1 cmoulliard Charles Moulliard cmoulliard@apache.org PMC +1 thug Thomas Hug thug@apache.org Committer +1 johndament John D. Ament johndament@apache.org PMC -5 tandraschko Thomas Andraschko tandraschko@apache.org PMC +1 rafabene Rafael Benevides rafabene@apache.org Committer -3 rsmeral Ron Smeral rsmeral@apache.org Committer +1 danielsoro Daniel Cunha danielsoro@apache.org Committer -3 hwellmann Harald Wellmann hwellmann@apache.org Committer +1 manovotn Matej Novotny manovotn@apache.org Committer +1 cbeikov Christian Beikov cbeikov@apache.org Committer +1 junit junit ${junit.version} test org.jboss.arquillian arquillian-bom ${arquillian.version} import pom jakarta.annotation jakarta.annotation-api ${jakarta.annotation-api.version} provided jakarta.inject jakarta.inject-api ${jakarta.atinject-api.version} provided jakarta.enterprise jakarta.enterprise.cdi-api ${jakarta.cdi-api.version} provided jakarta.interceptor jakarta.interceptor-api ${jakarta.interceptor-api.version} provided jakarta.el jakarta.el-api ${jakarta.el-api.version} provided jakarta.transaction jakarta.transaction-api ${jakarta.transaction-api.version} provided jakarta.persistence jakarta.persistence-api ${jakarta.persistence-api.version} provided org.apache.tomcat tomcat-servlet-api ${tomcat.version} provided org.hamcrest hamcrest-library ${hamcrest.version} test org.owasp.encoder encoder 1.2.2 org.mockito mockito-all 1.9.5 test junit junit org.jboss.arquillian.junit arquillian-junit-container ${arquillian.version} test maven-jar-plugin ${maven.jar.plugin.version} true maven-surefire-plugin ${maven.surefire.plugin.version} false org.apache.maven.surefire surefire-junit47 ${maven.surefire.plugin.version} maven-dependency-plugin org.apache.maven.plugins ${maven.dependency.plugin.version} org.apache.felix maven-bundle-plugin ${maven.bundle.plugin.version} org.apache.maven.plugins maven-assembly-plugin ${maven.assembly.plugin.version} org.apache.maven.plugins maven-antrun-plugin javadoc.resources generate-sources run javadoc.site.copy site run org.apache.maven.plugins maven-checkstyle-plugin ${maven.checkstyle.plugin.version} deltaspike/default-checks.xml deltaspike/asf-header.txt true verify-style verify check org.apache.deltaspike checkstyle-rules ${project.version} org.apache.maven.plugins maven-compiler-plugin ${maven.compiler.plugin.version} ${java.version} org.apache.felix maven-bundle-plugin ${maven.bundle.plugin.version} true ${project.artifactId} ${deltaspike.osgi.symbolic.name} ${deltaspike.osgi.activator} ${deltaspike.osgi.export} ${deltaspike.osgi.import} ${deltaspike.osgi.dynamic} ${deltaspike.osgi.private.pkg} Apache DeltaSpike ${project.version} ${cdi.osgi.beans-managed} DeltaSpike;${project.artifactId}=${project.version} <_versionpolicy>${deltaspike.osgi.import.default.version} <_failok>${deltaspike.osgi.failok} ${deltaspike.osgi.require.capability} ${deltaspike.osgi.provide.capability} versions validate cleanVersions ${project.version} org.apache.maven.plugins maven-checkstyle-plugin ${maven.checkstyle.plugin.version} deltaspike/default-checks.xml deltaspike/asf-header.txt ================================================ FILE: deltaspike/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike deltaspike-project 2.0.2-SNAPSHOT pom Apache DeltaSpike Sources Apache DeltaSpike CDI Extensions. http://deltaspike.apache.org https://svn.apache.org/repos/infra/sites/deltaspike/javadoc/${project.version} checkstyle-rules parent test-utils core cdictrl modules examples dist org.apache.rat apache-rat-plugin 0.13 .idea/**/* readme/**/* **/*.log **/target/** test-ee7/target/** **/*.iml **/MANIFEST.MF org.apache.maven.plugins maven-javadoc-plugin 3.6.3 UTF-8 false 11 none org.apache.deltaspike.example.*:org.apache.deltaspike.playground*:org.apache.deltaspike.test.*:org.apache.deltaspike.cdise.tck*:org.apache.deltaspike.cdise.servlet*:*impl* Core Module org.apache.deltaspike.core.* Bean Validation Module org.apache.deltaspike.beanvalidation* Container Control Module org.apache.deltaspike.cdise.api* Data Module org.apache.deltaspike.data.* JPA Module org.apache.deltaspike.jpa.* JSF Module org.apache.deltaspike.jsf.* Partial Bean Module org.apache.deltaspike.partialbean.* Scheduler Module org.apache.deltaspike.scheduler.* Security Module org.apache.deltaspike.security.* Servlet Module org.apache.deltaspike.servlet.* Test Control Module org.apache.deltaspike.testcontrol.* Proxy Module org.apache.deltaspike.proxy.* org.apache.maven.plugins maven-scm-publish-plugin ${project.reporting.outputDirectory}/apidocs scm:svn:${svn.scmPubUrl} true ${svn.scmPubCheckoutDirectory} deltaspike-site org.apache.rat apache-rat-plugin validate check ================================================ FILE: deltaspike/readme/ReleaseNotes-0.2-incubating.txt ================================================ Apache DeltaSpike-0.2-incubating Release Notes Sub-task [DELTASPIKE-15] - review and discuss @DefaultBean [DELTASPIKE-64] - review and discuss @Secured [DELTASPIKE-65] - review and discuss @SecurityBindingType [DELTASPIKE-83] - unit and integration tests for global alternatives [DELTASPIKE-93] - update java-se example [DELTASPIKE-99] - refactor the owb-se example to a generic se-example [DELTASPIKE-106] - re-visit separation of container control and context management [DELTASPIKE-116] - unit and integration tests for @ConfigProperty [DELTASPIKE-131] - Discuss the concept of exception handlers [DELTASPIKE-133] - Discuss using exception handling should be easy [DELTASPIKE-138] - unit and integration tests for @SecurityBindingType [DELTASPIKE-149] - unit and integration tests for @MessageContextConfig - static usage [DELTASPIKE-154] - unit and integration tests for Message and MessageContext - dynamic usage [DELTASPIKE-159] - unit and integration tests for @ExceptionHandler Bug [DELTASPIKE-95] - ConfigResolver#getAllPropertyValues implementation and javadoc out of sync [DELTASPIKE-124] - tests in ContainerCtrlTckTest don't stop contexts at the end [DELTASPIKE-135] - [CdiControl] make Weld and OWB dependencies provided [DELTASPIKE-136] - [CdiControl] cdictrl-owb should only use the Session mocks if the servlet-api is available Improvement [DELTASPIKE-56] - Add BeanManagerProvider.getRequiredBeanManager() method [DELTASPIKE-67] - auto-veto for (custom) project-stage beans [DELTASPIKE-72] - BeanManagerProvider#getBeanManager should fail fast if there is no bean-manager [DELTASPIKE-90] - default ConfigSource should have different ordinals [DELTASPIKE-97] - fallback for the lookup via ServiceLoader [DELTASPIKE-98] - fallback for the lookup of resource bundles [DELTASPIKE-100] - improve the bootstrapping module for java-se for simple use-cases [DELTASPIKE-112] - improved root-bean-manager support [DELTASPIKE-120] - BeanProvider: add convenience methods without the 'optional' flag [DELTASPIKE-123] - convenience methods for CdiContainer [DELTASPIKE-126] - Include SecurityParameterBinding support for SecurityBindingType feature [DELTASPIKE-130] - Remove custom ProjectStageProducer logic [DELTASPIKE-151] - Provide lookup method with Map result [DELTASPIKE-152] - unified package names New Feature [DELTASPIKE-61] - global alternatives [DELTASPIKE-69] - @SecurityBindingType [DELTASPIKE-70] - @Secured [DELTASPIKE-92] - ContainerControl API + impls [DELTASPIKE-114] - @ConfigProperty based on ConfigResolver [DELTASPIKE-121] - add a method to inject CDI beans in a particular instance [DELTASPIKE-127] - credential based login/logout [DELTASPIKE-137] - [CdiControl] implement ContainerControl for embedded OpenEJB + OWB [DELTASPIKE-146] - Type Safe Message - Basic [DELTASPIKE-148] - optional @MessageContextConfig - static usage [DELTASPIKE-153] - Message and MessageContext - dynamic usage [DELTASPIKE-158] - @ExceptionHandler Task [DELTASPIKE-57] - Add Apache TomEE managed Arquillian adapter to itests [DELTASPIKE-71] - create deltaspike security module [DELTASPIKE-85] - refactoring of util classes [DELTASPIKE-86] - change the test-config to allow to restrict tests to a specific environment [DELTASPIKE-91] - re-visit test setup [DELTASPIKE-101] - add incubating disclaimer [DELTASPIKE-103] - Integration testing on WebLogic Server 12c [DELTASPIKE-107] - add BackwardCompatibility profile [DELTASPIKE-108] - add profile for snapshots [DELTASPIKE-109] - weekly ci builds for different versions of owb and weld [DELTASPIKE-117] - create profile jbossas-build-managed-7 [DELTASPIKE-125] - refactor "deploy"-methods of arquillian tests [DELTASPIKE-129] - re-visit visibility of AnnotationBuilder, ImmutableInjectionPoint, InjectableMethod and ParameterValueRedefiner [DELTASPIKE-141] - move internal test artifacts to group-id orgapache.deltaspike.test [DELTASPIKE-142] - remove @author in javadoc [DELTASPIKE-144] - create profile jbossas-remote-7 [DELTASPIKE-163] - preparations for v0.2 ================================================ FILE: deltaspike/readme/ReleaseNotes-0.3-incubating.txt ================================================ Apache DeltaSpike-0.3-incubating Release Notes Sub-task [DELTASPIKE-38] - unit and integration tests for DeltaSpikeConfig [DELTASPIKE-54] - review and discuss DefaultAnnotation [DELTASPIKE-55] - review and discuss AnnotationInstanceProvider [DELTASPIKE-62] - Discuss security module [DELTASPIKE-74] - unit and integration tests for @Secured [DELTASPIKE-75] - documentation for @Secured [DELTASPIKE-77] - review and discuss Identity API [DELTASPIKE-78] - review and discuss Authentication API [DELTASPIKE-79] - review and discuss Authorization API [DELTASPIKE-81] - review and discuss Identity Management [DELTASPIKE-82] - review and discuss external authentication [DELTASPIKE-84] - documentation for global alternatives [DELTASPIKE-115] - documentation for @ConfigProperty [DELTASPIKE-139] - documentation for @SecurityBindingType [DELTASPIKE-143] - documentation for SecurityParameterBinding [DELTASPIKE-147] - documentation for @MessageTemplate and @MessageBundle [DELTASPIKE-150] - documentation for @MessageContextConfig - static usage [DELTASPIKE-155] - documentation for Message and MessageContext - dynamic usage [DELTASPIKE-160] - documentation for @ExceptionHandler [DELTASPIKE-170] - documentation for AnnotationInstanceProvider [DELTASPIKE-171] - unit and integration tests for AnnotationInstanceProvider [DELTASPIKE-176] - unit and integration tests for @Transactional [DELTASPIKE-177] - documentation for @Transactional [DELTASPIKE-179] - unit and integration tests for @TransactionScoped [DELTASPIKE-183] - unit and integration tests for TransactionHelper [DELTASPIKE-184] - documentation for TransactionHelper [DELTASPIKE-226] - unit and integration tests for minimal type-safe messages Bug [DELTASPIKE-145] - autom. check of license header in test files [DELTASPIKE-166] - integration test module can't run tests with resources [DELTASPIKE-167] - remove ReflectionUtil security methods [DELTASPIKE-168] - fix build config [DELTASPIKE-173] - @ConfigProperty for string properties [DELTASPIKE-185] - Our @Transactional interceptor also tries to handle @PersistenceContexts [DELTASPIKE-186] - doc is not up to date regarding configsource [DELTASPIKE-189] - cdictrl/impl-openejb breaks the sonar build [DELTASPIKE-191] - get rid of BeanManagerProvider#setTestMode() [DELTASPIKE-196] - review ConfigProperty and Converter logic [DELTASPIKE-199] - MessageBundle must only be used on interfaces [DELTASPIKE-200] - handle configuration issues in MessageBundles as DefinitionErrors [DELTASPIKE-205] - LocaleResolver#getLocale() doesn't get invoked [DELTASPIKE-206] - NPE in OpenWebBeansContainerControl#getBeanManager [DELTASPIKE-209] - ShrinkWrap.create(WebArchive.class,..)..addAsManifestResource(.., "beans.xml") not spec conform [DELTASPIKE-211] - ExcludeExtension uses wrong observed event type [DELTASPIKE-212] - replace ProcessAnnotatedType with ProcessAnnotatedType without type restriction [DELTASPIKE-213] - move atinject-api, jcdi-api and interceptors-api dependencies to the container configuration [DELTASPIKE-218] - ExceptionHandler observer chain is broken with same ordinal [DELTASPIKE-231] - add multiple Resource Sources in the MessageContext [DELTASPIKE-232] - Messages should be Serializable [DELTASPIKE-233] - ClassUtils does unnecessary doPrivileged [DELTASPIKE-235] - Always package categories to our unit test @Deployments [DELTASPIKE-237] - implement shutdown hook for ConfigResolver [DELTASPIKE-239] - Test failure for ConfigResolver on jdk7 [DELTASPIKE-240] - Security test failedLogin fails if executed after failedForcedReLogin [DELTASPIKE-248] - missing check of EntityTransaction#getRollbackOnly in ResourceLocalPersistenceStrategy Improvement [DELTASPIKE-96] - Give names to tests and shrinkwrap archives [DELTASPIKE-161] - veto internal beans annotated with @Vetoed [DELTASPIKE-172] - Improve BeanProvider [DELTASPIKE-194] - enable examples build by default [DELTASPIKE-197] - pickup ConfigSources via ServiceLoader as well [DELTASPIKE-204] - AnnotationInstanceProviderTest#assertComplexToString fails on certain JVM's [DELTASPIKE-216] - add the ability to specify other property config source from apache-deltaspike.properties file [DELTASPIKE-221] - Rename README.txt into README or readme.md to allow markodwn syntax to be rendered on GitHub [DELTASPIKE-225] - simplify fluent Message API [DELTASPIKE-251] - SetAccessiblePrivilegedAction isn't needed without a SecurityManager [DELTASPIKE-254] - the de-/activation logic for extensions should be unified [DELTASPIKE-258] - improve the compatibility with new versions of weld New Feature [DELTASPIKE-111] - Add and review Seam Catch as a new DeltaSpike module [DELTASPIKE-169] - AnnotationInstanceProvider [DELTASPIKE-175] - @Transactional for EntityTransaction [DELTASPIKE-178] - @TransactionScoped [DELTASPIKE-182] - import TransactionalHelper from CODI [DELTASPIKE-188] - defaultValue for @ConfigProperty [DELTASPIKE-190] - Create ConfigurableDataSource [DELTASPIKE-192] - BeanManagerProvider should warn User if called before the container got started [DELTASPIKE-195] - create default-value handling for ConfigResolver [DELTASPIKE-201] - move NarrowingBeanBuilder to API utils and rename it [DELTASPIKE-215] - Add a new annotation to override the location of the apache-deltaspike.properties file [DELTASPIKE-219] - @Transactional for JTA UserTransaction [DELTASPIKE-222] - Add possibility to set base path [DELTASPIKE-223] - Add convention for @MessageResource annotated types. [DELTASPIKE-230] - Fallback stragtegy for resource bundles and locales [DELTASPIKE-250] - persistence-strategy which is aware of the environment Task [DELTASPIKE-13] - Choose documentation format and tools [DELTASPIKE-33] - deltaspike website [DELTASPIKE-76] - Discuss and review security features [DELTASPIKE-87] - re-visit packaging issue [DELTASPIKE-102] - review sonar findings [DELTASPIKE-110] - Discuss adding Seam Catch to DeltaSpike [DELTASPIKE-119] - review and discuss i18n module [DELTASPIKE-140] - integration test module for the security module [DELTASPIKE-174] - create jpa module [DELTASPIKE-180] - [build] check for available plugin and version updates [DELTASPIKE-181] - add Test Coverage reporting to our build [DELTASPIKE-220] - update our test and build infrastructure for 0.3-incubating [DELTASPIKE-224] - remove integration-test module and move container profiles to parent-code [DELTASPIKE-236] - integration-test config for all modules [DELTASPIKE-243] - change misleading name of PropertyConfigSource [DELTASPIKE-244] - align naming of base classes [DELTASPIKE-245] - Enable ProjectStage UnitTest for UnitTests [DELTASPIKE-246] - Port Solder BeanBuilder to DeltaSpike [DELTASPIKE-249] - cleanup of the security module [DELTASPIKE-253] - rename PersistenceStrategy to TransactionStrategy [DELTASPIKE-257] - align api/spi and impl package for parts related to transactions ================================================ FILE: deltaspike/readme/ReleaseNotes-0.4-incubating.txt ================================================ Apache DeltaSpike-0.4 Release Notes Sub-task [DELTASPIKE-10] - review and discuss "metadata implementations and utils" [DELTASPIKE-80] - review and discuss built in Authorization providers [DELTASPIKE-104] - unit and integration tests for CdiContainer [DELTASPIKE-105] - remove workarounds for weld [DELTASPIKE-113] - Review and Discuss ServiceHandlers [DELTASPIKE-132] - Discuss the concept of the exception chain / stack [DELTASPIKE-328] - Create ClientWindow API [DELTASPIKE-329] - Create a WindowContextManager [DELTASPIKE-330] - Create a new WindowScope to represent beans that are bound to a browser window Bug [DELTASPIKE-202] - DefaultMessageInterpolator/LocaleResolver doesn't get picked up properly [DELTASPIKE-207] - memory leak in OpenWebBeansContextControl [DELTASPIKE-208] - activateGlobalAlternatives is broken [DELTASPIKE-260] - Weld serialization issue [DELTASPIKE-262] - remove useless OWB workaround [DELTASPIKE-264] - Exception handler swallows UnsatisfiedResolutionException [DELTASPIKE-268] - our transitive deltaspike dependencies are all set to 'provided [DELTASPIKE-275] - org.apache.deltaspike.core.impl.exception.control.extension.ExceptionControlExtension#verifyInjectionPoints calls BeanProvider while cdi is not completely started [DELTASPIKE-280] - ShrinkWrapArchiveUtil registers a picked up resource under the wrong absolute file path [DELTASPIKE-284] - Deltaspike CDIControl won't work with Weld EE [DELTASPIKE-286] - Comparators shall always also implement Serializable [DELTASPIKE-290] - JSF message test fails due to localization issue [DELTASPIKE-291] - @SecurityBindings don't respect parameter types of @SecureParameterBinding parameters when determining the authorization method [DELTASPIKE-294] - Weld: Ambiguous dependency with global alternatives when multiple @Alternative classes [DELTASPIKE-295] - JsfMessageProducer createJsfMessage return type should be parametrized [DELTASPIKE-296] - Retrieving owb-CdiControl with BeanProvider causes Warning [DELTASPIKE-297] - Exception handling and multiple qualifiers [DELTASPIKE-299] - InvocationTargetException not unwrapped [DELTASPIKE-300] - Basic MBean API/Extension to link CDI to JMX [DELTASPIKE-303] - Missing cdi-api dependency in jbossas-remote-7 profile [DELTASPIKE-309] - Locale-related test failure [DELTASPIKE-312] - GlobalAlternatives must not get handled for OpenWebBeans [DELTASPIKE-313] - allow cdictrl-openejb to use a different owb version in the build [DELTASPIKE-317] - NPE if CdiContainer#getContextControl gets called without #boot [DELTASPIKE-318] - OpenejbCdiControl tries to scan starting classes [DELTASPIKE-319] - Fail deployment of app with JPA module when EM not found in same class. [DELTASPIKE-320] - moving the entity-manager injection can break the default handling [DELTASPIKE-321] - DefaultMessage.argument(Serializable...) should guard against empty arrays [DELTASPIKE-322] - auto unregister MBeans if already registered [DELTASPIKE-323] - auto unregister MBeans if already registered [DELTASPIKE-327] - InvocationHandlerExtension Beans are not passivation capable [DELTASPIKE-339] - JndiUtils is broken [DELTASPIKE-343] - NPE in PartialBeanAsAbstractClassTest with Weld 2.0.0 [DELTASPIKE-348] - WindowScope stuff breaks ICEfaces [DELTASPIKE-354] - NPE in MessageBundleInvocationHandler on null Argument [DELTASPIKE-356] - MessageContextProducer causes a ton of log output on each request [DELTASPIKE-359] - Websphere 8.0.x javaassist proxy does not reflect instance value [DELTASPIKE-362] - BeanManagerProvider floods log file with warnings on AS7 [DELTASPIKE-363] - BeanManagerProvider NPE when shutting down after a failure [DELTASPIKE-367] - upgrade owb-arquillian-container to 1.2.0 Improvement [DELTASPIKE-89] - Improve JavaDoc [DELTASPIKE-165] - Exception handlers: support handling unexpected exceptions [DELTASPIKE-234] - Go back through documentation for Exception Handling add in about equality and ordinal [DELTASPIKE-255] - base class for extensions [DELTASPIKE-273] - Provide a way to obtain all property names or map of properties [DELTASPIKE-292] - @SecurityBindings don't respect parameter types of @SecureParameterBinding parameters when determining the authorization method [DELTASPIKE-293] - Improve the ViewScopedContext by observing ServletContext and HttpSession lifecycle events. [DELTASPIKE-298] - Post-Method-Authorizer [DELTASPIKE-301] - Improve site layout to manage nested dirs [DELTASPIKE-302] - Avoid same layout to maintain in different files/templates [DELTASPIKE-310] - Support for TransactionAttributeType REQUIRE_NEW [DELTASPIKE-314] - TransactionBeanStorage shouldn't be request scoped [DELTASPIKE-316] - Upgrade to latest pax-cdi requirements for cdi extensions [DELTASPIKE-326] - Introduce isScannable to ConfigSource [DELTASPIKE-340] - Support PreViewConfigNavigateEvent for "unknown" views as nav-source [DELTASPIKE-344] - BeanProvider should get a getBeans() with the BeanManager as parameter [DELTASPIKE-355] - Create Alternative to DefaultMessageInterpolator using java.text.MessageFormat [DELTASPIKE-365] - extend ContainerControl boot() to pass in config properties [DELTASPIKE-369] - Disable WindowScope by default New Feature [DELTASPIKE-122] - producer for logger [DELTASPIKE-187] - @PersistenceContext with @Transactional outside of application servers [DELTASPIKE-210] - Build OSGi bundles [DELTASPIKE-229] - Add JSFLocaleResolver as an DeaultLocaleResolver [DELTASPIKE-266] - Import @ViewScoped support from CODI [DELTASPIKE-267] - Create JSF module maven structure [DELTASPIKE-274] - Create a common base for writing Contexts [DELTASPIKE-277] - Typesafe Messgaes for JSF: add JsfMessage feature [DELTASPIKE-278] - add 'category' to Message API [DELTASPIKE-279] - import JSF-Scope_to_CDI-Scope mapping from CODI [DELTASPIKE-281] - add JsfLocaleResolver for our typesafe messages [DELTASPIKE-283] - event-broadcasting related to a faces-request [DELTASPIKE-288] - type-safe view-configs [DELTASPIKE-289] - implement WindowContext [DELTASPIKE-307] - integration of @Secured with type-safe view-configs [DELTASPIKE-315] - Provide a producer for EntityManagerFactories [DELTASPIKE-336] - support @Stereotype together with @ViewMetaData [DELTASPIKE-345] - integration of view-controller callbacks with type-safe view-configs [DELTASPIKE-346] - JsfModuleConfig as type-safe config for the jsf-module [DELTASPIKE-347] - keep faces-messages per default in case of a redirect Task [DELTASPIKE-2] - deltaspike java-se feature ranking [DELTASPIKE-41] - add examples for v0.1 [DELTASPIKE-59] - review and discuss logging [DELTASPIKE-68] - discuss BeanFilter for BeanProvider [DELTASPIKE-88] - discuss Editable* spi approach [DELTASPIKE-162] - add examples for v0.2 [DELTASPIKE-217] - test twitter bootstrap for DS site [DELTASPIKE-242] - add examples for v0.3 [DELTASPIKE-276] - upgrade dependencies and plugins before the next release [DELTASPIKE-325] - upgrade to owb-arquillian-standalone and owb 1.1.8 [DELTASPIKE-331] - create partial-bean module [DELTASPIKE-333] - replace javassist with commons-proxy [DELTASPIKE-337] - unify package for annotations [DELTASPIKE-338] - remove hard dependency to javassist [DELTASPIKE-351] - re-visit usage of DeltaSpikeConfig [DELTASPIKE-352] - update dependencies for weld2 [DELTASPIKE-353] - restrict global alternatives to weld 1.x Test [DELTASPIKE-247] - Create Identity Model [DELTASPIKE-285] - MinimalMessagesTest fails on WLS12c ================================================ FILE: deltaspike/readme/ReleaseNotes-0.5.txt ================================================ Apache DeltaSpike-0.5 Release Notes The following modules and big features got added in the DeltaSpike-0.5 release: * DeltaSpike-Data The DeltaSpike Data module enhances JPA experience with declarative queries, reducing boilerplate to a minimum. DeltaSpike Data repositories can derive queries by simple method names, or by method annotations defining JPQL, named queries or even plain SQL - beside result pagination and sorting. The module also features auditing of entities and a simplified alternative to the Criteria API. * DeltaSpike-Servlet The DeltaSpike Servlet module provides integration with the Java Servlet API. It adds support for injection of common servlet objects and propagates servlet events to the CDI event bus. * DeltaSpike-BeanValidation The main feature of the Bean Validation module is to provide CDI integration in to ConstraintValidators. This allows you to inject CDI objects, EJBs etc in to your validators. * The following issues got resolved in this release: Sub-task [DELTASPIKE-16] - review and discuss builders (metadata implementations) [DELTASPIKE-387] - Create new bean-validation module [DELTASPIKE-388] - Add support for a ConstraintValidatorFactory that creates CDI enabled constraint validators Bug [DELTASPIKE-380] - NPE in PartialBeanLifecycle if javassist not on classpath [DELTASPIKE-381] - missing optional bean-lookup [DELTASPIKE-384] - ViewConfigUtils.toNodeList() fails in EAR [DELTASPIKE-385] - Spurious BeanManagerProvider warnings when used in EAR [DELTASPIKE-394] - pom.xml files of the data-module aren't aligned with other modules [DELTASPIKE-397] - MessageBundleInvocationHandler should ignore methods like hashCode() etc from Object.class [DELTASPIKE-403] - MessageBundles are not PassivationCapable [DELTASPIKE-405] - producer for JsfMessage does not match CDI-1.1 rules [DELTASPIKE-407] - Tests for Servlet module incorrectly packaged Improvement [DELTASPIKE-332] - Discuss introducing BeanValidation support [DELTASPIKE-360] - alternative LocaleResolver which is aware of supported locales [DELTASPIKE-366] - basic test of properties usage in cdictrl openejb container [DELTASPIKE-383] - use getProjectStageAwarePropertyValue in @ConfigProperty and other configuration places [DELTASPIKE-390] - optional custom ConfigPreProcessor for @ViewMetaData [DELTASPIKE-409] - Servlet module events should be deactivatable [DELTASPIKE-410] - improve compatibility with mojarra New Feature [DELTASPIKE-375] - Create servlet module maven structure [DELTASPIKE-376] - Propagation of basic servlet events to the CDI event bus [DELTASPIKE-377] - Supporting injection of basic servlet objects [DELTASPIKE-378] - ProjectStage-aware and Property-aware configuration [DELTASPIKE-382] - mask out passwords and other credentials in our Configuration logs [DELTASPIKE-398] - BeanProvider handling for @Dependent scoped beans Task [DELTASPIKE-60] - Review and discuss a generic DAO API [DELTASPIKE-401] - change GlobalAlternativeTest to work on Weld-2, Weld-1 and OWB [DELTASPIKE-402] - Provide a way to skip tests depending on the CDI Container being used. [DELTASPIKE-408] - WildFly test profile ================================================ FILE: deltaspike/readme/ReleaseNotes-0.6.txt ================================================ Release Notes - Apache DeltaSpike - Version 0.6 Sub-task [DELTASPIKE-252] - documentation for @Transactional with JTA Bug [DELTASPIKE-391] - Memory Leak in Data Module [DELTASPIKE-414] - HttpServletRequest (and others) injection not working in servlet filters from web.xml [DELTASPIKE-415] - Nested @Folder throws IllegalStateException [DELTASPIKE-416] - @Folder's name check/resolution is broken [DELTASPIKE-417] - EntityManagerResolver ignored [DELTASPIKE-418] - EntityManagerResolver ignored [DELTASPIKE-424] - EntityManagerResolver with normal scope is not supported [DELTASPIKE-427] - WeldContainerControl throws a NullPointer before a null check. [DELTASPIKE-434] - bean-lookup during ProcessAnnotatedType in RepositoryComponent [DELTASPIKE-442] - PersistenceConfigurationProvider does not pick up any configuration yet [DELTASPIKE-446] - Current windowhandler.js is incompatible with PrimeFaces [DELTASPIKE-458] - UserTransaction is not always available in JNDI [DELTASPIKE-463] - @ViewConfigRoot breaks view-configs added earlier [DELTASPIKE-471] - support external handling of navigation-cases [DELTASPIKE-484] - wrong handling of new contextual-storages in WindowBeanHolder#getContextualStorage [DELTASPIKE-485] - WindowContext isn't injectable in passivation capable beans [DELTASPIKE-486] - #destroy and #destroyAllActive of AbstractContext destroy entries without dropping them [DELTASPIKE-489] - AbstractContext#getContextualStorage doesn't forward the current contextual [DELTASPIKE-490] - WindowContextImpl#closeWindow doesn't destroy beans [DELTASPIKE-493] - inconsistent handling in WindowContextImpl#closeWindow [DELTASPIKE-501] - windowhandler.js also handles NONE and CUSTOM [DELTASPIKE-507] - UserTransaction not available in WAS 8.0 and 8.5 during EJB CMT call [DELTASPIKE-512] - Navigation happens twice if DeltaSpikeNavigationHandler is de-activated [DELTASPIKE-513] - Transactional interceptor throws NPE for missing EntityManager [DELTASPIKE-516] - ClientWindowHelper.handleInitialRedirect mutilates URL, pathInfo is omitted [DELTASPIKE-518] - DS Data should support Wrapped JPA APIs [DELTASPIKE-524] - preserve view-parameters [DELTASPIKE-528] - stopContexts() and container shutdown() do not dispose of application scoped beans [DELTASPIKE-529] - DeltaSpikeExceptionHandler construction issue in non EE [DELTASPIKE-530] - deactivatable extensions [DELTASPIKE-532] - DeltaSpikeFacesContextFactory construction issue in non EE [DELTASPIKE-535] - DeltaSpikeViewHandler construction issue in non EE [DELTASPIKE-541] - Remove errant source directory Improvement [DELTASPIKE-341] - Provide Integration between Faces Exceptions and Exception Handling [DELTASPIKE-373] - Provide an out of the box alternative for ClientWindowConfig [DELTASPIKE-423] - limit inherited meta-data [DELTASPIKE-425] - DependentProvider#destroy() must not destroy NormalScoped instances [DELTASPIKE-429] - Old property that could be removed in parent\pom.xml [DELTASPIKE-431] - 'ordinal' for @JsfPhaseListener [DELTASPIKE-432] - ClientWindow adapter for jsf 2.2 [DELTASPIKE-439] - ViewConfigs not residing in packages should be treated as a definition error [DELTASPIKE-459] - add optional config "testcontrol.stop_container" [DELTASPIKE-460] - @SkipMetaDataMerge for view-configs [DELTASPIKE-461] - AccessDecisionVoterContext should contain view-meta-data in case of @Secured in combination with view-configs [DELTASPIKE-464] - unify naming (Broadcaster vs Emitter) [DELTASPIKE-465] - provide DefaultViewConfigInheritanceStrategy#addViewMetaData as protected method [DELTASPIKE-467] - Add default module.xml for jboss modules. [DELTASPIKE-478] - Create build profile in jenkins that creates binary distribution. [DELTASPIKE-480] - view-config validation [DELTASPIKE-495] - expose WindowContext as named bean [DELTASPIKE-499] - Minify javascripts [DELTASPIKE-502] - Finish LAZY ClientWindowRenderMode [DELTASPIKE-504] - easier configuration of ClientWindowRenderMode [DELTASPIKE-505] - change default ClientWindowRenderMode to LAZY [DELTASPIKE-517] - improved weld-support [DELTASPIKE-527] - @Named support for type-safe messages [DELTASPIKE-531] - rename ExternalResource to InjectableResource [DELTASPIKE-533] - Introduce a global deltaspike qualifier [DELTASPIKE-534] - Replace @Web with @DeltaSpike [DELTASPIKE-537] - test-utils jar should be added to deployed wars only if the test is a server test New Feature [DELTASPIKE-256] - allow custom timeout for the UserTransaction [DELTASPIKE-263] - Generate binaries of DeltaSpike project [DELTASPIKE-342] - config-annotations for test-runners to control CdiContainer and ContextControl [DELTASPIKE-399] - Incorporate Solder's ResourceLoader features into DeltaSpike [DELTASPIKE-426] - cdi support for jsf converters and validators [DELTASPIKE-437] - window-timeout [DELTASPIKE-438] - window quota handling [DELTASPIKE-444] - provide an utility class for data mapper to avoid to reimplement loops each time [DELTASPIKE-454] - Provide a ClientWindowRenderMode similiar to CODI [DELTASPIKE-466] - ExternalContainer spi [DELTASPIKE-468] - optional integration with myfaces-test [DELTASPIKE-474] - support of Deactivatable for the ds-spi [DELTASPIKE-475] - auto. registration of jobs with cron-expressions [DELTASPIKE-487] - port @ViewAccessScoped from codi [DELTASPIKE-488] - port grouped conversation scope from codi [DELTASPIKE-491] - port @ConversationSubGroup from codi [DELTASPIKE-492] - Create ExternalResourceProvider for the Servlet Module [DELTASPIKE-500] - Implement ds:disableClientWindow [DELTASPIKE-515] - optional adapter for MockedJsfTestContainer Task [DELTASPIKE-118] - custom port for jbossas-build-managed-7 [DELTASPIKE-389] - Create documentation for the servlet module [DELTASPIKE-428] - update build for weld 2.1.x [DELTASPIKE-430] - re-visit DependentProvider [DELTASPIKE-435] - upgrade arquillian adapter for glassfish3 [DELTASPIKE-447] - upgrade tests to tomee 1.6.0 [DELTASPIKE-455] - unify literal-packages [DELTASPIKE-456] - wildfly-build-managed profile [DELTASPIKE-477] - New Scheduler module is not included in binary distribution. [DELTASPIKE-481] - Use unique archive names in Servlet module integration tests [DELTASPIKE-483] - WildFly build-managed test profile [DELTASPIKE-496] - Merge arquillian.xml files into a single one [DELTASPIKE-497] - Create build-managed test profiles for Glassfish [DELTASPIKE-503] - Add JSF playground module [DELTASPIKE-523] - align event-packages [DELTASPIKE-525] - move @Initialized and @Destroyed [DELTASPIKE-526] - upgrade dependencies [DELTASPIKE-536] - align creation of test-archives [DELTASPIKE-539] - release notes for v0.6 [DELTASPIKE-540] - update notice file Test [DELTASPIKE-476] - scheduler tests [DELTASPIKE-479] - add tests with simple ear-packaging ================================================ FILE: deltaspike/readme/ReleaseNotes-0.7.txt ================================================ Release Notes - Apache DeltaSpike - Version 0.7 Sub-task [DELTASPIKE-156] - documentation for ContainerControl API Bug [DELTASPIKE-542] - Problem with JdbcJobstore [DELTASPIKE-545] - DeltaSpikeExceptionHandler getRootCause assumes caught FacesException is wrapping another Exception [DELTASPIKE-546] - NPE in observer method on Glassfish 4.x [DELTASPIKE-548] - WELD-001408: Unsatisfied dependencies for type Scheduler [DELTASPIKE-559] - ExceptionHandler lifecycle [DELTASPIKE-566] - JSF always requires an active WindowContext [DELTASPIKE-568] - Client Window cookie name is different on server and client side [DELTASPIKE-573] - f:viewAction is executed twice with LAZY window handling mode [DELTASPIKE-578] - org.apache.deltaspike.data.impl.meta.RepositoryComponent is not thread safe [DELTASPIKE-581] - CountQueryPostProcessor assumes a where clause [DELTASPIKE-583] - duplicated web-fragment.xml in test-archives [DELTASPIKE-584] - ds:disableClientWindow prevents child rendering with CLIENTWINDOW mode [DELTASPIKE-585] - HttpSession is not serializable Improvement [DELTASPIKE-441] - provide a default implementation for the interface 'SecurityViolation' [DELTASPIKE-445] - read ProjectStage also from a few other places [DELTASPIKE-547] - merge ProxyUtils [DELTASPIKE-550] - improve proxy detection [DELTASPIKE-551] - allow full deactivation of DeltaSpikeNavigationHandler [DELTASPIKE-554] - ContainerManagedTransactionStrategy [DELTASPIKE-563] - Deactivatable support for PhaseListener [DELTASPIKE-567] - Consistent post/get parameter naming [DELTASPIKE-569] - Improve DeltaSpikeResourceHandler handling [DELTASPIKE-572] - Remove Documentation TODOs [DELTASPIKE-574] - Versioning for DeltaSpike JSF resources [DELTASPIKE-576] - improved integration with view-controller [DELTASPIKE-579] - extract annotation lookup [DELTASPIKE-586] - optional forward compatibility for javax.interceptor.InvocationContext New Feature [DELTASPIKE-449] - ExceptionHandler not invoked for AccessDeniedException [DELTASPIKE-560] - interceptor for @NavigationParameter [DELTASPIKE-564] - optional double submit prevention Task [DELTASPIKE-553] - improve the config for maven-compiler-plugin [DELTASPIKE-556] - Impl-Weld tests: Unpacking causes ambiguous dependencies [DELTASPIKE-587] - release notes for v0.7 Wish [DELTASPIKE-555] - Do not use package-private methods in CDI beans ================================================ FILE: deltaspike/readme/ReleaseNotes-1.0.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.0.0 Sub-task [DELTASPIKE-227] - documentation for minimal type-safe messages Bug [DELTASPIKE-370] - ContainerCtrlTckTest - fix testShutdownWithInactiveContexts() [DELTASPIKE-372] - WeldContainerControl should stop contexts during shutdown [DELTASPIKE-543] - org.apache.deltaspike.distribution is disconnected [DELTASPIKE-590] - ExceptionHandlerBroadcaster should not rethrow exceptions from BridgeExceptionHandlerWrapper [DELTASPIKE-595] - broken assembly config [DELTASPIKE-597] - Use correct names of brands and products in documentation [DELTASPIKE-609] - @Transactional for methods in super-class(es) [DELTASPIKE-618] - NullPointerException when trying to schedule job manually [DELTASPIKE-624] - inconsistent package naming [DELTASPIKE-629] - Initial redirect fails behind proxy/fw/apache redirects [DELTASPIKE-639] - Fix Criteria API count methods signatures Improvement [DELTASPIKE-396] - ShrinkWrapArchiveUtil creates jar files with random names [DELTASPIKE-596] - use optional flag for ExceptionToCatchEvent [DELTASPIKE-598] - TestAware as optional contract for implementations of ExternalContainer [DELTASPIKE-601] - legacy support for ViewConfigPathValidator [DELTASPIKE-602] - forward manual request-handling to myfaces-test adapters [DELTASPIKE-606] - Simplified DTO mapping for Entity updates [DELTASPIKE-607] - Add EntityManagerDelegate interface to API [DELTASPIKE-611] - @Exclude on abstract classes [DELTASPIKE-612] - optional ConfigurableNavigationHandlerWrapper for jsf v2.2+ [DELTASPIKE-614] - @Named support for ExecutableCallbackDescriptor [DELTASPIKE-617] - Utility Method for TypedQuery in AbstractEntityRepository [DELTASPIKE-621] - DeltaSpikeResourceHandler should implement Deactivatable [DELTASPIKE-626] - ensure valid application wrapper chain [DELTASPIKE-630] - JsfSupportedLocaleAwareLocaleResolver should be the default LocaleResolver for the jsf module [DELTASPIKE-631] - improve supported-locale check [DELTASPIKE-636] - @Secures should trigger the ds-exception-handler New Feature [DELTASPIKE-514] - optional integration with myfaces-core 2.2 [DELTASPIKE-593] - support for mocked cdi-beans [DELTASPIKE-608] - @Transactional#readOnly [DELTASPIKE-628] - support for the configured message-bundle in faces-config.xml [DELTASPIKE-632] - CdiAwareJobFactory Task [DELTASPIKE-306] - Examples for the features of the JSF module [DELTASPIKE-589] - Support WLS Profile in Data Module [DELTASPIKE-592] - merge back release branch 'deltaspike-0.7' [DELTASPIKE-610] - re-visit DataSourceConfig [DELTASPIKE-615] - create list of undocumented api classes [DELTASPIKE-616] - update build config for v1 [DELTASPIKE-619] - update version numbers of dependencies [DELTASPIKE-622] - improve profile "wildfly-build-managed" [DELTASPIKE-644] - release notes for v1.0.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.0.1.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.0.1 Bug [DELTASPIKE-470] - Releases must be distributed via the ASF mirror system [DELTASPIKE-648] - @ConfigProperty in Wildfly 8.1 not working correctly [DELTASPIKE-650] - Custom JSF Converters/Validators error [DELTASPIKE-656] - Concurrency Problem when using QuartzScheduler [DELTASPIKE-661] - No custom quartz-config file found after upgrade to 1.0.0 [DELTASPIKE-664] - SecurityViolation are evaluated twice for redirect pages with configured errorView Improvement [DELTASPIKE-599] - CDI 1.1 friendly ViewConfig discovery [DELTASPIKE-651] - Support for disabling scope activation globally [DELTASPIKE-654] - veto converters and validators without injection-points or scope [DELTASPIKE-658] - improved @Stereotype support for @ViewMetaData Task [DELTASPIKE-520] - test proxy handling [DELTASPIKE-638] - re-visit inconsistent handling of @BeforeHandles [DELTASPIKE-646] - Please delete old releases from mirroring system [DELTASPIKE-655] - create ee6 only version of the jsf module [DELTASPIKE-657] - create simple scheduler example [DELTASPIKE-663] - force AccessDeniedException per default [DELTASPIKE-667] - update jsf demo [DELTASPIKE-668] - release notes for v1.0.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.0.2.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.0.2 Bug [DELTASPIKE-637] - duplicated handling of AccessDeniedException [DELTASPIKE-672] - Wrong Bean Validation artifactId on documentation [DELTASPIKE-679] - NPE in BeanManagerProvider if parentClassLoader is null [DELTASPIKE-681] - Handling AccessDeniedException will run the secured method [DELTASPIKE-684] - No OSGi headers in deltaspike-partial-bean-module-api [DELTASPIKE-685] - Guard against null FacesContext in Exception Handler Bridge Improvement [DELTASPIKE-506] - [perf] use a shared StringBuilder [DELTASPIKE-509] - [perf] cache map in DefaultClientWindow#getQueryURLParameters [DELTASPIKE-653] - Provide a platform inspecific servlet listener [DELTASPIKE-665] - Add utility method to always get new context control. [DELTASPIKE-666] - Improve BeanManager consistency [DELTASPIKE-669] - Try to shutdown contexts when shutting down container [DELTASPIKE-676] - ServletContext is available for injection before EventBridgeContextListener Task [DELTASPIKE-641] - Document prevent double submit feature [DELTASPIKE-689] - release notes for v1.0.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.0.3.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.0.3 Bug [DELTASPIKE-696] - Remove unneeded dependencies on CDICtrl Servlet [DELTASPIKE-706] - Multiple CDI API versions on classpath in JSF module tests (Weld) [DELTASPIKE-710] - Error using clientWindow and (p|f):ajax [DELTASPIKE-717] - Exception handlers not invoked when @Secured ViewConfig is violated in an app with JSF module without a DefaultErrorView page [DELTASPIKE-719] - Only one voter invoked if multiple voters are applied through a stereotype [DELTASPIKE-723] - Exception bypassing on JSF conversion errors [DELTASPIKE-726] - Lazy window handling doesn't recognize new windows anymore [DELTASPIKE-729] - f:viewAction is executed twice with LAZY window handling mode Improvement [DELTASPIKE-692] - workaround for tests which don't use optional classes [DELTASPIKE-699] - Signature relaxing of attribute method() in CriteriaSupport [DELTASPIKE-708] - Veto the AbstractEntityRepository class [DELTASPIKE-712] - BeanManagerProvider : Wrap usage in parent class loaders New Feature [DELTASPIKE-702] - Add support to GreaterThan and LessThan in criteria to dates Task [DELTASPIKE-640] - Document Scopes in Core module [DELTASPIKE-677] - document ds-security in combination with picketlink [DELTASPIKE-697] - Set the baseDir to reside in the target directory for tomcat tests. [DELTASPIKE-698] - re-visit glassfish4 profile [DELTASPIKE-711] - Create placeholder documentation directory [DELTASPIKE-716] - Migrate documentation format to asciidoc at git repo [DELTASPIKE-730] - release notes for v1.0.3 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.1.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.1.0 Bug [DELTASPIKE-732] - Servlet API module needs beans.xml [DELTASPIKE-733] - Documentation: CSS missing for https [DELTASPIKE-736] - MockAwareInjectionTargetWrapper breaks interceptors in unit tests [DELTASPIKE-738] - ViewConfigTest relies on ordering of elements in a HashSet [DELTASPIKE-739] - BeanBuilder#readFromType should respect @Typed [DELTASPIKE-742] - validateBindings fails with owb for secured-stereotypes with values [DELTASPIKE-744] - check is-prefix of converter-/validator-methods [DELTASPIKE-748] - Fix DS Security AbstractAccessDecisionVoter documentation [DELTASPIKE-752] - ensure a secure maximum length of the window-id [DELTASPIKE-753] - Initial redirect does not encode URL [DELTASPIKE-754] - Empty dswid-paramter causes infinite redirects [DELTASPIKE-757] - Create tests for WindowContextQuotaHandler [DELTASPIKE-764] - missing cleanup in EmbeddedServletContainer Improvement [DELTASPIKE-544] - api for a fine-grained control of @ViewAccessScoped beans [DELTASPIKE-735] - allow multiple stereotypes annotated with @Secured [DELTASPIKE-755] - cache proxy to ViewConfigResolver [DELTASPIKE-763] - check usage of disabled feature New Feature [DELTASPIKE-751] - WindowContextQuotaHandler Task [DELTASPIKE-725] - tests for converter/validator injection [DELTASPIKE-741] - set default version of tomee to 1.7.0 [DELTASPIKE-758] - Document WindowContextQuotaHandler [DELTASPIKE-761] - mocked producers can't be portable in any case [DELTASPIKE-762] - disable mock-support per default [DELTASPIKE-765] - release notes for v1.1.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.2.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.2.0 Bug [DELTASPIKE-745] - cdictr-weld ContextControl.startContext doesn't properly start RequestScoped context [DELTASPIKE-749] - Doc: Security: Making intitially requested and secured page available for redirect after login [DELTASPIKE-750] - No error message if the filename provided PropertyFileConfig implementation isn't found. [DELTASPIKE-771] - BeanManagerProvider#getBeanManagerInfo(ClassLoader) wipes out info for parent CL [DELTASPIKE-781] - AnnotatedTypeImpl doesn't work for Annotation AnnotatedType [DELTASPIKE-782] - BeanManager lookup fails when BeanManager created in parent classloader and in SE mode Improvement [DELTASPIKE-770] - Overload BeanProvider#getContextualReference with (BeanManager, String, boolean. Class) variant [DELTASPIKE-773] - improved testability of @WindowScoped beans [DELTASPIKE-780] - support more advanced cases by extending existing transaction-strategies [DELTASPIKE-785] - Make CdiTestRunner pick up container configuration from properties file [DELTASPIKE-789] - ClientWindowConfig should extend Serializable [DELTASPIKE-790] - cache result for JsfModuleConfig#isDelegatedWindowHandlingEnabled New Feature [DELTASPIKE-769] - add @Priority dyn. to deltaspike interceptors to avoid the manual config [DELTASPIKE-772] - use CDI#current if supported [DELTASPIKE-774] - map javax.faces.bean.ViewScoped to javax.faces.view.ViewScoped [DELTASPIKE-776] - check correct module usage Task [DELTASPIKE-649] - re-visit wls profile [DELTASPIKE-767] - Review javadoc in core/api [DELTASPIKE-777] - Create and publish Javadocs section [DELTASPIKE-778] - add duke's choice award badge to the site [DELTASPIKE-786] - migrate documentation about release preparation to asciidoc [DELTASPIKE-791] - release notes for v1.2.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.2.1.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.2.1 Sub-task [DELTASPIKE-796] - test view-actions in combination with @ViewAccessScoped Bug [DELTASPIKE-400] - BeanBuilder should set the bean of the InjectionPoints [DELTASPIKE-792] - Fix javadoc -Xdoclint:none for JDK < 8 [DELTASPIKE-795] - ViewAccessScope gets destroyed in combination with f:viewAction [DELTASPIKE-799] - Do not depend on Weld uberjar [DELTASPIKE-800] - Update documentation to 1.2.0 [DELTASPIKE-801] - Security: SecurityParameterValueRedefiner doesnt recognize @Nonbinding Improvement [DELTASPIKE-588] - Repositories from Data module should be deactivatable [DELTASPIKE-660] - OSGi support for DeltaSpike Data and its dependencies [DELTASPIKE-690] - Documentation donation from RedHat [DELTASPIKE-722] - Migrate non-documentation pages from markdown to asciidoc [DELTASPIKE-775] - provide a type-safe approach for low-level configs [DELTASPIKE-798] - Support for uber-jar creation in SE support Task [DELTASPIKE-635] - Document last TODOs in the JSF module documentation [DELTASPIKE-794] - update release steps [DELTASPIKE-797] - deploy javadoc for v1.2.0 to the cms [DELTASPIKE-802] - update OWB and Weld to use the latest CDI-1.0 compatible versions by default [DELTASPIKE-803] - exclude ee7 tests for ee6 servers [DELTASPIKE-804] - prepare v1.2.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.3.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.3.0 New Feature [DELTASPIKE-419] - Interceptors on partial beans [DELTASPIKE-420] - Transactional repositories [DELTASPIKE-837] - PropertyFileConfig pickup via java.util.ServiceLoader [DELTASPIKE-841] - make getConfigSources public [DELTASPIKE-842] - pick up ConfigFilters via ServiceLoader Bug [DELTASPIKE-647] - AppScoped abstract repositories doesn't work [DELTASPIKE-714] - QueryResult.count not work if jpql have order by [DELTASPIKE-746] - Doc: JSF/ExceptionControl integration redirect example [DELTASPIKE-808] - Make website to read pom.xml properties [DELTASPIKE-812] - remove AttributeAware [DELTASPIKE-814] - Create a root pom.xml to share common properties [DELTASPIKE-818] - CDI Events with reception condition in WindowScoped beans [DELTASPIKE-825] - Scheduler docs mention wrong method scheduleJob [DELTASPIKE-828] - Infinite recursive loop navigating through annoations [DELTASPIKE-831] - NPE in DefaultMockFilter when running JUnit and the application contains a class in the default package [DELTASPIKE-834] - MessageBundle Extension not working in EARs on some containers [DELTASPIKE-838] - SchedulerExtension: Multiple Job-Classes found with name Improvement [DELTASPIKE-805] - Provide utils method to check if an context is active or not [DELTASPIKE-829] - add hints for using jersey-test with test-control [DELTASPIKE-835] - Improve build config and add tests [DELTASPIKE-836] - Support case insensitive LIKE queries with method naming convention [DELTASPIKE-840] - ConfigResolver#getConfigFilters() shall return unmutable List Task [DELTASPIKE-806] - update site to 1.2.1 [DELTASPIKE-807] - update external resources [DELTASPIKE-810] - improve site headers [DELTASPIKE-811] - document custom project-stages [DELTASPIKE-815] - Publish 1.2.1 Javadoc [DELTASPIKE-821] - check compatibility with gradle [DELTASPIKE-823] - Reimplement Partial-Bean module [DELTASPIKE-845] - prepare v1.3.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.4.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.4.0 Bug [DELTASPIKE-822] - Repository method lookup in super interfaces [DELTASPIKE-830] - Now active ViewAccessScoped context during restore view phase [DELTASPIKE-832] - Javascript assert windowId not resilient enough [DELTASPIKE-833] - BeanManagerProvider Log Flood [DELTASPIKE-847] - java.util.Properties Provider does not close InputStream after usage [DELTASPIKE-849] - InjectableResourceProducer does not close InputStreams [DELTASPIKE-854] - Jacoco profile doesn't work anymore [DELTASPIKE-859] - Injection of @Named @MessageBundle works only with @Named injection point [DELTASPIKE-860] - documentation says "@LoggedIn User user", but that's impossible [DELTASPIKE-863] - NPE when invoking proxy for custom jsf converter [DELTASPIKE-867] - Clarify that Test-Control module has manual dependencies on CDI implementations [DELTASPIKE-869] - Minor typos on test-control asciidoc [DELTASPIKE-870] - Partial Bean with signed jar trouble. [DELTASPIKE-876] - Website navigation bar active tab highlighting broken [DELTASPIKE-884] - PropertyFileConfig shouldn't implement DeltaSpikeConfig [DELTASPIKE-889] - ValidatorWrapper causes filtering of multiple custom validators in ValidatorTagHandler [DELTASPIKE-893] - Remove erroneous WarpTest annotation and Warp dependency from JSF impl tests [DELTASPIKE-899] - Build fail for OWB15 Improvement [DELTASPIKE-809] - Clean up cdi ctrl and cdi imp pages [DELTASPIKE-846] - Docs: Clarify that scheduler module has manual dependencies [DELTASPIKE-852] - fix naming of type-safe configs [DELTASPIKE-855] - Review deltaspike-release-plugin and distribution profile to not consider deltaspike-root [DELTASPIKE-857] - [perf] skip method interception if no interceptors defined [DELTASPIKE-873] - show error-message on the same page [DELTASPIKE-875] - HTTPS support for site and documentation [DELTASPIKE-878] - AnnotationUtils should support literal instances [DELTASPIKE-879] - use @Priority for global-alternatives [DELTASPIKE-880] - Restrict initial redirect to GET requests [DELTASPIKE-881] - align invocation order of @PreRenderView with jsf [DELTASPIKE-882] - Create a new module for proxy [DELTASPIKE-885] - Static DeltaSpike configuration should be easy to find in code base [DELTASPIKE-886] - Add ignoreCase() to the criteria API [DELTASPIKE-891] - check for InvocationTargetException in ExecutableCallbackDescriptor [DELTASPIKE-896] - improve the warning in ViewConfigPathValidator New Feature [DELTASPIKE-420] - Transactional repositories [DELTASPIKE-874] - observe @javax.faces.bean.RequestScoped via @jakarta.enterprise.context.Initialized and @jakarta.enterprise.context.Destroyed [DELTASPIKE-877] - allow to inherit dynamically changed metadata [DELTASPIKE-888] - Add support for delete a job from the Scheduler [DELTASPIKE-892] - type-safe static config Task [DELTASPIKE-850] - Add Weld 3 profile [DELTASPIKE-862] - document JsfMessage [DELTASPIKE-903] - prepare v1.4.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.4.1.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.4.1 Bug [DELTASPIKE-594] - Memory leak in RepositoryComponents singleton [DELTASPIKE-901] - org.apache.deltaspike.data.impl.builder.postprocessor.CountQueryPostProcessor doesn't respect order by [DELTASPIKE-905] - Missing OSGi headers in Proxy modules [DELTASPIKE-908] - org.apache.deltaspike.test.scheduler.custom.CustomSchedulerWarFileTest fails with Weld [DELTASPIKE-915] - Transactional#readOnly needs to be @Nonbinding [DELTASPIKE-917] - EnvironmentAwareTransactionStrategy fails in unmanaged threads Improvement [DELTASPIKE-603] - removeBy* - similiar to findBy* [DELTASPIKE-911] - Criteria API - Add support for accept multiple columns in orderBy [DELTASPIKE-913] - QuartzScheduler uses BeanProvider.getContextualReference() for dependent scoped bean [DELTASPIKE-919] - higher priority for dynamic navigation-parameters [DELTASPIKE-924] - Adjust The AbstractEntityRepository Class section. New Feature [DELTASPIKE-700] - Add #tableName() to AbstractEntityRepository [DELTASPIKE-701] - Add method in EntityRepository to merge a detached entity and remove it [DELTASPIKE-894] - Trim for CriteriaSupport API [DELTASPIKE-923] - Add #entityName() to AbstractEntityRepository Task [DELTASPIKE-816] - document usage of multiple entity-managers [DELTASPIKE-909] - Site/Docs/Javadoc Release procedures for DS 1.4 [DELTASPIKE-916] - Weld 2.3 and 3.x support [DELTASPIKE-925] - prepare v1.4.1 Test [DELTASPIKE-902] - Test for EntityRepository#removeAndFlush(entity) ================================================ FILE: deltaspike/readme/ReleaseNotes-1.4.2.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.4.2 Bug [DELTASPIKE-830] - windowhandling doesn't work correctly when onload defined on h:body [DELTASPIKE-887] - ds:windowId should initialize the windowhandler script [DELTASPIKE-929] - Weld test profile is broken [DELTASPIKE-930] - Fix data module tests on GF [DELTASPIKE-931] - Integration tests fail when dependencies are class folders, not JARs [DELTASPIKE-939] - dswid=tempWindowId for every duplicated tab in Chrome/Firefox [DELTASPIKE-941] - JPA link broken in Data Module documentation [DELTASPIKE-947] - StackOverFlow with DELEGATED window mode and undefined javax.faces.CLIENT_WINDOW_MODE [DELTASPIKE-954] - CLIENTWINDOW windowhandler.html contains unreplaced variable [DELTASPIKE-958] - remove outdated information [DELTASPIKE-959] - DS cuts the windowId generated from JSF 2.2 [DELTASPIKE-960] - WindowIdHtmlRenderer needs to use maxWindowIdCount for window-id cookies Improvement [DELTASPIKE-673] - CdiQueryInvocationContext#isNew does not work well with OpenJpa and detached entities [DELTASPIKE-932] - Refactor ClientWindow server side [DELTASPIKE-933] - Upgrade to Arquillian 1.1.8.Final [DELTASPIKE-934] - @Query metadata should be considered for any method expression [DELTASPIKE-935] - ds:disableClientWindow should also disable JSF 2.2 rendering mode [DELTASPIKE-945] - Verify WildFly 9 profile [DELTASPIKE-946] - Prevent jfwid rendering [DELTASPIKE-948] - CdiQueryInvocationContext#isNew isn't portable across jpa providers [DELTASPIKE-949] - RequestResponseHolderListener should be deactivatable [DELTASPIKE-950] - RequestResponseHolderListener fails if requestInitialized() is called more than once [DELTASPIKE-951] - validate the content of TestControl#startScopes [DELTASPIKE-953] - Refactor ClientWindow client side New Feature [DELTASPIKE-904] - Stereotype support for interceptor binding lookup on partial beans [DELTASPIKE-910] - Add EntityRepository.getPrimaryKey(E entity) [DELTASPIKE-922] - OSGi support for Security Module Task [DELTASPIKE-961] - prepare v1.4.2 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.5.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.5.0 Bug [DELTASPIKE-963] - Header injection due to unescaped key in JsfUtils [DELTASPIKE-965] - EntityRepository.save() is broken for entities with String ID [DELTASPIKE-971] - CLIENTWINDOW mode broken in IE10 Improvement [DELTASPIKE-613] - Avoid windowhandler.html in GET requests from links [DELTASPIKE-817] - API and Core contain types recognized as managed beans but declaring an illegal bean type [DELTASPIKE-853] - Use @Stereotype for interface/enum/implicit bean discovery [DELTASPIKE-897] - check configuration of a ClassDeactivator [DELTASPIKE-928] - Allow to disable storeWindowTree() on ClientWindow mode [DELTASPIKE-942] - DeltaSpike fails to start with corrupted persistence.xml file. [DELTASPIKE-962] - Refactor windowhandler.html [DELTASPIKE-966] - Document ClientWindow configuration [DELTASPIKE-968] - ClientWindowMode shows white loading page for button navigation [DELTASPIKE-969] - Minor doc fixes around data module. [DELTASPIKE-972] - Center windowhandler.html messages [DELTASPIKE-973] - Fixed method name in Configuration doc [DELTASPIKE-975] - dependent-scoped EntityManagerResolver get destroyed too early Task [DELTASPIKE-964] - Publish Javadoc 1.4.2 [DELTASPIKE-980] - prepare v1.5.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.5.1.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.5.1 Bug [DELTASPIKE-978] - ClassCastException with Native Queries [DELTASPIKE-984] - DynamicMBeanWrapper throws misleading MBeanException saying that the required action does not exist when MBean method (deliberately) throws an exception [DELTASPIKE-985] - It's not possible to run tests against latest WildFly [DELTASPIKE-990] - BeanBuilder#readFromType drops java.lang.Object as type [DELTASPIKE-993] - Disabled initialRedirect is generating dswid=null [DELTASPIKE-994] - MessageBundleExtension: NPE on Shutdown [DELTASPIKE-997] - org.apache.deltaspike.data.impl.meta.unit.PersistenceUnitsTest fails on weblogic [DELTASPIKE-999] - several tests failing on weblogic due to missing org.quartz.utils package [DELTASPIKE-1002] - NPE when job startScopes is set to empty Improvement [DELTASPIKE-986] - support for atomikos [DELTASPIKE-987] - check for @Version [DELTASPIKE-991] - javax.interceptor.Interceptor.Priority.PLATFORM_BEFORE is used per default [DELTASPIKE-992] - optional support for bv 1.1 [DELTASPIKE-1001] - Skip caching ClassDeactivation for some project stages [DELTASPIKE-1004] - unified base-implementation for InvocationContext [DELTASPIKE-1008] - Introduce @MBean.type() to customize type in JMX bean objectName New Feature [DELTASPIKE-955] - Built in class deactivator [DELTASPIKE-1003] - support @Produces in partial-beans [DELTASPIKE-1005] - @Transactional and @TransactionScoped support for @Repository Task [DELTASPIKE-952] - Document Proxy Module [DELTASPIKE-956] - Clearly document transaction integration patterns for repository classes [DELTASPIKE-979] - Document new ClientWindowConfig modes [DELTASPIKE-981] - update site and javadoc to 1.5.0 [DELTASPIKE-983] - Investigate issue with DeltaSpike Validation Module [DELTASPIKE-995] - Define a weblogic managed profile for arquillian tests [DELTASPIKE-998] - many deltaspike/modules/data/impl tests fail on weblogic. [DELTASPIKE-1000] - prepare v1.5.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.5.2.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.5.2 Bug [DELTASPIKE-839] - Data module test deployments pack individual classes instead of JARs [DELTASPIKE-1009] - unknown repository class [DELTASPIKE-1014] - SecuredAnnotationAuthorizer overwrites method-level annotation metadata with class-level annotation metadata [DELTASPIKE-1016] - JSF documentation broken [DELTASPIKE-1024] - WindowHandler: Loading... not displayed in initial request in new tab [DELTASPIKE-1026] - WindowHandler: Loading... not displayed in IE8 [DELTASPIKE-1027] - WindowHandler: "screenshot" still clickable in IE8 [DELTASPIKE-1028] - WindowHandler: JS error on IE8 [DELTASPIKE-1034] - DefaultEntityManagerHolder is not Serializeable Improvement [DELTASPIKE-989] - Document ClientWindow modes more detailed [DELTASPIKE-1015] - Support hierarchical BeanManager and Extensions [DELTASPIKE-1017] - spi for config-validation [DELTASPIKE-1019] - Enterprise container friendlier deltaspike-cdictrl-weld [DELTASPIKE-1021] - Enhance documentation for JSF module [DELTASPIKE-1025] - WindowHandler: Remember every body attr for the windowhandler.html [DELTASPIKE-1029] - WindowHandler: Avoid windowhandler streaming in some redirect cases [DELTASPIKE-1031] - Update profiles for Wildfly New Feature [DELTASPIKE-1023] - WindowHandling: refactor screenshot handling/remember scroll position [DELTASPIKE-1035] - Make DS PersistenceUnit public and also parse properties Task [DELTASPIKE-982] - improve internal description of our release-steps [DELTASPIKE-1011] - re-visit excluded tests for the wls profiles [DELTASPIKE-1012] - update site and javadoc to 1.5.1 [DELTASPIKE-1013] - remove outdated content [DELTASPIKE-1020] - improve core documentation [DELTASPIKE-1038] - prepare v1.5.2 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.5.3.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.5.3 Bug [DELTASPIKE-1039] - LinkageError on container reboot [DELTASPIKE-1043] - Loop redirect in error-page (404) with CLIENTWINDOW [DELTASPIKE-1044] - ClientWindow - skip links with "empty" href [DELTASPIKE-1046] - wildfly-remote profile is broken [DELTASPIKE-1050] - EntityManagerLookup isn't thread-safe [DELTASPIKE-1057] - Fix type parameters of OrderBy query processor [DELTASPIKE-1061] - custom annotation member values [DELTASPIKE-1063] - ClientWindow - StoreWindowTreeEnabledOnButtonClick prevents defined onclick [DELTASPIKE-1071] - URLs like ?&dswid=XYZ lead to window cloning Improvement [DELTASPIKE-1040] - ClassDeactivationUtils spams the log in ProjectStages Development and UnitTest [DELTASPIKE-1048] - Fix compiler warnings in Data module [DELTASPIKE-1049] - Avoid bean serializations / use ApplicationScoped instead Dependent for performance reasons [DELTASPIKE-1055] - JobRunnableAdapter should be pluggable [DELTASPIKE-1058] - add info in case of a global-alternative [DELTASPIKE-1059] - integrate @Scheduled Runnable with exception-control [DELTASPIKE-1062] - @Transactional and @TransactionScoped support for @Repository including qualifiers [DELTASPIKE-1065] - improve build-config per profile [DELTASPIKE-1072] - improve wls12 test-profiles New Feature [DELTASPIKE-1045] - Convenience repository classes exposing all EntityManager methods [DELTASPIKE-1054] - optional mode to switch from org.quartz.Job to java.lang.Runnable Task [DELTASPIKE-1041] - update site and javadoc to 1.5.2 [DELTASPIKE-1056] - document optional mode for java.lang.Runnable with @Scheduled [DELTASPIKE-1067] - Data module should use utils from core [DELTASPIKE-1073] - prepare v1.5.3 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.5.4.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.5.4 Bug [DELTASPIKE-1074] - Severe problem in setUrlParam() (windowhandler.js) [DELTASPIKE-1078] - Request binding throws exception when using forwards Improvement [DELTASPIKE-1076] - improve release-documentation [DELTASPIKE-1077] - improve documentation about ClassDeactivator and Deactivatable Task [DELTASPIKE-1075] - update site and javadoc to 1.5.3 [DELTASPIKE-1079] - update external resources [DELTASPIKE-1080] - prepare v1.5.4 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.6.0.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.6.0 Sub-task [DELTASPIKE-1100] - Support remove expressions Bug [DELTASPIKE-1087] - core-jmx: missing blank in log statement [DELTASPIKE-1097] - Fix Data Module tests for TomEE7 [DELTASPIKE-1105] - Cannot sort on a find all query [DELTASPIKE-1107] - Wrong usage of Dependency Scope=Import in deltaspike-scheduler-module-impl [DELTASPIKE-1108] - Tests in 'deltaspike-data-module-test-ee7' fail with Weld and should be ignored Improvement [DELTASPIKE-1066] - [perf] enhance caching in RepositoryEntity [DELTASPIKE-1090] - ProjectStage config key with just uppercase letters and '_' [DELTASPIKE-1092] - improve documentation [DELTASPIKE-1095] - Move persistence/orm.xml mapping + parsing from DATA impl to JPA api/spi New Feature [DELTASPIKE-1081] - Offer the possibility to provide the cron expression via configuration [DELTASPIKE-1093] - add @Throttled [DELTASPIKE-1094] - add @Futureable [DELTASPIKE-1096] - project-stage bridge for jsf [DELTASPIKE-1099] - @Locked: method access controlled by a ReadWriteLock Task [DELTASPIKE-1068] - Merge data ClassUtils to core ClassUtils [DELTASPIKE-1069] - evaluate interceptors for producer-methods [DELTASPIKE-1082] - document configurable cron-expressions [DELTASPIKE-1083] - update site and javadoc to 1.5.4 [DELTASPIKE-1106] - prepare v1.6.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.6.1.txt ================================================ Release Notes - Apache DeltaSpike - Version 1.6.1 Improvement [DELTASPIKE-1113] - WindowIdHtmlRenderer should skip DELEGATED [DELTASPIKE-1116] - allow conditional injection-point customization in test-classes [DELTASPIKE-1118] - ThrottledInterceptor needs to use an InterceptorStrategy [DELTASPIKE-1119] - FutureableInterceptor needs to use an InterceptorStrategy [DELTASPIKE-1120] - LockedInterceptor needs to use an InterceptorStrategy [DELTASPIKE-1124] - optimize internal handling of cron-config updates [DELTASPIKE-1125] - make ParentExtension mechanism configurable [DELTASPIKE-1130] - improve cdi-ctrl-tck [DELTASPIKE-1131] - improve MockHttpSession New Feature [DELTASPIKE-1117] - add cache(long ms) to ConfigResolver.TypedResolver [DELTASPIKE-1126] - variable support in ConfigResolver Task [DELTASPIKE-1006] - document @Transactional and @TransactionScoped support for @Repository [DELTASPIKE-1032] - document creating quartz scheduling jobs at runtime [DELTASPIKE-1112] - Document - getting started w/ DeltaSpike using Gradle [DELTASPIKE-1114] - update site and javadoc to 1.6.0 [DELTASPIKE-1128] - add deltaspike.future.timeout to CoreBaseConfig [DELTASPIKE-1132] - prepare v1.6.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.7.0.txt ================================================ Release Notes - DeltaSpike - Version 1.7.0 Sub-task [DELTASPIKE-1102] - Support TOP and FIRST Bug [DELTASPIKE-1089] - No possible to select non Entity object via Native query [DELTASPIKE-1138] - FutureableTest not compatible with weld v1.x [DELTASPIKE-1139] - TypedResolver might prematurely return null under high load [DELTASPIKE-1141] - @Futureable @Locked and @EnableInterceptor cannot work with CDI 1.0/Weld 1.x [DELTASPIKE-1142] - Documentation wrong: an interface does not implement another interface [DELTASPIKE-1144] - Existing window name may lead to infinite redirects [DELTASPIKE-1147] - TypedResolver behaves different than ConfigResolver [DELTASPIKE-1151] - CdiTestSuiteRunner.LogRunListener logs multiple times [DELTASPIKE-1156] - Scheduler tests are failing in TomEE [DELTASPIKE-1158] - It is not possible to override generic methods defined within delegates Improvement [DELTASPIKE-1088] - Provide a BOM for deltaspike with no transitive dependencies [DELTASPIKE-1091] - Weld core BOM update in next 2.3/3.x release [DELTASPIKE-1135] - Cannot use typesafe messages on Application scope initialization observer [DELTASPIKE-1148] - Reduce redirects in CLIENTWINDOW mode when opening a link in a new tab [DELTASPIKE-1149] - CLIENTWINDOW tokenizedRedirect should ignore ctrl-key [DELTASPIKE-1150] - Ignore "external" links in CLIENTWINDOW-mode [DELTASPIKE-1153] - Expand query support to not require a where clause [DELTASPIKE-1154] - [perf] use EntityVerifier in a static way [DELTASPIKE-1155] - tableName fallback to Metamodel only when not defined on @Table [DELTASPIKE-1159] - BOM Needs a dependency management section [DELTASPIKE-1161] - [perf] avoid Instance#Select [DELTASPIKE-1162] - [perf] avoid duplicate RepositoryComponent lookup [DELTASPIKE-1163] - [perf] avoid duplicate RepositoryComponent lookup [DELTASPIKE-1164] - [perf] QueryBuilder can be ApplicationScoped [DELTASPIKE-1168] - [perf] optimize DelegateQueryBuilder#selectDelegate [DELTASPIKE-1169] - Separate concerns of EntityRepository [DELTASPIKE-1170] - Proxy should be invocationHandler class independent [DELTASPIKE-1171] - [perf] cache interceptors per proxy method New Feature [DELTASPIKE-1036] - Repositories should support java.util.Optional as return type [DELTASPIKE-1152] - Add support for firstXX in query method expressions [DELTASPIKE-1157] - Repository.findBy methods do not allow an override to add query hints. [DELTASPIKE-1160] - Not possible to select non Entity or other Entity object via Native query [DELTASPIKE-1165] - Repositories support returning Stream in addition to List Task [DELTASPIKE-1047] - Setup builds for TomEE 7 [DELTASPIKE-1136] - update site and javadoc to 1.6.1 [DELTASPIKE-1140] - improve build for ee7-tests [DELTASPIKE-1145] - improve tests with @TransactionScoped [DELTASPIKE-1146] - improve test-code of TransactionalBean#executeInTransaction [DELTASPIKE-1166] - Prep the 1.7 release ================================================ FILE: deltaspike/readme/ReleaseNotes-1.7.1.txt ================================================ Release Notes - DeltaSpike - Version 1.7.1 Bug [DELTASPIKE-1167] - deltaspike configuration: Variable Replacement in Configured Values is NOT (!) stage aware [DELTASPIKE-1173] - DefaultEntityManagerHolder is not registered in uber jars when discovery is annotated [DELTASPIKE-1175] - Weld(1|2|3) profiles do not activate Weld profile in cdictrl [DELTASPIKE-1179] - [Deltaspike Data] ContextNotActiveException: WELD-001303: No active contexts for scope type jakarta.enterprise.context.ApplicationScoped [DELTASPIKE-1183] - NPE in proxy handler with concurrent requests Improvement [DELTASPIKE-1180] - Remove unused imports ================================================ FILE: deltaspike/readme/ReleaseNotes-1.7.2.txt ================================================ Release Notes - DeltaSpike - Version 1.7.2 Bug [DELTASPIKE-1191] - Update Test-Control gradle docs [DELTASPIKE-1194] - Distribution not including binary artifacts [DELTASPIKE-1196] - Syntax error in DOAP file [DELTASPIKE-1199] - Problems with ContextControl and Weld ContainerInitialized, ContainerShutdown event. [DELTASPIKE-1204] - Wildfly managed profiles blow up [DELTASPIKE-1207] - Incorrect exception handling in DynamicMBeanWrapper.invoke() [DELTASPIKE-1208] - deltaspike configuration: Variable Replacement in Configured Values is NOT fully stage aware [DELTASPIKE-1209] - Textual fixes for documentation of Data Module [DELTASPIKE-1210] - DelegateQueryHandler has missing Javadoc [DELTASPIKE-1211] - SingleResultType.OPTIONAL refers to nonexistent constant SINGLE [DELTASPIKE-1213] - LockedTest fails on OWB 1.1.x Improvement [DELTASPIKE-1201] - add logout link to security example [DELTASPIKE-1203] - create jpa examples [DELTASPIKE-1205] - create deltaspike data module examples New Feature [DELTASPIKE-1176] - Support void methods in Futureable Task [DELTASPIKE-1181] - Implement tests for Payara [DELTASPIKE-1186] - 1.7.1 Release execution and website clean up [DELTASPIKE-1187] - Document entity graph support [DELTASPIKE-1188] - Improve contributor guide [DELTASPIKE-1189] - Migrate index.html into git [DELTASPIKE-1192] - Fix increase in warning messages with DeltaSpike Data and Weld Wish [DELTASPIKE-1185] - Allow customization (name, description) of JMX managed methods' parameters ================================================ FILE: deltaspike/readme/ReleaseNotes-1.8.2.txt ================================================ Release Notes - DeltaSpike - Version 1.8.2 Bug [DELTASPIKE-1276] - Multiple license headers [DELTASPIKE-1299] - Order by items are applied in alphabetic order [DELTASPIKE-1310] - Please use https (SSL) for links to KEYS, hashes, sigs [DELTASPIKE-1313] - DeltaSpikeProxyInterceptorLookup fails on WAS [DELTASPIKE-1316] - add dynamic annotations feature, configurable via config [DELTASPIKE-1317] - AnnotatedCallableImpl blows up with ArrayOutofBounds when parsing enums [DELTASPIKE-1344] - deltaspike-cdictrl-owb has a transient runtime dependency on Shrinkwrap and Arquillian New Feature [DELTASPIKE-1319] - labeled alternatives [DELTASPIKE-1320] - global alternative spi to support custom (type-safe) mechanisms [DELTASPIKE-1337] - optional ClassFilter spi [DELTASPIKE-1338] - support class-filter per test Improvement [DELTASPIKE-1309] - Upgrade ASM [DELTASPIKE-1311] - Allow Excluded Repositories [DELTASPIKE-1329] - ProjectStageProducer should log changed values [DELTASPIKE-1331] - minor type improvement of the ViewConfigNode spi [DELTASPIKE-1332] - support further cases for custom view-meta-data [DELTASPIKE-1334] - javadoc for ConfigPreProcessor#beforeAddToConfig [DELTASPIKE-1339] - Add support for dynamic interceptor binding, added via Extension Task [DELTASPIKE-1257] - Research why BOM isn't working right in a release [DELTASPIKE-1312] - Upgrade to quartz-2.3.0 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.9.5.txt ================================================ Release Notes - DeltaSpike - Version 1.9.5 Bug [DELTASPIKE-1314] - ContainerCtrlTckTest fails with tomee7-build-managed [DELTASPIKE-1413] - dsrwid cookie should not be set to sameSite="None" [DELTASPIKE-1416] - deltaspike-core-impl.jar does not contain the Main class to execute in your Manifest.MF to Crypto [DELTASPIKE-1423] - JSF-2.3 managed() in FacesValidator and FacesConverter break CDI integration Improvement [DELTASPIKE-1420] - Update ASM to 9.1 ================================================ FILE: deltaspike/readme/ReleaseNotes-1.9.6.txt ================================================ Release Notes - DeltaSpike - Version 1.9.6 Bug [DELTASPIKE-1133] - Don't override the log level [DELTASPIKE-1427] - JUL Logging with {} as param leeds to NumberFormatException [DELTASPIKE-1433] - EntityManagerFactoryProducer should also provide a @Disposes method [DELTASPIKE-1453] - injecting config of Class got broken New Feature [DELTASPIKE-1431] - add easy way to disable InvocationResultLogger [DELTASPIKE-1444] - Create POJO and Record based Config [DELTASPIKE-1445] - Dynamic Config injection via a Supplier Improvement [DELTASPIKE-1426] - DeltaSpikeProxyFactory is slow on start [DELTASPIKE-1432] - Proxy class definition does not work [DELTASPIKE-1454] - Upgrade ASM to 9.3 Task [DELTASPIKE-1452] - upgrade to apache-parent 25 ================================================ FILE: deltaspike/readme/ReleaseNotes-2.0.0.txt ================================================ Release Notes - DeltaSpike - Version 2.0.0 This is the first release targeting jakarta.* package names. The target specification is JakartaEE-9 Sub-task [DELTASPIKE-1438] - Remove EAR support [DELTASPIKE-1439] - Remove Global Alternatives [DELTASPIKE-1440] - Remove Metadata Builders [DELTASPIKE-1460] - Move outdated APIs [DELTASPIKE-1466] - move beans.xml to CDI-3.0 style Bug [DELTASPIKE-1435] - dsrwid cookie should not be set to sameSite="None" - again [DELTASPIKE-1458] - DefaultConfigSourceProvider cannot be instantiated [DELTASPIKE-1467] - Saving existing entity throws an exception [DELTASPIKE-1469] - WindowIdHtmlRenderer loads wrong Javascript file New Feature [DELTASPIKE-1468] - AuditProvider (PrincipalProvider/TimestampsProvider) not working Improvement [DELTASPIKE-1238] - Create a better default TransactionStrategy [DELTASPIKE-1260] - Remove Servlet Module [DELTASPIKE-1261] - Remove BeanVal Module [DELTASPIKE-1262] - Remove CdiContainer control [DELTASPIKE-1263] - Remove BeanBuilder [DELTASPIKE-1265] - Align JSF module to features provided by JSF 2.3 [DELTASPIKE-1266] - Remove != JavaEE8 workarounds [DELTASPIKE-1434] - Namespace change javax to jakarta [DELTASPIKE-1455] - Allow to pass properties to Weld [DELTASPIKE-1456] - Introduce default methods for some functions in ConfigSource [DELTASPIKE-1461] - Cleanup Window/ViewAcessScoped [DELTASPIKE-1463] - Reimplement DS ClientWindow as native Faces ClientWindow [DELTASPIKE-1464] - Use jfwid over dswid [DELTASPIKE-1465] - print ConfigSource of the values for deltaspike.config.log Test [DELTASPIKE-1206] - support for CDI 2.0 feature Wish [DELTASPIKE-1235] - DS 2: check if we can remove our ContextControl [DELTASPIKE-1376] - Warning on CDI 2.0 Task [DELTASPIKE-1437] - DeltaSpike-2.0 umbrella ticket [DELTASPIKE-1471] - Remove @EnableInterceptors in favor of CDI InterceptionFactory ================================================ FILE: deltaspike/test-utils/pom.xml ================================================ 4.0.0 org.apache.deltaspike parent 2.0.2-SNAPSHOT ../parent/pom.xml org.apache.deltaspike.test test-utils Apache DeltaSpike Test-Utils This package contains our Test Categories and other useful stuff for running our tests. org.jboss.shrinkwrap shrinkwrap-api ${shrinkwrap.version} org.jboss.arquillian.container arquillian-container-test-spi ${arquillian.version} org.apache.maven maven-artifact ${maven.artifact.version} junit junit compile true 1.2.6 ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/arquillian/DeltaSpikeServerUtilAppender.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.arquillian; import org.apache.deltaspike.test.category.DeltaSpikeTest; import org.apache.deltaspike.test.utils.Serializer; import org.jboss.arquillian.container.test.spi.client.deployment.CachedAuxilliaryArchiveAppender; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import static org.apache.deltaspike.test.utils.BeansXmlUtil.BEANS_XML_ALL; public class DeltaSpikeServerUtilAppender extends CachedAuxilliaryArchiveAppender { @Override protected Archive buildArchive() { return ShrinkWrap.create(JavaArchive.class, "test-utils.jar") .addPackage(Serializer.class.getPackage()) .addPackage(DeltaSpikeTest.class.getPackage()) .addAsManifestResource(BEANS_XML_ALL, "beans.xml"); } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/arquillian/DeltaSpikeTestUtilExtension.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.arquillian; import org.jboss.arquillian.container.test.spi.client.deployment.AuxiliaryArchiveAppender; import org.jboss.arquillian.core.spi.LoadableExtension; public class DeltaSpikeTestUtilExtension implements LoadableExtension { @Override public void register(final ExtensionBuilder extensionBuilder) { extensionBuilder.service(AuxiliaryArchiveAppender.class, DeltaSpikeServerUtilAppender.class); extensionBuilder.service(AuxiliaryArchiveAppender.class, TestUtilDependenciesAppender.class); } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/arquillian/TestUtilDependenciesAppender.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.arquillian; import org.jboss.arquillian.container.test.spi.client.deployment.CachedAuxilliaryArchiveAppender; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; public class TestUtilDependenciesAppender extends CachedAuxilliaryArchiveAppender { @Override protected Archive buildArchive() { return ShrinkWrap.create(JavaArchive.class, "maven-artifact.jar") .addPackage("org.apache.maven.artifact.versioning"); } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/DeltaSpikeTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * This class contains a few constants and utility methods. */ public class DeltaSpikeTest { public static final String DELTASPIKE_PROPERTIES = "META-INF/apache-deltaspike.properties"; private DeltaSpikeTest() { // just to prevent initialisation! } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/EnterpriseArchiveProfileCategory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * Category marker interface. Tests which are packaged as ear-file. */ public interface EnterpriseArchiveProfileCategory { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/FullProfileCategory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * Category marker interface. Tests which are Full profile minimum. */ public interface FullProfileCategory { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/SeCategory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * Category marker interface for tests which only run outside of a java-ee server * e.g. due to a restriction of our test-setup with packaging resources with the same name from different sources * like multiple parallel versions of apache-deltaspike.properties which is caused by the autom. unpack to the * integration-test module. */ public interface SeCategory { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/WebEEProfileCategory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * Category marker interface. Tests which are Web profile minimum. */ public interface WebEEProfileCategory { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/category/WebProfileCategory.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.category; /** * Category marker interface. Tests which are Web profile minimum. */ public interface WebProfileCategory { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/control/LockedContainerVersions.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.control; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value = { ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface LockedContainerVersions { } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/control/LockedImplementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.control; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.apache.deltaspike.test.utils.Implementation; /** * This annotation is used to define the {@link #implementations()} which the test is allowed to run. * * If {@link #implementations()} is not defined, It will be used all available implementations * defined on {@link Implementation}. * * A specific implementation can have {@link #versions()} range locked through the use of {@link LockedVersionRange} * @author rafaelbenevides * @author struberg * */ @Target(value = { ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface LockedImplementation { /** * If defined, the test will only run if one of those implementations get detected */ Implementation[] implementations() default {}; /** * Can be used to further restrict the implementation for {@link #implementations()}. */ LockedVersionRange[] versions() default { }; /** * If defined, the test will NOT run if one of those implementations get detected */ Implementation[] excludedImplementations() default {}; /** * Can be used to further restrict the implementation for {@link #excludedImplementations()} ()}. */ LockedVersionRange[] excludedVersions() default {}; } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/control/LockedVersionRange.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.control; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.apache.deltaspike.test.utils.Implementation; /** * It allows to specify the version range that the test is allowed to run for an specified {@link #implementation()}. * * The {@link #versionRange()} attribute uses the Maven version range pattern * @author rafaelbenevides * */ @Target(value = { ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface LockedVersionRange { Implementation implementation(); String versionRange(); } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/control/VersionControlRule.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.control; import java.util.Arrays; import org.apache.deltaspike.test.utils.CdiContainerUnderTest; import org.apache.deltaspike.test.utils.Implementation; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; /** * * This {@link TestRule} allows a test to check those methods annotated with {@link LockedImplementation}. * * You can define some {@link LockedImplementation}. Example: * *
 *     @LockedCDIImplementation(cdiImplementations = {
 *           CdiImplementation.OWB11,
 *           CdiImplementation.OWB12
 *   })
 * 
* * * You can also define specific versions of a specific implementation. Example: * *
 *     @LockedCDIImplementation(versions = {
 *           @LockedVersionRange(implementation = CdiImplementation.WELD11, versionRange = "[1.1.13,1.2)"),
 *           @LockedVersionRange(implementation = CdiImplementation.WELD20, versionRange = "[2.0.1.Final,2.1)")
 *           })
 * 
* * @author rafaelbenevides * @author struberg */ public class VersionControlRule implements TestRule { private static final Implementation[] EMPTY_IMPL = new Implementation[0]; @Override public Statement apply(final Statement base, final Description description) { return new Statement() { @Override public void evaluate() throws Throwable { LockedImplementation lockedCDIImplAnnotation = description .getAnnotation(LockedImplementation.class); // no @LockedCDIImplementation present or if running specified Container if (lockedCDIImplAnnotation == null) { base.evaluate(); } else { checkAnnotation(lockedCDIImplAnnotation, base); } } private void checkAnnotation(LockedImplementation lockedImplAnnotation, Statement base) throws Throwable { Implementation[] implementations = getImplementations(lockedImplAnnotation.implementations(), lockedImplAnnotation.versions()); // Run the test if there is no explicit list of implementations to only run on. boolean shouldRun = implementations.length == 0; for (Implementation impl : implementations) { String versionRange = getLockedVersionRange(lockedImplAnnotation.versions(), impl); if (CdiContainerUnderTest.isImplementationVersion(impl, versionRange)) { shouldRun = true; } } // now check the exclude list: implementations to NOT run on! final Implementation[] excludedImplementations = getImplementations(lockedImplAnnotation.excludedImplementations(), lockedImplAnnotation.excludedVersions()); for (Implementation impl : excludedImplementations) { String versionRange = getLockedVersionRange(lockedImplAnnotation.excludedVersions(), impl); if (CdiContainerUnderTest.isImplementationVersion(impl, versionRange)) { shouldRun = false; } } if (shouldRun) { base.evaluate(); } } /** * Get the locked version Range * * @return the locked version range */ private String getLockedVersionRange(LockedVersionRange[] versions, Implementation cdiImpl) { for (LockedVersionRange versionRange : versions) { if (versionRange.implementation().equals(cdiImpl)) { return versionRange.versionRange(); } } return null; } }; } private Implementation[] getImplementations(Implementation[] implementations, LockedVersionRange[] lockedVersionRanges) { if (implementations != null && implementations.length > 0) { return implementations; } if (lockedVersionRanges != null && lockedVersionRanges.length > 0) { return Arrays.stream(lockedVersionRanges) .map(lr -> lr.implementation()) .distinct() .toArray(Implementation[]::new); } return EMPTY_IMPL; } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/utils/BeansXmlUtil.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.utils; import org.jboss.shrinkwrap.api.asset.Asset; import org.jboss.shrinkwrap.api.asset.StringAsset; public class BeansXmlUtil { /** * A Beans.xml instance enabling Discovery-Mode ALL for unit tests */ public static final Asset BEANS_XML_ALL = new StringAsset(""); private BeansXmlUtil() { } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/utils/CdiContainerUnderTest.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.utils; import java.net.URL; import java.util.jar.Attributes; import java.util.jar.Manifest; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; /** * A small helper class which checks if the container which is currently being tested matches the given version RegExp */ public class CdiContainerUnderTest { private CdiContainerUnderTest() { // utility class ct } /** * Checks whether the current container matches the given version regexps. * * @param containerRegExps * container versions to test against. e.g. 'owb-1\\.0\\..*' or 'weld-2\\.0\\.0\\..*' */ public static boolean is(String... containerRegExps) { String containerVersion = System.getProperty("cdicontainer.version"); if (containerVersion == null) { return false; } for (String containerRe : containerRegExps) { if (containerVersion.matches(containerRe)) { return true; } } return false; } /** * Verify if the runtime is using the following Implementation * * @param implementation * @param versionRange * optional - If not defined it will used the range defined on {@link Implementation} * @return * @throws InvalidVersionSpecificationException */ public static boolean isImplementationVersion(Implementation implementation, String versionRange) throws InvalidVersionSpecificationException { Class implementationClass = tryToLoadClassForName(implementation.getImplementationClassName()); if (implementationClass == null) { return false; } VersionRange range = VersionRange.createFromVersionSpec(versionRange == null ? implementation .getVersionRange() : versionRange); String containerVersion = getJarSpecification(implementationClass); return containerVersion != null && range.containsVersion(new DefaultArtifactVersion(containerVersion)); } private static Class tryToLoadClassForName(String name) { try { return loadClassForName(name); } catch (ClassNotFoundException e) { // do nothing - it's just a try return null; } } private static Class loadClassForName(String name) throws ClassNotFoundException { try { // Try WebApp ClassLoader first return Class.forName(name, false, // do not initialize for faster startup getClassLoader(null)); } catch (ClassNotFoundException ignore) { // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib) return Class.forName(name, false, // do not initialize for faster startup CdiContainerUnderTest.class.getClassLoader()); } } private static ClassLoader getClassLoader(Object o) { return getClassLoaderInternal(o); } private static ClassLoader getClassLoaderInternal(Object o) { ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null && o != null) { loader = o.getClass().getClassLoader(); } if (loader == null) { loader = CdiContainerUnderTest.class.getClassLoader(); } return loader; } private static String getJarVersion(Class targetClass) { String manifestFileLocation = getManifestFileLocationOfClass(targetClass); try { return new Manifest(new URL(manifestFileLocation).openStream()) .getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION); } catch (Exception e) { return null; } } private static String getJarSpecification(Class targetClass) { String manifestFileLocation = getManifestFileLocationOfClass(targetClass); try { return new Manifest(new URL(manifestFileLocation).openStream()) .getMainAttributes().getValue(Attributes.Name.SPECIFICATION_VERSION); } catch (Exception e) { return null; } } private static String getManifestFileLocationOfClass(Class targetClass) { String manifestFileLocation; try { manifestFileLocation = getManifestLocation(targetClass); } catch (Exception e) { // in this case we have a proxy manifestFileLocation = getManifestLocation(targetClass.getSuperclass()); } return manifestFileLocation; } private static String getManifestLocation(Class targetClass) { String classFilePath = targetClass.getCanonicalName().replace('.', '/') + ".class"; String manifestFilePath = "/META-INF/MANIFEST.MF"; String classLocation = targetClass.getResource(targetClass.getSimpleName() + ".class").toString(); return classLocation.substring(0, classLocation.indexOf(classFilePath) - 1) + manifestFilePath; } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/utils/Implementation.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.utils; public enum Implementation { OWB11 ("org.apache.webbeans.container.BeanManagerImpl", "[1.1,1.2)"), OWB12 ("org.apache.webbeans.container.BeanManagerImpl", "[1.2,1.3)"), WELD11("org.jboss.weld.manager.BeanManagerImpl", "[1.1,1.2)"), WELD12("org.jboss.weld.manager.BeanManagerImpl", "[1.2,1.3)"), WELD20("org.jboss.weld.manager.BeanManagerImpl", "[2.0,2.1)"), MYFACES40("jakarta.faces.annotation.FacesConfig", "[4.0,4.1)"); // not really a CDI implementation but the mechanism works as well. private final String implementationClassName; private final String versionRange; Implementation(String implementationClassName, String versionRange) { this.implementationClassName = implementationClassName; this.versionRange = versionRange; } public String getImplementationClassName() { return implementationClassName; } public String getVersionRange() { return versionRange; } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/utils/Serializer.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * A few helper methods for testing serialisation. * They help serializing to a byte[] and back to the object */ public class Serializer { /** * Serializes the given instance to a byte[] and immediately * de-serialize it back. * @param original instance * @return the deserialized new instance */ public T roundTrip(T original) { return deserialize(serialize(original)); } /** * Serializes the given instance to a byte[]. */ public byte[] serialize(T o) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; oos = new ObjectOutputStream(baos); oos.writeObject(o); return baos.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } } /** * De-serializes the given byte[] to an instance of T. */ public T deserialize(byte[] serial) { try { ByteArrayInputStream bais = new ByteArrayInputStream(serial); ObjectInputStream ois = new ObjectInputStream(bais); return (T) ois.readObject(); } catch (Exception e) { throw new RuntimeException(e); } } } ================================================ FILE: deltaspike/test-utils/src/main/java/org/apache/deltaspike/test/utils/ShrinkWrapArchiveUtil.java ================================================ /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.deltaspike.test.utils; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.*; import java.util.logging.Logger; /** * Lots of neat little helpers to more easily create JavaArchives from marker files on the classpath. * This should finally get moved to ShrinkWrap core! * * TODO This class should get moved to ShrinkWrap itself! */ public class ShrinkWrapArchiveUtil { private static final Logger LOG = Logger.getLogger(ShrinkWrapArchiveUtil.class.getName()); private ShrinkWrapArchiveUtil() { // private ct for utility class } /** * Resolve all markerFiles from the current ClassPath and package the root nodes * into a JavaArchive. * * @param classLoader to use * @param markerFile finding this marker file will trigger creating the JavaArchive. * @param includeIfPackageExists if not null, we will only create JavaArchives if the given package exists * @param excludeIfPackageExists if not null, we will not create JavaArchives if the given package exists. * This has a higher precedence than includeIfPackageExists. */ public static JavaArchive[] getArchives(ClassLoader classLoader, String markerFile, String[] includeIfPackageExists, String[] excludeIfPackageExists, String archiveName) { if (classLoader == null) { classLoader = ShrinkWrapArchiveUtil.class.getClassLoader(); } try { Enumeration foundFiles = classLoader.getResources(markerFile); List archives = new ArrayList(); int numArchives = 0; while (foundFiles.hasMoreElements()) { URL foundFile = foundFiles.nextElement(); LOG.fine("Evaluating Java ClassPath URL " + foundFile.toExternalForm()); String suffix = (numArchives == 0) ? "" : Integer.toString(numArchives); JavaArchive archive = createArchive(foundFile, markerFile, includeIfPackageExists, excludeIfPackageExists, archiveName + suffix); if (archive != null) { LOG.info("Test " + getTestName() + " Adding Java ClassPath URL as JavaArchive " + foundFile.toExternalForm()); archives.add(archive); numArchives++; } } return archives.toArray(new JavaArchive[archives.size()]); } catch (IOException ioe) { throw new RuntimeException(ioe); } } private static JavaArchive createArchive(URL foundFile, String markerFile, String[] includeIfPackageExists, String[] excludeIfPackageExists, String archiveName) throws IOException { String urlString = foundFile.toString(); int idx = urlString.lastIndexOf(markerFile); urlString = urlString.substring(0, idx); String jarUrlPath = isJarUrl(urlString); if (jarUrlPath != null) { JavaArchive foundJar = ShrinkWrap.createFromZipFile(JavaArchive.class, new File(URI.create(jarUrlPath))); if (excludeIfPackageExists != null) { for (String excludePackage : excludeIfPackageExists) { if (foundJar.contains(excludePackage.replaceAll("\\.", "\\/"))) { return null; } } } if (includeIfPackageExists != null) { for (String includePackage : includeIfPackageExists) { if (foundJar.contains(includePackage.replaceAll("\\.", "\\/"))) { return foundJar; } } } return null; // couldn't find any jar } else { File f = new File( (new URL(ensureCorrectUrlFormat(urlString))).getFile() ); if (!f.exists()) { // try a fallback if the URL contains %20 -> spaces if (urlString.contains("%20")) { urlString = urlString.replaceAll("%20", " "); f = new File( (new URL(ensureCorrectUrlFormat(urlString))).getFile() ); } } return addFileArchive(f, includeIfPackageExists, excludeIfPackageExists, archiveName); } } private static JavaArchive addFileArchive(File archiveBasePath, String[] includeIfPackageExists, String[] excludeIfPackageExists, String archiveName) throws IOException { if (!archiveBasePath.exists()) { return null; } if (archiveName == null) { archiveName = UUID.randomUUID().toString(); } JavaArchive ret = null; JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class, archiveName + ".jar"); if (includeIfPackageExists == null) { // no include rule, thus add it immediately ret = javaArchive; } int basePathLength = archiveBasePath.getAbsolutePath().length() + 1; for (File archiveEntry : collectArchiveEntries(archiveBasePath) ) { String entryName = archiveEntry.getAbsolutePath().substring(basePathLength); // exclude rule if (excludeIfPackageExists(entryName, excludeIfPackageExists)) { continue; } // include rule if (ret == null && includeIfPackageExists(entryName, includeIfPackageExists)) { ret = javaArchive; } if (entryName.endsWith(".class")) { String className = pathToClassName(entryName.substring(0, entryName.length() - (".class".length()))); try { javaArchive.addClass(className); } catch (Throwable t) { LOG.info("Ignoring class " + className + " due to " + t.getMessage()); } } else { javaArchive.addAsResource(archiveEntry, entryName.replace('\\', '/')); } } return ret; } private static List collectArchiveEntries(File archiveBasePath) { if (archiveBasePath.isDirectory()) { List archiveEntries = new ArrayList(); File[] files = archiveBasePath.listFiles(); for (File file : files) { if (file.isDirectory()) { archiveEntries.addAll(collectArchiveEntries(file)); } else { archiveEntries.add(file); } } return archiveEntries; } return Collections.emptyList(); } private static boolean excludeIfPackageExists(String jarEntryName, String[] excludeOnPackages) { if (excludeOnPackages != null) { String packageName = pathToClassName(jarEntryName); for (String excludeOnPackage : excludeOnPackages) { if (packageName.startsWith(excludeOnPackage)) { return true; } } } return false; } private static boolean includeIfPackageExists(String jarEntryName, String[] includeOnPackages) { if (includeOnPackages == null ) { return true; } String packageName = pathToClassName(jarEntryName); for (String includeOnPackage : includeOnPackages) { if (packageName.startsWith(includeOnPackage)) { return true; } } return false; } /** * check if the given url path is a Jar * @param urlPath to check */ private static String isJarUrl(String urlPath) { // common prefixes of the url are: jar: (tomcat), zip: (weblogic) and wsjar: (websphere) final int jarColon = urlPath.indexOf(':'); if (urlPath.endsWith("!/") && jarColon > 0) { urlPath = urlPath.substring(jarColon + 1, urlPath.length() - 2); return urlPath; } return null; } private static String ensureCorrectUrlFormat(String url) { //fix for wls if (!url.startsWith("file:/")) { url = "file:/" + url; } return url; } private static String pathToClassName(String pathName) { return pathName.replace('/', '.').replace('\\', '.'); // replace unix and windows separators } public static String getTestName() { StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); String testName = "unknown"; for (StackTraceElement ste : stackTraceElements) { if (ste.getClassName().contains("Test")) { testName = ste.getClassName(); break; } } return testName; } } ================================================ FILE: deltaspike/test-utils/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension ================================================ # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # org.apache.deltaspike.test.arquillian.DeltaSpikeTestUtilExtension ================================================ FILE: deltaspike/test-utils/src/main/resources/arquillian-jboss.xml ================================================ -client -Xms64m -Xmx1024m -Dcdicontainer.version=${cdicontainer.version} ${jacoco.agent} false true ${cdicontainer.version} ${arquillian.jboss_home} -client -Xms64m -Xmx1024m -Djboss.socket.binding.port-offset=50000 -Dcdicontainer.version=${cdicontainer.version} -Ddeltaspike.bean-manager.delegate_lookup=false false 59990 ================================================ FILE: deltaspike/test-utils/src/main/resources/arquillian.xml ================================================ t3://localhost:7001 weblogic1 weblogic1 AdminServer ${WLS_HOME} ${MW_HOME} ${MW_HOME}/wlserver ${DS_DOMAIN_DIR} ${DS_DOMAIN_TARGET} ${DS_ADMIN_URL} ${DS_ADMIN_USER} ${DS_ADMIN_PSWD} 600 target/tomee -1 -1 -1 target/arquillian-test-working-dir -Dcdicontainer.version=${cdicontainer.version} true testDatabase = new://Resource?type=DataSource testDatabase.JdbcDriver = org.hsqldb.jdbcDriver testDatabase.JdbcUrl = jdbc:hsqldb:mem:testdb testDatabase.JtaManaged = true ${arquillian.glassfish_home} 24848 ${arquillian.payara_home} 24848 ================================================ FILE: doap_DeltaSpike.rdf ================================================ 2014-04-11 Apache DeltaSpike DeltaSpike is a collection of portable Extensions for CDI Containers Apache DeltaSpike is a suite of portable CDI (Contexts & Dependency Injection) extensions intended to make application development easier when working with CDI and Java EE. Some of its key features include: - A core runtime that supports component configuration, type safe messaging and internationalization, and exception handling. - A suite of utilities to make programmatic bean lookup easier. - A plugin for Java SE to bootstrap both JBoss Weld and Apache OpenWebBeans outside of a container. - JSF integration, including backporting of JSF 2.2 features for Java EE 6. - JPA integration and transaction support. - A Data module, to create an easy to use repository pattern on top of JPA. - Quartz integration Testing support is also provided, to allow you to do low level unit testing of your CDI enabled projects. Java Mark Struberg ================================================ FILE: documentation/README.md ================================================ title: Apache DeltaSpike Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike documentation ------------------------- DeltaSpike documentation uses [Asciidoc](http://www.methods.co.nz/asciidoc/). You're welcome to contribute. License ------- Apache DeltaSpike is licensed under ALv2. See the LICENSE file for the full license text. Publish procedure ----------------- To publish the documentation at [DeltaSpike Site](http://deltaspike.apache.org/) you have do the following steps: Put the following information in your ~/.m2/settings.xml file deltaspike-site To publish to [staging area](http://deltaspike.apache.org/staging/documentation), run: mvn clean site-deploy -Pstaging To publish to [production area](http://deltaspike.apache.org/documentation), run: mvn clean site-deploy ================================================ FILE: documentation/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike deltaspike-documentation 2.0.2-SNAPSHOT pom Apache DeltaSpike Documentation Documentation of DeltaSpike project. http://deltaspike.apache.org/documentation https://svn.apache.org/repos/infra/sites/deltaspike/documentation/ org.asciidoctor asciidoctor-maven-plugin output-html site process-asciidoc .. documentation org.apache.maven.plugins maven-scm-publish-plugin scm-publish site-deploy publish-scm ================================================ FILE: documentation/src/main/asciidoc/build.adoc ================================================ = Build and Test DeltaSpike from Source :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. The DeltaSpike source (modules and examples) is provided for inspection, contribution and testing purposes. The source must be built with Maven, which has been used to automate the compilation, testing and packaging processes. Arquillian tests are included with the source and a CDI implementation or container can be specified with which to carry out the tests. In all cases, to obtain the DeltaSpike source, link:https://deltaspike.apache.org/download.html[download] `deltaspike-project-{latestStable}-source-release.zip` and extract the contents. NOTE: You can also obtain the DeltaSpike source from the project Git repository. The repository is subject to change and it can be used for contributing but should not be used in production environments. For more information, see <>. == Build without CDI Implementation Tests DeltaSpike can be built without executing tests against a CDI implementation, with the following commands: [source,shell,subs="+attributes"] ---- $ cd /path/to/deltaspike-project-{latestStable}/ $ mvn clean install ---- == Build and Test with a CDI Implementation Tests can be executed with both the JBoss Weld and Apache OpenWebBeans CDI implementations. [cols="1,2a", options="header"] .Build Tests |=== |Container |Command to Execute Arquillian Tests |JBoss Weld 1.x (CDI 1.0) | [source,shell] ---- $ mvn clean install -PWeld1 -Dweld.version=1.1.33.Final ---- |JBoss Weld 2.x (CDI 1.2) | [source,shell] ---- $ mvn clean install -PWeld2 -Dweld.version=2.3.4.Final ---- |JBoss Weld 3.x (CDI 2.0) | [source,shell] ---- $ mvn clean install -PWeld3 -Dweld.version=3.0.0.Alpha16 ---- |Apache OpenWebBeans | [source,shell] ---- $ mvn clean install -POWB ---- |=== == Build and Test with a CDI Container Tests can be executed with JBoss Weld and Apache OpenWebBeans through Java EE 6+ application servers and containers. Configurations are currently provided as details in the table here. [cols="2,3a", options="header"] .Integration Tests |=== |Container |Command to Execute Arquillian Tests |Apache TomEE | [source,shell] ---- $ mvn clean install -Ptomee-build-managed ---- |JBoss AS7 (without AS7 installation) | [source,shell] ---- $ mvn clean install -Pjbossas-build-managed-7 ---- |JBoss AS7 (AS7 installation required) |Set `JBoss_HOME` [source,shell] ---- $ mvn clean install -Pjbossas-managed-7 ---- |JBoss WildFly 8 (without WildFly 8 installation) | [source,shell] ---- mvn clean install -Pwildfly-build-managed ---- |JBoss WildFly 8 (WildFly 8 installation required) |Set `WILDFLY_HOME` [source,shell] ---- $ mvn clean install -Pwildfly-managed ---- |Oracle GlassFish 3 (without GlassFish 3 installation) | [source,shell] ---- mvn clean install -Pglassfish-build-managed-3 ---- |Oracle GlassFish 3.1 (GlassFish 3.1 installation required) |Install GlassFish (default setup without admin-password) and start GlassFish with `asadmin start-domain` and `asadmin start-database`. [source,shell] ---- $ mvn clean install -Pglassfish-remote-3.1 ---- |Oracle GlassFish 4 (without Oracle GlassFish 4 installation) | [source,shell] ---- mvn clean install -Pglassfish-build-managed-4 ---- |Oracle WebLogic 12c |Install WebLogic 12c. Start Configuration Wizard to create a new basic WebLogic Domain. Default options and domain name = base_domain, administrator user name = weblogic1, administrator password = weblogic1. Set `WLS_HOME` so that `%WLS_HOME%.jar` exists. Start the domain. [source,shell] ---- $ mvn clean install -Pwls-remote-12c ---- |=== == Build and Debug with a Java EE6+ application servers Tests can be debugged through Java EE 6+ application servers. Configurations are currently provided as details in the table here. [cols="2,3a", options="header"] .Integration Tests with debug |=== |Container |Command to Execute Arquillian Tests with remote debugging |Apache TomEE |Use remote debuggig at port 5005 [source,shell] ---- mvn test -Ptomee-build-managed -Dtest=UnitTestName -Dopenejb.server.debug=true ---- |=== == Next * For analysis of the DeltaSpike source, see https://analysis.apache.org/dashboard/index/org.apache.deltaspike:deltaspike-project * For information about DeltaSpike automated Jenkins builds, see https://builds.apache.org/view/A-D/view/DeltaSpike/ ================================================ FILE: documentation/src/main/asciidoc/cdiimp.adoc ================================================ = Enable CDI For Your Java Environment :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike requires a CDI implementation to be available in the Java environment where your projects are deployed. The implementation provides the CDI essentials, managing dependency injection and contextual lifecycles. link:http://weld.cdi-spec.org/[JBoss Weld] and link:http://openwebbeans.apache.org/[Apache OpenWebBeans (OWB)] are two widely used CDI implementations. Dependent on the Java environment you choose, some setup may be necessary as detailed here. == Java EE6+ Containers CDI is part of Java EE6 and later so CDI implementations are included as standard in Java EE6+ compliant environments. There is no additional CDI configuration needed besides including the CDI-obligatory `beans.xml` file in your project. JBoss Weld is integrated in Java EE application servers including WildFly, JBoss Enterprise Application Platform, GlassFish, IBM WebSphere Application Server (8.5.5 and up) and Oracle WebLogic. Apache OpenWebBeans (OWB) is integrated in Java EE containers including Apache TomEE, Apache Geronimo, IBM WebSphere Application Server, and SiwPas. == Java EE5 and Servlet Containers CDI implementations are not distributed with Java EE5 application servers or Servlet-only environments such as Apache TomCat and Eclipse Jetty. You can use CDI in these environments by embedding a standalone CDI implementation. Both JBoss Weld and Apache OpenWebBeans can be used for this task; for more information, see the corresponding CDI implementation documentation. [[javase6]] == Java SE6+ CDI is not part of Java SE but it can still be used. JBoss Weld and Apache OpenWebBeans implementations can be used to act as dependency injection bean managers but the respective containers must be booted manually. DeltaSpike provides a dedicated Container Control module to enable applications deployed in Java SE environments to boot a CDI container. The Container Control module consists of the API component and components specific to the JBoss Weld, Apache OpenWebBeans and Apache OpenEJB CDI containers. The DeltaSpike module provides a layer of abstraction from the specific CDI containers, enabling you to write container-independent code in your project. Instructions are provided here for adding the required resources to Maven based, Gradle based and build independent projects and subsequently booting the CDI container from your project source code. === Declare CDI Dependencies ==== Dependencies for Maven and Gradle based Projects For Maven-based projects, the Container Control module is available in Maven Central together with the other DeltaSpike modules. You must configure your project to use the DeltaSpike Container Control API and one of the CDI container-specific modules. . Import the project as defined in link:/documentation/configure.html[Configure DeltaSpike in Your Projects] . Import the CDI Control API to your project. a. If you're using Maven, add the following to `pom.xml` + [source,xml] ---- org.apache.deltaspike.cdictrl deltaspike-cdictrl-api compile ---- + b. If you're using Gradle, add the following to `build.gradle` + [source] ---- dependencies { compile 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api' } ---- + . Add CDI container dependencies for one of the container options listed here - For JBoss Weld .. Add the JBoss Weld version to the list of properties, replacing the version as desired + [source,xml] ---- 2.3.3.Final ---- + .. Add the JBoss Weld dependency to the list of dependencies + [source,xml] ---- org.jboss.weld.se weld-se ${weld.version} runtime ---- + .. Add the DeltaSpike Weld-specific Container Control module to the list of dependencies + [source,xml] ---- org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld runtime ---- + - JBoss Weld with Gradle .. If you're using Gradle, add the following to `build.gradle` + [source] ---- def weldVersion = '2.3.3.Final' dependencies { runtime 'org.jboss.weld.se:weld-se:'+weldVersion runtime 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-weld' } ---- + - For Apache OpenWebBeans .. Add the Apache OpenWebBeans version to the list of properties, replacing the version as desired + [source,xml] ---- 1.6.3 ---- + .. Add the Apache OpenWebBeans dependencies to the list of dependencies + [source,xml] ---- org.apache.openwebbeans openwebbeans-impl ${owb.version} runtime org.apache.openwebbeans openwebbeans-spi ${owb.version} compile ---- + .. Add the DeltaSpike Apache OpenWebBeans-specific Container Control module to the list of dependencies + [source,xml] ---- org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb runtime ---- + - Apache OpenWebBeans with Gradle .. If you're using Gradle, add the following to `build.gradle` + [source] ---- def owbVersion = '1.6.3' dependencies { runtime 'org.apache.openwebbeans:openwebbeans-impl:'+owbVersion compile 'org.apache.openwebbeans:openwebbeans-spi:'+owbVersion runtime 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-owb' } ---- + - Save the `pom.xml` file changes + ---- mvn clean install ---- + - Save the `build.gradle` file changes + ---- gradle build ---- ==== Dependencies for build independent projects For build independent projects, the Container Control module is distributed together with the other DeltaSpike modules in `distribution-full-.zip`. You must add two of the files from the `cdictrl` directory to your project, namely `deltaspike-cdictrl-api.jar` and the .jar file that corresponds to the CDI container you have chosen. Add these files to the project `WEB-INF/lib` or `EAR/lib` directory for .war and .ear projects respectively. == Next * For more information about the Container Control module, see <>. * To understand how the various DeltaSpike modules can enhance and extend your applications, see <> and the individual module pages. * To see ready-to-deploy example DeltaSpike applications, see link:http://deltaspike.apache.org/examples.html[See DeltaSpike in Action]. ================================================ FILE: documentation/src/main/asciidoc/configuration.adoc ================================================ = DeltaSpike Configuration Mechanism :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Introduction The goal of the DeltaSpike configuration mechanism is to make it obsolete to touch released binaries for changing the configuration of your project. All values which are needed in your code (but should not be hardcoded as static final constants) can be maintained via DeltaSpike's own configuration mechanism in a very flexible and powerful way. === Benefits for Production Once a binary like a WAR file or an EAR got created and tested, it must _not_ get changed anymore. The exact same binary which got created by the release manager will get moved to the Test system, then further propagated to the Staging environment and finally (if all people are happy with it) will get moved to the Production system. And all this without any changes on the binary itself! The Apache DeltaSpike configuration system makes this possible by providing a default configuration inside the binary and allowing to amend this configuration (e.g. database credentials, some URLs from remote REST or SOAP endpoints, etc) from outside like environment settings, JNDI or the current <>. === Drop-In Configuration This mechanism also allows for dynamic configuration in case of a JAR drop-in. By adding some JAR to the classpath, all its contained configuration will get picked up and considered in the property value evaluation. You could also use this mechanism to switch implementations of some SPI (Service Provider Interface) in your own code. === CDI-Extension Configuration In some cases low-level configs are needed, for example during the bootstrapping process of the CDI container. The good news: our DeltaSpike configuration mechanism does not rely on any other EE mechanism to be booted. Which means it can perfectly get used to even configure those parts itself. Since the mechanism does not rely on CDI it can for example be used to configure CDI-Extensions. Currently this is, for example, used to configure the value of the current <>, configured values which can be used in the expressions for `@Exclude`, 'Deactivatable', etc. DeltaSpike needs such a low-level approach for several features internally, but users can utilize it for their own needs as well. This is done by using the `ConfigResolver` which resolves and caches ConfigSources per application. == Accessing configured values using ConfigResolver The `ConfigResolver` is the central point to access configuration in DeltaSpike. There are several different APIs and ways to access the individual configured values, each suitable for a different purpose: * `ConfigResolver` methods for easy programmatic access to values * `TypedResolver` API for typed configuration values and precise control over resolution * `@ConfigProperty` for injection of configured values into beans * interface based configuration All four mechanisms are described in the following sections. === ConfigResolver methods ConfigResolver offers several methods for easy access to String values of configured properties. ==== getPropertyValue() The method `ConfigResolver#getPropertyValue(String key)` returns the value configured for a given key as `String`, or `null` if no value has been found. `ConfigResolver#getAllPropertyValues(String key)` has a similar contract but it returns a list which might be empty if there are no configured values for the given key. This is a code excerpt about how to do a simple lookup in the deltaspike configuration: [source,java] ------------------------------------------------------------------------------- String dbUserName = ConfigResolver.getPropertyValue("databaseconfig.username"); ------------------------------------------------------------------------------- ==== getProjectStageAwarePropertyValue() The method `ConfigResolver#getProjectStageAwarePropertyValue(String key)` utilizes the <> mechanism to allow configured values to depend on the current `ProjectStage` of the running system. This is done by first looking up the ProjectStage (this internally happens with the DeltaSpike ConfigResolver as well) and then go down the following lookup chain until we found a configured value. * key + '.' + projectStage , e.g. "databaseconfig.username.Production" * key alone , e.g. "databaseconfig.username" ==== getPropertyAwarePropertyValue() The method `ConfigResolver#getPropertyAwarePropertyValue(String key, String property)` first looks up the configured value of the given property and uses this value to determine the final lookup path. All those lookups take the <> mechanism into account. [source,java] -------------------------------------------------------------------------------------------------------- String dbUserName = ConfigResolver.getPropertyAwarePropertyValue("databaseconfig.username", "dbvendor"); -------------------------------------------------------------------------------------------------------- ===== Property value resolution sequence The following lookup sequence will be performed until a value is found: First, the value of the _parameter_ property is resolved: * propertyValue = property + '.' + projectStage, e.g. "dbvendor.Production" * if nothing found: propertyValue = property, e.g. "dbvendor" Let's assume we found the value 'mysql' for our dbvendor. In this case the following lookup chain is used until a value got found: * key + '.' + propertyValue + '.' + projectstage, e.g. "databaseconfig.username.mysql.Production" * key + '.' + propertyValue, e.g. "databaseconfig.username.mysql" * key + '.' + projectStage, e.g. "databaseconfig.username.Production" * key, e.g. "databaseconfig.username" ==== Handling of Default Values There is a 2nd variant of all those methods where it is possible to provide a default value which gets returned instead of `null` or if the final result is an empty String. .Performance Hint TIP: The only `ConfigResolver` operation which is cached is the determination of the `ConfigSources`. The various getPropertyValue operations are not cached in the ConfigResolver but might be cached in the ConfigSources. This makes the overall calculation a bit slower, but allows for values to change dynamically if someone likes to for example implement a `JmxConfigSource` (not yet part of DeltaSpike, but easily implementable). You can also use the <> with the `cacheFor(TimeUnit, long)` setting to cache the resolved values on the caller side. === Variable Replacement in Configured Values Since version 1.6.1, DeltaSpike also supports using 'variables' inside configured values. You can e.g. define a single configuration key for your server and use it in other configuration values ----------------------------------------------------------------- document.server.url=http://localhost:8081 myapp.document.lists=${document.server.url}/docapp/list myapp.document.admin=${document.server.url}/docadmin/app ----------------------------------------------------------------- A variable name starts with `${` and ends with `}`. Variable support is enabled by default. If you like to use the `ConfigResolver` without variable support you need to use the methods with the `evaluateVariables` parameter set to `false`. === TypedResolver API Very often the configured values represent more than just strings -- number types and booleans are commonly used as configuration types. ConfigResolver provides a builder-style API to access configuration values as specific types. The API is accessed by a call to `ConfigResolver.resolve(propertyKey)`. The simplest usage of the API is resolution of a String property, equivalent to a call to `ConfigResolver.getPropertyValue(propertyKey)`. .Simple example of TypedResolver [source,java] ----------------------------------------------------------------- String userName = ConfigResolver.resolve("user.name").getValue(); ----------------------------------------------------------------- The call to `ConfigResolver.resolve(..)` returns a builder which has methods to refine the resolution, including the following: * `as(Class clazz)` -- defines the return type of the property * `parameterizedBy(String propertyName)` -- sets a parameter for the resolution, similarly as in <<_getpropertyawarepropertyvalue, ConfigResolver.getPropertyAwarePropertyValue>> * `withCurrentProjectStage(boolean with)` -- indicates whether the current ProjectStage should be taken into account for the resolution * `strictly(boolean strictly)` -- indicates, whether the <<_property_value_resolution_sequence, property value resolution sequence>> should be taken into account. When set to true, the sequence is not followed. * `withDefault(T value)` -- sets the default value, used in case the resolution returns `null` * `getValue()` -- terminates the builder and returns the resolved value with the appropriate type .A more complete example of TypedResolver [source,java] ----------------------------------------------------------------- Integer dbPort = ConfigResolver .resolve("db.port") .as(Integer.class) .withProjectStage(true) .parameterizedBy("db.vendor") .withDefault(3306) .getValue(); ----------------------------------------------------------------- ==== Supported types The types supported out of the box include: String, Integer, Long, Float, Double, Boolean, Class. Custom types can be supported by providing an implementation of the `ConfigResolver.Converter` interface. [source,java] --------------------------------------------------------------------------------------------------------- Date deadline = ConfigResolver.resolve("deadline").as(Date.class, new CustomDateConverter()).getValue()); --------------------------------------------------------------------------------------------------------- [source,java] ------------------------------------------------------------------------------------------ public class CustomDateConverter implements ConfigResolver.Converter { @Override public Date convert(String value) { String[] parts = value.split("-"); return new GregorianCalendar(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]), Integer.valueOf(parts[2])).getTime(); } } ------------------------------------------------------------------------------------------ ==== Dynamic Reloading The TypedResolver can also be used to efficiently cache configured values. That way you can pick up configuration which might get changed during runtime on the fly. E.g. if you have a ConfigSource which picks up the values from a database table. Instead of resolving the configured value at the beginning you simply invoke `.getValue()` on your TypedResolver each time you need the value. .Working with dynamically changing values [source,java] ----------------------------------------------------------------- private ConfigResolver.TypedResolver urlConfig = ConfigResolver.resolve("myapp.some.remote.rest.url") .logChanges(true) .cacheFor(TimeUnit.MINUTES, 5); ... connecTo( urlConfig.getValue() ); ----------------------------------------------------------------- The sample above will log any value changes in the configuration (`logChanges(true)`) and internally cache the configured value for 5 minutes (`cacheFor(TimeUnit.MINUTES, 5)`). Only after that time the configured value will get evaluate again. TIP: Note that the 'cache' is only held within the very TypedResolver instance. If you use different `TypedResolver` instances (e.g. in different classes) then you might get different cache timeouts. ==== List Values handling As of DeltaSpike-1.8.0, the `Typed Resolver` is also able to handle list values. Resolve a list of e.g. retry interval values via: [source,java] ---- List retryIntervals = ConfigResolver.resolve("myapp.retry.intervalls") .as(Integer.class) .asList() .getValue(); ---- The values get configured as comma (`','`) separated value String. A Comma inside a value can be escaped with a backslash (`\,`), backslashes should be escaped with double-backslash (`\\`). Trailing and leading whitespaces get trimmed for each value. === Injection of configured values into beans using @ConfigProperty DeltaSpike provides a way to inject configured values into your code via the qualifier `@ConfigProperty`. The supported types are the same as the <<_supported_types,supported types of the TypedResolver>>. [source,java] ------------------------------------------------------ @ApplicationScoped public class SomeRandomService { @Inject @ConfigProperty(name = "endpoint.poll.interval") private Integer pollInterval; @Inject @ConfigProperty(name = "endpoint.poll.servername") private String pollUrl; ... } ------------------------------------------------------ ==== Custom ConfigProperty types Custom types can be injected using `@ConfigProperty` by providing a custom producer. DeltaSpike provides a base implementation for custom producers in the class `BaseConfigPropertyProducer` which offers the following methods: * `getStringPropertyValue` -- looks for the property name in `@ConfigProperty` annotation on the injection point. If not found, it looks for it in other annotations on the injection point. * `getPropertyValue` -- a shortcut to <<_configresolver, ConfigResolver#getProjectStageAwarePropertyValue>> * `getAnnotation` -- extracts any annotation type from the injection point, useful when a custom annotation is used instead of `@ConfigProperty` The following example uses `getStringPropertyValue` and a custom `@Location` annotation annotated `@ConfigProperty`. In such case, the `@Location` annotation is bound to a single fixed property name and acts as a type-safe replacement for `@ConfigProperty(name = "locationId")`. [source,java] -------------------------------------------------------------------- @ApplicationScoped public class CustomConfigPropertyProducer extends BaseConfigPropertyProducer { @Produces @Dependent @Location public LocationId produceLocationId(InjectionPoint injectionPoint) { String configuredValue = getStringPropertyValue(injectionPoint); return LocationId.valueOf(configuredValue.trim().toUpperCase()); } } -------------------------------------------------------------------- [source,java] ----------------------------------------------------------------- @Target({ FIELD, METHOD }) @Retention(RUNTIME) @ConfigProperty(name = "locationId", defaultValue = "LOCATION_X") @Qualifier public @interface Location {} ----------------------------------------------------------------- The `@ConfigProperty` annotation doesn't need to be used at all. Instead, a custom annotation can be provided and obtained in the producer using `getAnnotation` and `getPropertyValue`: [source,java] ------------------------------------------------------------------------------------------------------ @ApplicationScoped public class NumberConfigPropertyProducer extends BaseConfigPropertyProducer { @Produces @Dependent @NumberConfig(name = "unused") public Float produceNumberProperty(InjectionPoint injectionPoint) throws ParseException { // resolve the annotation NumberConfig metaData = getAnnotation(injectionPoint, NumberConfig.class); // get the configured value from the underlying configuration system String configuredValue = getPropertyValue(metaData.name(), metaData.defaultValue()); // format according to the given pattern DecimalFormat df = new DecimalFormat(metaData.pattern(), new DecimalFormatSymbols(Locale.US)); return df.parse(configuredValue).floatValue(); } } ------------------------------------------------------------------------------------------------------ [source,java] ------------------------------------------------------------------- @Qualifier public @interface NumberConfig { @Nonbinding String name(); @Nonbinding String defaultValue() default ConfigProperty.NULL; @Nonbinding String pattern() default "#0.00"; } ------------------------------------------------------------------- == Interface based configuration The interfaces decorated with `@Configuration` are converted during CDI startup to Beans matching the interface type. Concretely this interface: [source] ---- @Configuration public interface MyConfig { } ---- Will use accessible using: [source] ---- @Inject private MyConfig config; ---- To define a configuration entry in this mode you define an interface method and decorate it with `@ConfigProperty` exactly as a normal injection: [source] ---- @Configuration public interface MyConfig { @ConfigProperty(name = "my.config") String url(); } ---- TIP: this mode also supports primitives like `int`, `boolean`, ... as returned types. The methods are no parameter and not returning void methods. If all your keys use the same prefix you can configure it on `@Configuration`: [source] ---- @Configuration(prefix = "client.") public interface MyConfig { @ConfigProperty(name = "url") String url(); @ConfigProperty(name = "timeout", defaultValue = "30000") long timeout(); } ---- Finally, you can also access the caching feature of the `TypedResolver` through `@Configuration`: [source] ---- @Configuration(cacheFor = 30, cacheUnit = TimeUnit.SECONDS) public interface MyConfig { @ConfigProperty(name = "url") String url(); @ConfigProperty(name = "timeout", defaultValue = "30000") long timeout(); } ---- == Providing configuration using ConfigSources A `ConfigSource` is exactly what its name says: a source for configured values. The `ConfigResolver` uses all configured implementations of `ConfigSource` to lookup the property in question. Each 'ConfigSource' has a specified 'ordinal' which can be configured using the key `deltaspike_ordinal`. This ordinal get's used to determine the importance of the values taken from the very ConfigSource. A higher ordinal means that the values taken from this ConfigSource will override values from less important ConfigSources. This is the trick which allows to amend configuration from outside a binary - given those outside ConfigSources have a higher `deltaspike_ordinal` than the ones who pickup the values from within the release binaries. === ConfigSources Provided by Default By default there are implementations for the following configuration sources (listed in the lookup order): * System properties (deltaspike_ordinal = 400) * Environment properties (deltaspike_ordinal = 300) * JNDI values (deltaspike_ordinal = 200, the base name is "java:comp/env/deltaspike/") * All apache-deltaspike.properties files on the classpath (deltaspike_ordinal = 100, default filename is "META-INF/apache-deltaspike.properties") * A property file in user.home `~/.deltaspike/apache-deltaspike.properties` (if exists, deltaspike_ordinal = 100) *It is possible to change this order and to add custom configuration sources.* .Important Tips Especially for Custom Implementations TIP: - The config-source with the highest ordinal gets used first. - If a custom implementation should be invoked _before_ the default implementations, use an ordinal-value > 400. - If a custom implementation should be invoked _after_ the default implementations, use an ordinal-value < 100. - The `ConfigResolver` performs no caching. If your custom ConfigSource operation is expensive, then you might think about introducing some caching. === Reordering of the Default Order of ConfigSources To change the lookup order, you have to configure the ordinal in the corresponding configuration source (e.g. to change the configuration ordinal of the configuration source for system properties, you have to set the system property with the ordinal key 'deltaspike_ordinal' and the new value). Example with `/META-INF/apache-deltaspike.properties`: If the properties file/s should be used *before* the other implementations, you have to configure an ordinal > 400. That means, you have to add for example `deltaspike_ordinal=401`. Each single property file is treated as own `ConfigSource` and thus can have different `deltaspike_ordinal` values! NOTE: In case of *property files* which are supported by default (`/META-INF/apache-deltaspike.properties`) every file is handled as independent config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner). === Custom ConfigSources ConfigSources are picked up using the `java.util.ServiceLoader' mechanism. To add a custom config-source, you have to implement the interface `ConfigSource` and register your implementation in a file `/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource` by writing the fully qualified class name of the custom implementation/s into it. If you need dynamic ConfigSources you can also register a `ConfigSourceProvider` in a similar way. This is useful if you like to dynamically pick up multiple ConfigSources of the same kind. For example, if you like to pick up all `myproject.properties` files from all the JARs in your classpath. Please note that a single `ConfigSource` should be either registered directly or via a `ConfigSourceProvider`, but never both ways. TIP: Have a look at the abstract base-implementation of `ConfigSource` DeltaSpike is using internally, if a custom implementation should load the ordinal value from the config-source like the default implementations provided by DeltaSpike do. Since 1.8.0 you can also decorate a CDI `ConfigSource` with `@Source` and it will be added to DeltaSpike configuration *once the CDI container is started* (it means you can't use this source in an `Extension`). ==== PropertyFileConfig For registering all your own property files of a certain name in your classpath to get picked up as ConfigSources you can also provide a class which implements the `PropertyFileConfig` interface. If `getPropertyFileName()` returns an URL, e.g. `file:///var/opt/myapp/my.properties"` then this will be used to pick up the configured values. In other words: with using `file://` you can specify a file on the file system. The method `isOptional` indicates whether your custom property file is mandatory. If a mandatory property file is not found during deployment, DeltaSpike throws an `IllegalStateException` and stops the deployment. [source,java] --------------------------------------------------------------------- public class MyCustomPropertyFileConfig implements PropertyFileConfig { @Override public String getPropertyFileName() { return "myconfig.properties"; } @Override public boolean isOptional() { return false; } } --------------------------------------------------------------------- _Note: If you are using WildFly with EAR packaging and with ear-subdeployments-isolated=true, then your EAR should have a deployment dependency to the module that contains the property file._ [source,xml] --------------------------------------------------------------------------------------------------- true --------------------------------------------------------------------------------------------------- == Filtering configured values It is possible to perform filtering on all configured values on their way between the ConfigSource and user code. This might be useful for example for decryption of values from an encrypted ConfigSource or to hide passwords from a log. DeltaSpike doesn't provide any filters by default but custom filters can be provided by implementing the `ConfigFilter` interface. This is then enabled either using the ServiceLoader mechanism or by calling `ConfigResolver.addConfigFilter(ConfigFilter)`. Provided ConfigFilters are then enabled for the whole application. Once some filters are provided, all operations of ConfigResolver return filtered values. .A custom ConfigFilter [source,java] ------------------------------------------------------------- public class DecryptingConfigFilter implements ConfigFilter { private DefaultCipherService ciperSvc = new DefaultCipherService(); private String masterSalt = "someApplicationMasterSalt"; @Override public String filterValue(String key, String value) { if (key.contains("password")) { try { return cipherSvc.decrypt(value, masterSalt); } catch (Exception e) { return value; } } return value; } @Override public String filterValueForLog(String key, String value) { if (key.contains("password")) { return "***************"; } return value; } } ------------------------------------------------------------- For more information about the `CipherService` please see the <> section. Since 1.8.0 you can also decorate a CDI `ConfigFilter` with `@Filter` and it will be added to DeltaSpike configuration *once the CDI container is started* (Note that this means you can't use this ConfigFilter in a CDI `Extension`). ================================================ FILE: documentation/src/main/asciidoc/configure.adoc ================================================ = Configure DeltaSpike in Your Projects :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike is available for use in projects of many build tools. Instructions are given here for obtaining released final versions of DeltaSpike for both approaches. NOTE: You can also opt to use the lastest DeltaSpike snapshots; for more information, see <>. == Maven Projects DeltaSpike released versions are available from the Maven Central repository for use in Maven-based projects. This means that you do not need to modify your Maven configuration `settings.xml` file; when building projects, Maven automatically searches the online Maven Central repository for project dependencies and downloads sources to your local Maven repository. To begin use the DeltaSpike releases from Maven Central, you simply need to configure the project `pom.xml` file for each project with information about the release version and modules you want to use. At a minimum, you must add the DeltaSpike Core module, which provides the DeltaSpike API and utility classes. . Open the project `pom.xml` file for editing . Add the DeltaSpike version to the list of properties + [source,xml,subs="+attributes"] ---- {latestStable} ---- + . Add the DeltaSpike Core module to the list of dependencies + [source,xml] ---- org.apache.deltaspike.distribution distributions-bom ${deltaspike.version} pom import org.apache.deltaspike.core deltaspike-core-api compile org.apache.deltaspike.core deltaspike-core-impl runtime ---- + . Save the `pom.xml` file changes TIP: The API is scoped for compile time and implementation only included for runtime, assisting to prevent you from inadvertently depending on an implementation class. For instructions on adding the optional DeltaSpike modules, see the relevant module page: * <> * <> * <> * <> * <> * <> * <> * <> * <> * <> [[config-gradle]] == Gradle Projects Setting up DeltaSpike in a Gradle based project is just as easy as Maven. [source,subs="+attributes"] ---- // setup the Spring Dependency Management Plugin for Gradle, to import BOMs. plugins { id "io.spring.dependency-management" version "0.5.6.RELEASE" id "java" // you'll likely also want the WAR plugin } repositories { mavenCentral() } dependencyManagement { imports { mavenBom 'org.apache.deltaspike.distribution:distributions-bom:{latestStable}' } } dependencies { compile 'org.apache.deltaspike.core:deltaspike-core-api' runtime 'org.apache.deltaspike.core:deltaspike-core-impl' } sourceSets { main { //To use standard bean discovery mechanisms, CDI expects beans.xml to be in your classes directory output.resourcesDir = output.classesDir } test { output.resourcesDir = output.classesDir } // and any other sourceSet you might have. } ---- This will give you a Gradle build setup to run DeltaSpike. [[config-maven-indep]] == Other Projects DeltaSpike is provided as a set of downloadable .jar files for projects not utilizing the Maven build system. Alternatively, you can build the DeltaSpike .jar files from source; for instructions, see <>. In both cases, you must add the DeltaSpike .jar files directly to your projects. To use DeltaSpike without Maven from the downloadable .jar files, complete the following steps: . Download the latest `distribution-full-.zip` from https://deltaspike.apache.org/download.html . Extract the archive contents + [source,shell] ---- $ unzip distribution-full-.zip ---- + . Add the source to your project a. For .war projects, copy the .jar files to the `WEB-INF/lib` directory b. For .ear projects, copy the .jar files to the `EAR/lib directory` and add the following to `META-INF/application.xml`: + [source,xml] ---- lib ---- == Next * To check whether your Java environment needs any additional CDI-specific configuration, see <>. * To see ready-to-deploy example DeltaSpike applications, see link:http://deltaspike.apache.org/examples.html[See DeltaSpike in Action]. * To understand how the various DeltaSpike modules can enhance and extend your applications, see <> and the individual module pages. ================================================ FILE: documentation/src/main/asciidoc/container-control.adoc ================================================ = Container Control Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Container Control module provides CDI container booting and shutdown, crucial for CDI use in Java SE6+ environments, and associated context lifecycle management. The module abstracts individual CDI container implementations, ensuring projects are container-independent. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === Enable CDI For Your Java Environment This module requires a CDI implementation to be available in the Java environment where your projects are deployed. Dependent on the Java environment you choose, some setup may be necessary as detailed at the <> page. === Declare Container Control Module Dependencies Add the Container Control module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${deltaspike.version} compile ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- compile 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api' ---- == Start the CDI Container from Your Project To start a CDI container in your application, you must instantiate a `CdiContainer` object and call the `#boot` method. When `#boot` is called, the `CdiContainer` scans CDI-enabled archives for beans and CDI extensions. Before the application exits, `#shutdown` must be called to correctly destroy all beans. An example is given in the code snippet here. [source,java] ---- import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; public class MainApp { public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); // You can use CDI here cdiContainer.shutdown(); } } ---- Starting the container does not automatically start all CDI Contexts. Contexts must be started independently using the provided `ContextControl` class. An example of starting the Context for `@ApplicationScoped` beans is added to the code snippet here. [source,java] ---- import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import jakarta.enterprise.context.ApplicationScoped; public class MainApp { public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); // Starting the application-context enables use of @ApplicationScoped beans ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); // You can use CDI here cdiContainer.shutdown(); } } ---- To resolve project beans, you can use the DeltaSpike `BeanProvider` class. Whether `EchoService` is a concrete implementation or just an interface depends on the application. In the case that it is an interface, the corresponding implementation is resolved. The resolved bean is a standard CDI bean and it can be used for all CDI concepts, such as `@Inject`, in the class without further uses of `BeanProvider`. An example of resolving the bean without qualifiers is given in the code snippet here. [source,java] ---- EchoService echoService = BeanProvider.getContextualReference(EchoService.class, false); ---- == CdiContainer The `CdiContainer` interface provides booting and shutdown of the CDI containers from deployed applications, with `CdiContainerLoader` a simple factory providing access to the underlying `CdiContainer` implementation. This is useful to Java SE6+ applications in which a standalone CDI implementation must be provided and booted and shutdown by the application. Booting and shutdown of the CDI container for Java EE and servlet containers is managed by the servlet container integration. For instructions and examples on using this feature in your projects, see <>. == ContextControl Usage The `ContextControl` interface provides life-cycle control of the CDI container built-in contexts. This includes starting and stoping built-in standard contexts like `@RequestScoped`, `@ConversationScoped`, and `@SessionScoped`. It is provided as an `@Dependent` bean and can be injected in the classic CDI way. This feature can be used and is helpful in all Java environments, including Java SE, as illustrated here. == Procedure for building an uber jar Uber jar or executable jar can created by using the maven shade plugin. Some things you needs to be aware of when you use it. * Multiple `beans.xml` and `jakarta.enterprise.inject.spi.Extension` files needs to be merged into the final jar using a transformer. [source,xml] ---- ---- * The _asm:asm:3.3.1_ transitive dependency of OpenWebBeans isn't properly included in the Uber jar. Add it as a project dependency if you use OWB. (Only needed for OWB 1.1.8 !) * Some frameworks, like logging frameworks, aren't CDI compatible. So you need to exclude them from scanning. Use for example the `scan` feature of Weld to define which packages needs to be excluded. === Restart the RequestContext in Unit Tests In unit testing it can be necessary to test with attached and also with detached JPA entities. A very common approach for JPA is the http://docs.redhat.com/docs/en-US/JBoss_Enterprise_Web_Server/1.0/html/Hibernate_Entity_Manager_Reference_Guide/transactions.html[entitymanager-per-request approach] and thus have a producer method which creates a @RequestScoped EntityManager. Since a single unit test is usually treated as one ‘request’ a problem arises detaching entities. .Using ContextControl to Detach Entities [source,java] --------------------------------------------------------------------------------------- @Test public void testMyBusinessLogic() { doSomeJpaStuff() MyEntity me = em.find(...); ContextControl ctxCtrl = BeanProvider.getContextualReference(ContextControl.class); //stop the RequestContext to dispose of the @RequestScoped EntityManager ctxCtrl.stopContext(RequestScoped.class); //immediately restart the context again ctxCtrl.startContext(RequestScoped.class); //the entity 'em' is now in a detached state! doSomeStuffWithTheDetachedEntity(em); } --------------------------------------------------------------------------------------- === Attach a RequestContext to a New Thread in EE Accessing the `@RequestScoped` bean in a new thread will result in a `ContextNotActiveException`. The RequestContext usually gets started for a particular thread via a simple `ServletRequestListener`. So "no servlet-request" means that there is no Servlet-Context for the current (/new) Thread. You might face such issues, if you would like to reuse business services in for example a Quartz Job. .Using ContextControl to Control the RequestContext for a Quartz-Job [source,java] --------------------------------------------------------------------------------------------- public class CdiJob implements org.quartz.Job { public void execute(JobExecutionContext context) throws JobExecutionException { ContextControl ctxCtrl = BeanProvider.getContextualReference(ContextControl.class); //this will implicitly bind a new RequestContext to the current thread ctxCtrl.startContext(RequestScoped.class); try { doYourWork(); } finally { //stop the RequestContext to ensure that all request-scoped beans get cleaned up. ctxCtrl.stopContext(RequestScoped.class); } } } --------------------------------------------------------------------------------------------- == Embedded Servlet Support From DeltaSpike 1.0.2, you can use DeltaSpike to power embedded Servlet runtimes. This work is done via Servlet Listeners. The configuration is specific to each container, below are some examples. The two main listeners are `CdiServletRequestListener` and `CdiServletContextListener`. `CdiServletRequestListener` is responsible for starting a `RequestContext` on each incoming request. In most containers this is all you need. For Tomcat specifically, you need to use `CdiServletContextListener` which registers the `CdiServletRequestListener`. The main use case for this feature is for lightweight embedded runtimes, microservices. For each of these, it is assumed that you are using the following start up code somewhere: [source,java] ----------------------------------------------------------------- CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); cdiContainer.getContextControl().startContexts(); ----------------------------------------------------------------- === Jetty For Jetty, you need to add an `EventListener` which will be your `CdiServletRequestListener`. The object must be instantiated. This must be done before the server is started. [source,java] ------------------------------------------------------------------------------------------ Server server = new Server(port); ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); server.setHandler(context); context.addEventListener(new CdiServletRequestListener()); context.addServlet(new ServletHolder(new YourServlet()),"/*"); server.start(); ------------------------------------------------------------------------------------------ === Undertow For Undertow, you register the `CdiServletRequestListener` via `ListenerInfo` by passing in the class to their builders. Then you add the `ListenerInfo` to your deployment before starting. [source,java] -------------------------------------------------------------------------------------------------------- ServletInfo servletInfo = Servlets.servlet("YourServletName", YourServlet.class).setAsyncSupported(true) .setLoadOnStartup(1).addMapping("/*"); ListenerInfo listenerInfo = Servlets.listener(CdiServletRequestListener.class); DeploymentInfo di = new DeploymentInfo() .addListener(listenerInfo) .setContextPath("/") .addServlet(servletInfo).setDeploymentName("CdiSEServlet") .setClassLoader(ClassLoader.getSystemClassLoader()); DeploymentManager deploymentManager = Servlets.defaultContainer().addDeployment(di); deploymentManager.deploy(); Undertow server = Undertow.builder() .addHttpListener(port, "localhost") .setHandler(deploymentManager.start()) .build(); server.start(); -------------------------------------------------------------------------------------------------------- === Tomcat For Tomcat, you need to register the `CdiServletContextListener` instead of the `CdiServletRequestListener`. It is added as an `ApplicationListener` by passing in the class name as a `String`. [source,java] ----------------------------------------------------------------------------------- Tomcat tomcat = new Tomcat(); tomcat.setPort(port); File base = new File("..."); Context ctx = tomcat.addContext("/",base.getAbsolutePath()); StandardContext standardContext = (StandardContext)ctx; standardContext.addApplicationListener(CdiServletContextListener.class.getName()); Wrapper wrapper = Tomcat.addServlet(ctx,"YourServlet",YourServlet.class.getName()); wrapper.addMapping("/*"); tomcat.start(); ----------------------------------------------------------------------------------- ================================================ FILE: documentation/src/main/asciidoc/core.adoc ================================================ :modulebase: core :moduleconf: api:org.apache.deltaspike.core.api.config.base.CoreBaseConfig = Core Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. The Core module provides fundamental and defining DeltaSpike API and utility classes. As such, this module must be included in every project that uses DeltaSpike. Instructions for configuring your projects to use the DeltaSpike Core module are detailed in <> as part of the general instructions for configuring your projects for DeltaSpike. == Project Setup Add Core-API and Core-Impl to your project as detailed in <>. For Maven-independent projects, see <>. == DeltaSpike Configuration DeltaSpike provides a very flexible application configuration mechanism. Its main goal is to make it possible to never have to rebuild a project just for the sake of adjusting configuration values. It respects the usual software development cycle and takes into account project stages, various configuration sources and resolution mechanisms. Configuration can be overridden just by dropping a JAR into the classpath. Detailed documentation is available on a separate page: <>. == DeltaSpike CipherService Apache DeltaSpike also provides an <> mechanism for handling secret values within your application. === Internal configuration The functionality of DeltaSpike itself and its modules is adjustable using the same mechanism. There are two main types of internal configuration: * *static configuration:* certain configurable options, like the maximum number of windows in the window scope or the priority for DeltaSpike's global interceptors, are defined using the DeltaSpike configuration mechanism and can be adjusted by redefining their value in the `apache-deltaspike.properties` file, as described in the <>. All of these configuration options and their corresponding properties can be found as members of interfaces extending `DeltaSpikeBaseConfig`, e.g. `CoreBaseConfig` which configures the core module. * *dynamic configuration:* certain values can change dynamically during runtime and some may differ even among contexts. For example, much of the behaviour of the JSF module is configured in `JsfModuleConfig`. To override any of the default configuration options, the `JsfModuleConfig` bean can be overridden using a custom implementation of `JsfModuleConfig` which would be annotated `@Alternative` or `@Specializes`. All of the dynamic CDI-based configuration beans can be found as implementations of the `DeltaSpikeConfig` interface. == BeanProvider The `BeanProvider` utility class provides static methods for manual lookup of bean instances in places where standard injection is not available or if the lookup depends on dynamic conditions. WARNING: `BeanProvider` is only used to look up normal-scoped contextual instances. To obtain instances of dependent-scoped beans, use <<_dependentprovider, DependentProvider>>. NOTE: The term 'contextual instance' is used instead of 'bean' because that's the term used by CDI itself. The following example shows a simple lookup. With the second parameter it is possible to specify if the contextual instance is optional. If it is not expected that the contextual instance is optional, but no instance has been found, an `IllegalStateException` will be thrown. .Resolving a Simple Contextual Instance [source,java] ------------------------------------------------------------------------- MyBean myBean = BeanProvider.getContextualReference(MyBean.class, false); ------------------------------------------------------------------------- Pass `true` as second argument, if you look for an implementation of the given interface and an implementation is not required or it is not required that there is an instance with the given qualifier (see the qualifier example for further details). .Resolving an Optional Contextual Instance [source,java] --------------------------------------------------------------------------------------------------------- MyServiceInterface optionalService = BeanProvider.getContextualReference(MyServiceInterface.class, true); --------------------------------------------------------------------------------------------------------- Optionally you can provide a qualifier for the contextual instance in question. CDI qualifiers are annotations, therefore you need to implement a corresponding literal for providing an instance. .Literal Implementation for '@MyQualifier' [source,java] --------------------------------------------------------------------------------------------- import jakarta.enterprise.util.AnnotationLiteral; //... public class MyQualifierLiteral extends AnnotationLiteral implements MyQualifier { } --------------------------------------------------------------------------------------------- The following example will return a contextual instance with the qualifier `@MyQualifier`. .Resolving a Simple Contextual Instance with Qualifier [source,java] --------------------------------------------------------------------------------------------------- MyBean myBean = BeanProvider.getContextualReference(MyBean.class, false, new MyQualifierLiteral()); --------------------------------------------------------------------------------------------------- The `@Named` qualifier has a special role and allows to specify a string based name (e.g. for referencing CDI beans in EL-expressions). However, the following examples show how to do a manual lookup by name. .Resolving a Simple Contextual Instance by Name [source,java] --------------------------------------------------------------------- Object myBean = BeanProvider.getContextualReference("myBean", false); --------------------------------------------------------------------- .Resolving a Simple Contextual Instance by Name and Expected Type [source,java] ----------------------------------------------------------------------------------- MyBean myBean = BeanProvider.getContextualReference("myBean", false, MyBean.class); ----------------------------------------------------------------------------------- Sometimes it is essential to resolve all contextual instances which implement for example an interface or all beans with the same type but a different qualifier. The following example shows how to do such a lookup which returns all contextual instances (independent of the scope -> also dependent scoped instances). .Resolving All Contextual Instances of a Given Type [source,java] --------------------------------------------------------------------------------------------------------------- List myServiceList = BeanProvider.getContextualReferences(MyServiceInterface.class, false); --------------------------------------------------------------------------------------------------------------- Since dependent scoped beans have a special role in CDI (you have to destroy them manually - especially if you get them via a manual lookup), you can also call the previous util method with an additional parameter to filter dependent scoped instances. .Resolving All Contextual Instances of a Given Type without Dependent-scoped Instances [source,java] ---------------------------------------------------------------------------------------------------------------------- List myServiceList = BeanProvider.getContextualReferences(MyServiceInterface.class, false, false); ---------------------------------------------------------------------------------------------------------------------- Furthermore, it is possible to trigger the injection of fields of any given instance, if it was not done by the container (e.g. because the class is in a jar-file without beans.xml) and `@Inject` is used for 1-n fields. .Manually Inject Fields [source,java] ------------------------------------ BeanProvider.injectFields(myObject); ------------------------------------ === DependentProvider `DependentProvider` must be used instead of `BeanProvider` to obtain instances of dependent-scoped beans to allow for their proper destruction. When obtaining contextual instances using `@Inject`, the normal-scoped ones get destroyed along with their associated context. However, instances of dependent-scoped beans -- as implied by their name -- depend on the lifecycle of the contextual instance which declares them and get destroyed along with this declaring bean's instance. However, if dependent-scoped instances are obtained programmatically using `DependentProvider`, there's no "declaring bean" to speak of and they *must be destroyed manually*. .Obtaining and destroying an instance of a dependent-scoped bean using DependentProvider [source,java] ----------------------------------------------------------------------------------- DependentProvider myBeanProvider = BeanProvider.getDependent(MyBean.class); MyBean myBean = myBeanProvider.get(); // ...work with myBean... myBeanProvider.destroy(); ----------------------------------------------------------------------------------- == BeanManagerProvider This mechanism provides access to the `BeanManager` by registering the current `BeanManager` during the startup. This is really handy if you like to access CDI functionality from places where no CDI based injection is available. If a simple but manual bean-lookup is needed, it is easier to use the `BeanProvider`. .Resolving the BeanManager [source,java] ----------------------------------------------------------------------------- //in most cases the following works without problems: @Inject private BeanManager beanManager; //use BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); //if CDI based injection is not available. ----------------------------------------------------------------------------- `BeanManagerProvider` uses a different approach to find the correct `BeanManager`, because a portable API for it has only been available from CDI 1.1. However, once you are using CDI 1.1+ DeltaSpike delegates the lookup to the CDI container instead of using its own approach. If you migrate from CDI 1.0 to a later version of CDI and you would like to keep the lookup strategy you used before, you can deactivate the delegation to the container by adding `deltaspike.bean-manager.delegate_lookup=false` to your config-source (e.g. in `/META-INF/apache-deltaspike.properties`). == AnnotationInstanceProvider Java EE provides a standard mechanism for obtaining annotation instances -- the `AnnotationLiteral` class. [source,java] ------------------------------------------------------------------------------------------------ public class CurrentUserLiteral extends AnnotationLiteral implements CurrentUser {} ------------------------------------------------------------------------------------------------ [source,java] ----------------------------------------------- CurrentUser user = new CurrentUserLiteral() {}; ----------------------------------------------- `AnnotationLiteral` can however be used only if the annotation class name is known beforehand. `AnnotationInstanceProvider` is the solution for dynamic creation of annotation instances, with the option to provide a map of values for annotation members. That might be useful in many situations, especially for CDI extension authors. For example: * avoiding a compile-time dependency on an annotation class + [source,java] -------------------------------------------------------------------------------------------------------------------- Class priorityAnnotationClass = ClassUtils.tryToLoadClassForName("javax.annotation.Priority"); priorityAnnotationInstance = AnnotationInstanceProvider.of(priorityAnnotationClass, mapOfMemberValues); -------------------------------------------------------------------------------------------------------------------- * getting an instance of a dynamically obtained annotation class + [source,java] ------------------------------------------------------------------------------------------------------- Annotation exceptionQualifier = AnnotationInstanceProvider.of(jsfModuleConfig.getExceptionQualifier()); ------------------------------------------------------------------------------------------------------- * or simply for the sake of a prettier syntax compared to `AnnotationLiteral` + [source,java] ------------------------------------------------------------------------- CurrentUser principal = AnnotationInstanceProvider.of(CurrentUser.class); ------------------------------------------------------------------------- == Type-safe ProjectStage The DeltaSpike <> mechanism allows to use configuration and implementations depending on the server environment you currently run on. DeltaSpike provides some pre-defined <> but it's also possible to create your own <>, Please, check the <> page for more details. == @Exclude With `@Exclude` it is possible to annotate beans which should be ignored by CDI even if they are in a CDI enabled archive. .Excluding a Bean in any Case [source,java] ------------------- @Exclude public class NoBean { } ------------------- .Excluding a Bean in Case of ProjectStageDevelopment [source,java] --------------------------------------------------------- @Exclude(ifProjectStage = ProjectStage.Development.class) public class MyBean { } --------------------------------------------------------- .Excluding a Bean if the ProjectStage is different from Development [source,java] --------------------------------------------------------------- @Exclude(exceptIfProjectStage = ProjectStage.Development.class) public class MyDevBean { } --------------------------------------------------------------- The following usage allows to exclude a bean based on a configured value (see the <>). .Excluding a Bean based on an Expression which Evaluates to True [source,java] ------------------------------------- @Exclude(onExpression = "db==prodDB") public class DevDbBean { } ------------------------------------- By default a simple syntax is supported ([TODO]), however, it is possible to provide a custom `ExpressionInterpreter` for interpreting custom expressions. .Excluding a Bean based on a Custom Expression [source,java] ------------------------------------------------------------------------------------------ @Exclude(onExpression = "db eq prodDB", interpretedBy = SimpleExpressionInterpreter.class) public class DevDbBean { } public class SimpleExpressionInterpreter implements ExpressionInterpreter { @Override public Boolean evaluate(String expression) { if(expression.contains(" eq ")) { //... } //... } } ------------------------------------------------------------------------------------------ In several cases it is also useful to combine this feature with the `@Alternative` annotation provided by CDI. In addition to the following snippet, it is required to configure the implementation as alternative in the beans.xml file. This configuration entry will not be changed, for example for different environments, because it just gets active if it is not excluded during the bootstrapping process. .Excluding an Alternative implementation if the ProjectStage is different from Development [source,java] --------------------------------------------------------------- @Exclude(exceptIfProjectStage = ProjectStage.Development.class) @Alternative public class MyDevBean { } --------------------------------------------------------------- === Custom ExpressionInterpreter By default only a very simple and limited syntax is supported. In real projects there are usually quite concrete requirements. Since it would be very complex to support most of them, it is easier for users to implement an optimized syntax. For such cases a custom ExpressionInterpreter is needed: [source,java] ---------------------------------------------------------------------------------------------------- @Alternative @Exclude(onExpression = "environment!=HSQL", interpretedBy = ConfigAwareExpressionInterpreter.class) public class DevDbBean implements DbBean { } public class ConfigAwareExpressionInterpreter implements ExpressionInterpreter { public Boolean evaluate(String expression) { if (expression == null) { return false; } String[] values = expression.split("!="); if (values.length != 2) { throw new IllegalArgumentException("'" + expression + "' is not a supported syntax"); } String configuredValue = ConfigResolver.getPropertyValue(values[0], null); //exclude if null or the configured value is different return configuredValue == null || !values[1].trim().equalsIgnoreCase(configuredValue); } } ---------------------------------------------------------------------------------------------------- == Type-safe View-Config TODO (Overview) == Literals Literals allow the instantiation of annotations by extending the abstract class `jakarta.enterprise.util.AnnotationLiteral` .Example [source,java] ---------------------------------------------------------------------------------------------- public abstract class PayByQualifier extends AnnotationLiteral implements PayBy {} PayBy paybyCheque = new PayByQualifier() { public PaymentMethod value() { return CHEQUE; } }; ---------------------------------------------------------------------------------------------- DeltaSpike provides many annotation literals that you can use, including the following: * AlternativeLiteral * AnyLiteral * ApplicationScopedLiteral * ConversationScopedLiteral * DefaultLiteral * DependentScopeLiteral * ModelLiteral * NamedLiteral * NewLiteral * RequestedScopeLiteral * SessionScopeLiteral * Singleton * SpecializesLiteral * TypedLiteral == Messages and i18n The following implementation is the minimal effort to use type-safe messages (which are hardcoded in this case). .Simple Type-safe Message [source,java] --------------------------------------------- @MessageBundle public interface SimpleMessage { @MessageTemplate("Welcome to DeltaSpike") String welcomeToDeltaSpike(); } --------------------------------------------- The following implementation uses the key `welcome_to_deltaspike` to do a lookup in the default message bundle. The default bundle has the same name as the interface (but .properties instead of .java (/.class) as file extension). .Internationalized Type-safe Message [source,java] ----------------------------------------------------------------- @MessageBundle public interface SimpleMessage { @MessageTemplate("{welcome_to_deltaspike}") String welcomeToDeltaSpike(); } org.apache.deltaspike.example.message.SimpleMessage -> org/apache/deltaspike/example/message/SimpleMessage.properties org/apache/deltaspike/example/message/SimpleMessage_en.properties org/apache/deltaspike/example/message/SimpleMessage_de.properties ... //content (as usual in message bundle files): welcome_to_deltaspike=Welcome to DeltaSpike ----------------------------------------------------------------- The following implementation uses the key `welcome_to_deltaspike` to do a lookup in a custom message bundle known by `CustomMessageResolver`. .Internationalized Type-safe Message [source,java] -------------------------------------------------------------------- @MessageBundle @MessageContextConfig(messageResolver = CustomMessageResolver.class) public interface SimpleMessage { @MessageTemplate("{welcome_to_deltaspike}") String welcomeToDeltaSpike(); } -------------------------------------------------------------------- `@MessageContextConfig` allows to provide a custom `MessageResolver`, `MessageInterpolator` and `LocaleResolver`. The following implementation shows the usage of an internationalized simple type-safe message. .Internationalized Type-safe Message with Parameter/s [source,java] ---------------------------------------------------------------------------- @MessageBundle @MessageContextConfig(messageInterpolator = CustomMessageInterpolator.class) public interface SimpleMessage { //in the message bundle: welcome_to=Welcome to %s @MessageTemplate("{welcome_to}") String welcomeTo(String name); } //... public class MyBean { @Inject private SimpleMessage messages; public String welcomeToDeltaSpike { return this.messages.welcomeTo("DeltaSpike"); } } ---------------------------------------------------------------------------- === Dynamic Message Builder ==== Creating Message Instances The following implementation creates an instance of `Message` for the key `hello`. The final text will be resolved and interpolated lazily. Later on it might be supported to provide a different `MessageContext` via `#toString(MessageContext)` like it is in MyFaces CODI right now. You can use `#argument(String)` to pass these arguments to the message template specified on `#template(String)` method. The template pattern uses printf-style format strings. [source,java] --------------------------------------------------------------------------------------------- public class MyBean { @Inject private MessageContext messageContext; public void action() { Message message = this.messageContext.message(); write(message.template("Hello %s from %s").argument("World").argument("DeltaSpike")); } //... } --------------------------------------------------------------------------------------------- Besides the static configuration via `@MessageContextConfig#messageSource`, you can also specify the message sources dynamically. [source,java] -------------------------------------------------------------------------------------------------------------------- @Inject private MessageContext messageContext; public void action() { Message message = this.messageContext.messageSource("org.apache.deltaspike.example.message.Messages").message(); write(message.template("{hello}").argument("World").argument("DeltaSpike")); } //... -> org/apache/deltaspike/example/message/Messages.properties org/apache/deltaspike/example/message/Messages_en.properties org/apache/deltaspike/example/message/Messages_de.properties ... //content (as usual) in message bundle files: hello=Hello %s from %s -------------------------------------------------------------------------------------------------------------------- ==== Customizing the Message Context ===== MessageResolver A message-resolver is responsible for creating the message-text based on the message-descriptor (key or inline-text), the current locale (and in some cases the message-payload). (The supported format, for example, if it is required to escape a key, if inline-text is supported,... depends on the concrete implementation.) In case of a message-key, the message-resolver has to transform it to the message-text by looking it up in a message source like a resource-bundle. *Configuration of a message-resolver* Besides the static configuration via `@MessageContextConfig#messageResolver`, you can use it dynamically via passing a custom message-resolver instance to the current messageContext: [source,java] --------------------------------------------------------------------------------------------- @Inject private MessageContext messageContext; //... Message message = this.messageContext.messageResolver(new CustomMessageResolver()).message(); --------------------------------------------------------------------------------------------- The result of a `MessageResolver` is the message-text. The text might contain placeholders which are processed by a `MessageInterpolator` ===== MessageInterpolator A `MessageInterpolator` replaces the placeholders in a message-text with the arguments of the message. *Configuration of a message-interpolator* Besides the static configuration via `@MessageContextConfig#messageInterpolator, you can use it dynamically via passing a custom message-interpolator instance to the current messageContext: [source,java] ----------------------------------------------------------------------------------------------------- @Inject private MessageContext messageContext; //... Message message = this.messageContext.messageInterpolator(new CustomMessageInterpolator()).message(); ----------------------------------------------------------------------------------------------------- ===== LocaleResolver A locale resolver provides the current locale. The locale is, for example, used to by a `MessageResolver` to choose the correct language for the message-text. *Configuration of a locale-resolver* Besides the static configuration via `@MessageContextConfig#localeResolver, you can use it dynamically via passing a custom locale-resolver instance to the current messageContext: ------------------------------------------------------------------------------------------- @Inject private MessageContext messageContext; //... Message message = this.messageContext.localeResolver(new CustomLocaleResolver()).message(); ------------------------------------------------------------------------------------------- == Injecting Resources DeltaSpike has simple APIs for performing basic resource loading and property file reading. [source,java] ---------------------------------------- @Inject @InjectableResource(location="myfile.properties") private InputStream inputStream; ---------------------------------------- This can be used to read resources from the classpath or from the file system using the two default implementations -- `ClasspathResourceProvider` and `FileResourceProvider` -- or from any other source using a custom provider. === Custom resource providers The `InjectableResourceProvider` interface can be implemented to allow reading from alternate sources if needed (e.g. database LOBs, NoSQL storage areas). A base class called `AbstractResourceProvider` is provided by DeltaSpike and contains most of the methods for potential implementations. The only method which must be provided is the `readStream(InjectableResource)` which returns an InputStream. == Exception Control Exception handling in DeltaSpike is based around the CDI eventing model. While the implementation of exception handlers may not be the same as a CDI event, and the programming model is not exactly the same as specifying a CDI event observer, the concepts are very similar. DeltaSpike makes use of events for many of its features. Eventing is actually the only way to start using DeltaSpike's exception handling. This event is fired either by the application or a DeltaSpike exception handling integration. DeltaSpike then hands the exception off to a chain of registered handlers, which deal with the exception appropriately. The use of CDI events to connect exceptions to handlers makes this strategy of exception handling non-invasive and minimally coupled to the exception handling infrastructure. The exception handling process remains mostly transparent to the developer. In most cases, you register an exception handler simply by annotating a handler method. Alternatively, you can handle an exception programmatically, just as you would observe an event in CDI. === Usage The entire exception handling process starts with an event. This helps keep your application minimally coupled to DeltaSpike, but also allows for further extension. Exception handling in DeltaSpike is all about letting you take care of exceptions the way that makes the most sense for your application Events provide this delicate balance. Firing the event is the main way of starting the exception handling proccess. Manually firing an event to use DeltaSpike's exception handling is primarily used in your own try/catch blocks. It is very painless and also easy. Let's examine a sample that might exist inside of a simple business logic lookup into an inventory database: [source,java] ---------------------------------------------------------------------------- public class InventoryActions { @PersistenceContext private EntityManager em; @Inject private Event catchEvent; public Integer queryForItem(Item item) { try { Query q = em.createQuery("SELECT i from Item i where i.id = :id"); q.setParameter("id", item.getId()); return q.getSingleResult(); } catch (PersistenceException e) { catchEvent.fire(new ExceptionToCatchEvent(e)); } } } ---------------------------------------------------------------------------- The `Event` of generic type `ExceptionToCatchEvent` is injected into your class for use later within a try/catch block. The event is fired with a new instance of `ExceptionToCatchEvent` constructed with the exception to be handled. === Exception Handlers As an application developer (i.e., an end user of DeltaSpike's exception handling), you'll be focused on writing exception handlers. An exception handler is a method on a CDI bean that is invoked to handle a specific type of exception. Within that method, you can implement any logic necessary to handle or respond to the exception. *If there are no exception handlers for an exception, the exception is rethrown - except `ExceptionToCatchEvent#optinal` is set to true* Given that exception handler beans are CDI beans, they can make use of dependency injection, be scoped, have interceptors or decorators and any other functionality available to CDI beans. Exception handler methods are designed to follow the syntax and semantics of CDI observers, with some special purpose exceptions explained in this guide. The advantage of this design is that exception handlers will be immediately familiar to you if you are studying or well-versed in CDI. In this and subsequent sections, you'll learn how to define an exception handler, explore how and when it gets invoked, modify an exception and a stack trace, and even extend exception handling further through events that are fired during the handling workflow. We'll begin by covering the two annotations that are used to declare an exception handler, `@ExceptionHandler` and `@Handles`, and `@BeforeHandles` to create a callback before the handler is called. Exception handlers are considered equal if they both handle the same exception class, have the same qualifiers, the same ordinal and the same value for `isBeforeHandler()`. Exception handlers are contained within exception handler beans, which are CDI beans annotated with `@ExceptionHandler`. Exception handlers are methods which have a parameter which is an instance of `ExceptionEvent` annotated with the `@Handles` annotation. ==== @ExceptionHandler The `@ExceptionHandler` annotation is simply a marker annotation that instructs the DeltaSpike exception handling CDI extension to scan the bean for handler methods. Let's designate a CDI bean as an exception handler by annotating it with `@ExceptionHandler`. [source,java] -------------------------- @ExceptionHandler public class MyHandlers {} -------------------------- That's all there is to it. Now we can begin defining exception handling methods on this bean. ==== @Handles and @BeforeHandles `@Handles` is a method parameter annotation that designates a method as an exception handler. Exception handler methods are registered on beans annotated with `@ExceptionHandler`. DeltaSpike will discover all such methods at deployment time. Let's look at an example. The following method is invoked for every exception that DeltaSpike processes and prints the exception message to stdout. (`Throwable` is the base exception type in Java and thus represents all exceptions). [source,java] ---------------------------------------------------------------- @ExceptionHandler public class MyHandlers { void printExceptions(@Handles ExceptionEvent evt) { System.out.println("Something bad happened:" + evt.getException().getMessage()); evt.handleAndContinue(); } } ---------------------------------------------------------------- The `@Handles` annotation on the first parameter designates this method as an exception handler (though it is not required to be the first parameter). This parameter must be of type `ExceptionEvent`, otherwise it is detected as a definition error. The type parameter designates which exception the method should handle. This method is notified of all exceptions (requested by the base exception type `Throwable`). The `ExceptionEvent` instance provides access to information about the exception and can be used to control exception handling flow. In this case, it is used to read the current exception being handled in the exception chain, as returned by `getException()`. This handler does not modify the invocation of subsequent handlers, as designated by invoking `handleAndContinue()` on `ExceptionEvent`. As this is the default behavior, this line could be omitted. The `@Handles` annotation must be placed on a parameter of the method, which must be of type `ExceptionEvent`. Handler methods are similar to CDI observers and, as such, follow the same principles and guidelines as observers (such as invocation, injection of parameters, qualifiers, etc) with the following exceptions: * a parameter of a handler method must be a `ExceptionEvent` * handlers are ordered before they are invoked (invocation order of observers is non-deterministic) * any handler can prevent subsequent handlers from being invoked In addition to designating a method as exception handler, the `@Handles` annotation specifies an `ordinal` about when the method should be invoked relative to other handler methods of the same type. Handlers with higher ordinal are invoked before handlers with a lower ordinal that handle the same exception type. The default ordinal (if not specified) is 0. The `@BeforeHandles` designates a method as a callback to happen before handlers are called. Let's take a look at more sophisticated example that uses all the features of handlers to log all exceptions. [source,java] ------------------------------------------------------------------------------------------- @ExceptionHandler public class MyHandlers { void logExceptions(@BeforeHandles @WebRequest ExceptionEvent evt, Logger log) { log.warn("Something bad happened: " + evt.getException().getMessage()); } void logExceptions(@Handles @WebRequest ExceptionEvent evt, Logger log) { // possibly send a HTTP Error code } } ------------------------------------------------------------------------------------------- This handler has a default ordinal of 0 (the default value of the ordinal attribute on `@Handles`). This handler is qualified with `@WebRequest`. When DeltaSpike calculates the handler chain, it filters handlers based on the exception type and qualifiers. This handler will only be invoked for exceptions passed to DeltaSpike that carry the `@WebRequest` qualifier. We'll assume this qualifier distinguishes a web page request from a REST request. Any additional parameters of a handler method are treated as injection points. These parameters are injected into the handler when it is invoked by DeltaSpike. In this case, we are injecting a `Logger` bean that must be defined within the application (or by an extension). A handler is guaranteed to only be invoked once per exception (automatically muted), unless it re-enables itself by invoking the `unmute()` method on the `ExceptionEvent` instance. Handlers must not throw checked exceptions, and should avoid throwing unchecked exceptions. Should a handler throw an unchecked exception it will propagate up the stack and all handling done via DeltaSpike will cease. Any exception that was being handled will be lost. ==== Ordinal When DeltaSpike finds more than one handler for the same exception type, it orders the handlers by ordinal. Handlers with higher ordinal are executed before handlers with a lower ordinal. If DeltaSpike detects two handlers for the same type with the same ordinal, the order is non-deterministic. Let's define two handlers with different ordinals: [source,java] ------------------------------------------------------------------------------------ void handleIOExceptionFirst(@Handles(ordinal = 100) ExceptionEvent evt) { System.out.println("Invoked first"); } void handleIOExceptionSecond(@Handles ExceptionEvent evt) { System.out.println(“Invoked second”); } ------------------------------------------------------------------------------------ The first method is invoked first since it has a higher ordinal (100) than the second method, which has the default ordinal (0). To summarize, here's how DeltaSpike determines the order of handlers to invoke (until a handler marks exception as handled): 1. Unwrap exception stack 2. Begin processing root cause 3. Invoke any callback methods annotated with @BeforeHandles for the closest type to the exception 4. Find handler for the closest type to the exception 5. If multiple handlers for same type, invoke handlers with higher ordinal first 6. Continue above steps for each exception in stack === Exception Chain Processing When an exception is thrown, chances are it is nested (wrapped) inside other exceptions. (If you've ever examined a server log, you'll appreciate this fact). The collection of exceptions in its entirety is termed an exception chain. The outermost exception of an exception chain (e.g., EJBException, ServletException, etc) is probably of little use to exception handlers. That's why DeltaSpike does not simply pass the exception chain directly to the exception handlers. Instead, it intelligently unwraps the chain and treats the root exception cause as the primary exception. The first exception handlers to be invoked by DeltaSpike are those that match the type of root cause. Thus, instead of seeing a vague `EJBException`, your handlers will instead see an meaningful exception such as `ConstraintViolationException`. _This feature, alone, makes DeltaSpike's exception handling a worthwhile tool._ DeltaSpike continues to work through the exception chain, notifying handlers of each exception in the stack, until a handler flags the exception as handled or the whole exception chain has been iterated. Once an exception is marked as handled, DeltaSpike stops processing the exception chain. If a handler instructs DeltaSpike to rethrow the exception (by invoking `ExceptionEvent#throwOriginal()`, DeltaSpike will rethrow the exception outside the DeltaSpike exception handling infrastructure. Otherwise, it simply returns flow control to the caller. Consider a exception chain containing the following nested causes (from outer cause to root cause): * EJBException * PersistenceException * SQLGrammarException DeltaSpike will unwrap this exception and notify handlers in the following order: * SQLGrammarException * PersistenceException * EJBException If there's a handler for `PersistenceException`, it will likely prevent the handlers for `EJBException` from being invoked, which is a good thing since what useful information can really be obtained from `EJBException`? === APIs for Exception Information and Flow Control There are two APIs provided by DeltaSpike that should be familiar to application developers: * `ExceptionEvent` * `ExceptionStackEvent` ==== ExceptionEvent In addition to providing information about the exception being handled, the `ExceptionEvent` object contains methods to control the exception handling process, such as rethrowing the exception, aborting the handler chain or unmuting the current handler. Five methods exist on the `ExceptionEvent` object to give flow control to the handler * `abort()` -- terminate all handling immediately after this handler, does not mark the exception as handled, does not re-throw the exception. * `throwOriginal()` -- continues through all handlers, but once all handlers have been called (assuming another handler does not call abort() or handled()) the initial exception passed to DeltaSpike is rethrown. Does not mark the exception as handled. * `handled()` -- marks the exception as handled and terminates further handling. * `handleAndContinue()` -- default. Marks the exception as handled and proceeds with the rest of the handlers. * `skipCause()` -- marks the exception as handled, but proceeds to the next cause in the cause container, without calling other handlers for the current cause. * `rethrow(Throwable)` -- Throw a new exception after this handler is invoked Once a handler is invoked it is muted, meaning it will not be run again for that exception chain, unless it is explicitly marked as unmuted via the `unmute()` method on `ExceptionEvent`. == Scopes DeltaSpike Core provides the API and SPI for several scopes. Currently all scopes are only implemented in the <>. === @WindowScoped === @ViewAccessScoped === @GroupedConversationScoped === Creating a Custom CDI Scope To create a custom CDI scope to match your needs, complete the following steps: 1. Create an Annotation with annotated with @jakarta.inject.Scope; + .Example [source,java] ---------------------------------------------------------------- @Scope @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) public @interface ACustomScope {} ---------------------------------------------------------------- + 2. Create an Extension to add the scope and a context for it. + .Example [source,java] --------------------------------------------------------------------------------------- public class ACustomScopeExtension implements Extension, Serializable { public void addACustomScope(@Observes final BeforeBeanDiscovery event) { event.addScope(ACustomScope.class, true, false); } public void registerACustomScopeContext(@Observes final AfterBeanDiscovery event) { event.addContext(new ACustomScopeContext()); } } --------------------------------------------------------------------------------------- + 3. Implement a jakarta.enterprise.context.spi.Context interface to hold the jakarta.enterprise.inject.spi.Bean instances according to your needs. + .Example [source,java] ----------------------------------------------------------------------------------------------------- public class ACustomScopeContext implements Context, Serializable { // Get the scope type of the context object. public Class getScope() { return ACustomScope.class; } // Return an existing instance of certain contextual type or create a new instance by calling // jakarta.enterprise.context.spi.Contextual.create(CreationalContext) and return the new instance. public T get(Contextual contextual, CreationalContext creationalContext) { Bean bean = (Bean) contextual; // you can store the bean somewhere if (somewhere.containsKey(bean.getName())) { return (T) somewhere.get(bean.getName()); } else { T t = (T) bean.create(creationalContext); somewhere.put(bean.getName(), t); return t; } } // Return an existing instance of a certain contextual type or a null value. public T get(Contextual contextual) { Bean bean = (Bean) contextual; // you can store the bean somewhere if (somewhere.containsKey(bean.getName())) { return (T) somewhere.get(bean.getName()); } else { return null; } } // Determines if the context object is active. public boolean isActive() { return true; } } ----------------------------------------------------------------------------------------------------- == Deactivatable DeltaSpike allows you to deactivate its own pre-configured parts (like Extensions, event-broadcasters,...). Therefore DeltaSpike offers `org.apache.deltaspike.core.spi.activation.ClassDeactivator` and `org.apache.deltaspike.core.spi.activation.Deactivatable`. A `ClassDeactivator` allows to specify deactivated classes (if they implement `Deactivatable`) which can't be deactivated/customized via std. CDI mechanisms (like the veto-method or alternative/specialized CDI-beans). This might be the case e.g. for CDI Extensions because CDI mechanisms are not available at startup time. Use it mainly to deactivate specific parts *explicitly* (blacklist approach), if there is an issue with such parts (and waiting for the next release isn't an option). You just need to implement your <>. The `ClassDeactivator` should be resolved by any ConfigSource using the key `org.apache.deltaspike.core.spi.activation.ClassDeactivator`. For example, if we need to provide our own version of the SecurityExtension, we can disable the SecurityExtension provided by DeltaSpike with the following `ClassDeactivator`: .Disable a specific extension [source,java] -------------------------------------------------------------------------- public class CustomClassDeactivator implements ClassDeactivator { private static final long serialVersionUID = 1L; @Override public Boolean isActivated(Class targetClass) { if (targetClass.equals(SecurityExtension.class)) { return Boolean.FALSE; } return null; //no result for the given class } } -------------------------------------------------------------------------- Now, we can use the file `/META-INF/apache-deltaspike.properties` (or any other <>) with the following key/value: ------------------------------------------------------------------------------------------ org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.test.CustomClassDeactivator ------------------------------------------------------------------------------------------ SecurityExtension still gets started, because it isn't possible to veto it, however, it isn't processing beans (once deactivated) and therefore it's e.g. possible to extend and customize the default implementation provided by DeltaSpike. The following listing shows how to enable only a minimal set of extensions. Technically that's possible, however, it isn't suggested to use such an approach, because you might disable mechanisms need later on (in your project). .Possible but not suggested [source,java] -------------------------------------------------------------------------- public class WhitelistFilter implements ClassDeactivator { private List> limitedExtensions = new ArrayList>() {{ add(ConfigurationExtension.class); add(PartialBeanBindingExtension.class); add(RepositoryExtension.class); }}; @Override public Boolean isActivated( Class deactivatableClass) { return !Extension.class.isAssignableFrom(deactivatableClass) || limitedExtensions.contains(deactivatableClass); } } -------------------------------------------------------------------------- Instead it's better to disable the part you really like to deactivate (see `CustomClassDeactivator`). === Deactivate Deactivatable-Classes via Config The default implementation of `ClassDeactivator` allows to deactivate classes by adding config-entries to one of your config-sources (like `META-INF\apache-deltaspike.properties`). The following example shows how it would look like e.g. in case of the SecurityExtension: ------------------------------------------------------------------------------------------ deactivate.org.apache.deltaspike.security.impl.extension.SecurityExtension=true ------------------------------------------------------------------------------------------ == Asynchronous Operations DeltaSpike provides support for executing code in an asynchronous manner. The behavior is implemented as three different interceptors for your beans. - `@Futureable` - Designed for bean methods that return `Future's` of some form. The method call will automatically be submitted to an `ExecutorService` - `@Locked` - Ability to prevent concurrent access to a method based on its usage of reads/writes. - `@Throttled` - Ability to limit how frequently a method can be invoked. == @Futureable configuration The strategy to find the `ExecutorService` associated to the `@Futureable` name is the following one: 1. Check if there is a CDI bean of type `ExecutorService` with the name of the pool, if not try 2 2. Check if there is a JNDI entry matching the pool name directly or prefixed with `java:app/`, `java:global/`, `java:global/threads/`, `java:global/deltaspike/`, `java:`, if not try 3 3. Read the configuration and create a `ThreadPoolExecutor` IMPORTANT: the instance is looked up only once so from the first time it was read you can't change any configuration anymore. If you rely on the last option (configured executor) here are the keys you can set in DeltaSpike configuration: |=== | Key | Description | Default | futureable.pool..coreSize | The core size of the pool. | Number of available processors | futureable.pool..maxSize | The max size of the pool. | coreSize value | futureable.pool..keepAlive.value | Pool keep alive (when a thread is released). | 0 | futureable.pool..keepAlive.unit | Unit of keepAlive.value. It must match a `TIMEUNIT` name. | MILLISECONDS | futureable.pool..queue.type | The task queue type of the executor. Can be `ARRAY` to use an `ArrayBlockingQueue`, `LINKED` for a `LinkedBlockingQueue` or `SYNCHRONOUS` for a `SynchronousQueue`. | LINKED | futureable.pool..queue.fair | For synchronous and array queue types, if the queue is fair. | false | futureable.pool..queue.size | For array queue type, the size of the queue. | 1024 | futureable.pool..queue.capacity | For linked queue type, the capacity of the queue. | `Integer.MAX_VALUE` | futureable.pool..threadFactory.name | If set a CDI bean matching the value will be looked up and used as `ThreadFactory`. | none, `Executors.defaultThreadFactory()` is used | futureable.pool..rejectedExecutionHandler.name | If set a CDI bean matching the value will be looked up and used as `RejectedExecutionHandler`. | none, `ThreadPoolExecutor.AbortPolicy` is used |=== == Utilities DeltaSpike provides many utility classes (no constructor / static methods) that can be useful for your project. Below you can find an information about these classes. === AnnotationUtils Utilities for working with annotations on methods and classes. * `#findAnnotation` -- obtains an `Annotation` instance of a given annotation `Class` from the given `Annotation[]`, recursing any possible stereotype tree along the way * `#extractAnnotationFromMethod` -- uses `findAnnotation` to obtain an `Annotation` from a given `Method` * `#extractAnnotationFromMethodOrClass` -- uses `findAnnotation` to obtain an `Annotation` on either the given `Method` or the given `Class`, in that order * `#getQualifierHashCode` -- computes the hashCode of a qualifier annotation, taking into account only the "binding" members (not annotated `@Nonbinding`) === ArraysUtils A collection of utilities for working with Arrays * `#asSet` -- Create a set from an array. If the array contains duplicate objects, the last object in the array will be placed in resultant set. === BeanUtils A set of utility methods for working with beans. * `#getQualifiers` -- Extract the qualifiers from a set of annotations. * `#extractAnnotation` -- Extract the annotations. * `#createInjectionPoints` -- Given a method, and the bean on which the method is declared, create a collection of injection points representing the parameters of the method. === ContextUtils A set of utility methods for working with contexts. * `#isContextActive` -- Checks if the context for the scope annotation is active. === ClassDeactivationUtils Helper methods for `ClassDeactivator` * `#isActivated` -- Evaluates if the given `Deactivatable` is active. To add a custom `ClassDeactivator` add `org.apache.deltaspike.core.spi.activation.ClassDeactivator=my.CustomClassDeactivator` to `META-INF\apache-deltaspike.properties`. Or configure it via a custom `ConfigSource`. === ExceptionUtils Helper methods to deal with Exceptions * `#throwAsRuntimeException` -- helper which allows to use a trick to throw a catched checked exception without a wrapping exception. * `#changeAndThrowException` -- helper which allows to use a trick to throw a cached checked exception without a wrapping exception. === PropertyFileUtils Helper methods for Property files * `#resolvePropertyFiles` -- Allows to lookup for resource bundle files. * `#loadProperties` -- Load a Properties file from the given URL. * `#getResourceBundle` -- Return the ResourceBundle for the current default Locale. === ProxyUtils Helper for CDI proxies * `#getUnproxiedClass` -- Return class of the real implementation. * `#isProxiedClass` -- Analyses if the given class is a generated proxy class. === StringUtils A collection of utilities for working with Strings. * `#isEmpty` -- return true if the String is null or empty ( `string.trim().isEmpty()` ) ================================================ FILE: documentation/src/main/asciidoc/data.adoc ================================================ :moduledeps: core, jpa, partial-bean = Data Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Data module provides capabilities for implementing repository patterns and thereby simplifying the repository layer. Repository patterns are ideal for simple queries that require boilerplate code, enabling centralization of query logic and consequently reducing code duplication and improving testability. The code sample below gives you a quick overview on the common usage scenarios of the data module: [source,java] ---------------------------------------------------------------------------------- @Repository public interface PersonRepository extends EntityRepository { List findByAgeBetweenAndGender(int minAge, int maxAge, Gender gender); @Query("select p from Person p where p.ssn = ?1") Person findBySSN(String ssn); @Query(named=Person.BY_FULL_NAME) Person findByFullName(String firstName, String lastName); } ---------------------------------------------------------------------------------- As you see in the sample, there are several usage scenarios outlined here: * Declare a method which executes a query by simply translating its name and parameters into a query. * Declare a method which automatically executes a given JPQL query string with parameters. * Declare a method which automatically executes a named query with parameters. The implementation of the method is done automatically by the CDI extension. A client can declare a dependency to the interface only. The details on how to use those features are outlined in the following chapters. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare Data Module Dependencies Add the Data module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-data-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-data-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-data-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-data-module-api' ---- === 2. Complete Additional Java Environment Configuration The Data module requires a JPA implementation to be available in the Java environment where your projects are deployed. The simplest way using the DeltaSpike Data module is to run your application in a Java EE container supporting at least the Java EE6 Web Profile. Other configurations like running it inside Tomcat or even a Java SE application should be possible - you need to include a JPA provider as well as a CDI container to your application manually. As of DeltaSpike v1.4.0, the Data module internally leverages the Proxy module, which wraps ASM 5. No external dependencies required, and now we have full support for interceptors on partial beans. === 3. Complete Additional Project Configuration DeltaSpike Data requires an `EntityManager` exposed via a CDI producer - which is common practice in Java EE6 applications. [source,java] ------------------------------------------------------ public class EntityManagerProducer { @PersistenceUnit private EntityManagerFactory emf; @Produces // you can also make this @RequestScoped public EntityManager create() { return emf.createEntityManager(); } public void close(@Disposes EntityManager em) { if (em.isOpen()) { em.close(); } } } ------------------------------------------------------ This allows the `EntityManager` to be injected over CDI instead of only being used with a `@PersistenceContext` annotation. Using multiple `EntityManager` is explored in more detail in a following section. If you use a JTA DataSource with your `EntityManager`, you also have to configure the `TransactionStrategy` your repositories use. Adapt your `beans.xml` for this: [source,xml] ---- org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy ---- IMPORTANT: Using the DeltaSpike Data module in an EAR deployment is currently restricted to annotation-based entities. == Core Concepts === Repositories With the DeltaSpike Data module, it is possible to make a repository out of basically any abstract class or interface (using a concrete class will work too, but you will not be able to use most of the CDI extension features). All that is required is to mark the type as such with a simple annotation: [source,java] ---------------------------------------- @Repository(forEntity = Person.class) public abstract class PersonRepository { ... } @Repository(forEntity = Person.class) public interface PersonRepository { ... } ---------------------------------------- The `@Repository` annotation tells the extension that this is a repository for the `Person` entity. Any method defined on the repository will be processed by the framework. The annotation does not require to set the entity class (we'll see later why) but if there are just plain classes or interfaces this is the only way to tell the framework what entity the repository relates to. In order to simplify this, DeltaSpike Data provides several base types. ==== The `EntityRepository` Interface Although mainly intended to hold complex query logic, working with both a repository and an `EntityManager` in the service layer might unnecessarily clutter code. In order to avoid this for the most common cases, DeltaSpike Data provides base types which can be used to replace the entity manager. The top base type is the `EntityRepository` interface, providing common methods used with an `EntityManager`. The following code shows the most important methods of the interface: [source,java] ------------------------------------------------------------------------- public interface EntityRepository { E save(E entity); void remove(E entity); void refresh(E entity); void flush(); E findBy(PK primaryKey); List findAll(); List findBy(E example, SingularAttribute... attributes); List findByLike(E example, SingularAttribute... attributes); Long count(); Long count(E example, SingularAttribute... attributes); Long countLike(E example, SingularAttribute... attributes); } ------------------------------------------------------------------------- The concrete repository can then extend this basic interface. For our Person repository, this might look like the following: [source,java] ------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { Person findBySsn(String ssn); } ------------------------------------------------------------------------ TIP: Annotations on interfaces do not inherit. If the `EntityRepository` interface is extended by another interface adding some more common methods, it is not possible to simply add the annotation there. It needs to go on each concrete repository. The same is not true if a base class is introduced, as we see in the next chapter. ===== The AbstractEntityRepository Class This class is an implementation of the `EntityRepository` interface and provides additional functionality when custom query logic needs also to be implemented in the repository. [source,java] ------------------------------------------------------------------------------------- public abstract class PersonRepository extends AbstractEntityRepository { public List findBySSN(String ssn) { return typedQuery("select p from Person p where p.ssn = ?1") .setParameter(1, ssn) .getResultList(); } } ------------------------------------------------------------------------------------- === Deactivating Repositories Repositories can be deactivated creating a <>. The `EntityRepository` interface implements the <> interface allowing it to be used in the ClassDeactivator. If your repository does not implement `EntityRepository` and you want to deactivate it, you will need to implement the <> interface yourself. [source,java] ---------------------------------------- @Repository(forEntity = Person.class) public abstract class PersonRepository implements Deactivatable { ... } @Repository(forEntity = Person.class) public interface PersonRepository extends Deactivatable { ... } ---------------------------------------- === Support of @TransactionScoped EntityManagers For using `@TransactionScoped` beans like a `@TransactionScoped`-`EntityManager`, you need to annotate the Data-repository with @Transactional explicitly or one of the beans in the call-hierarchy. That's needed, because the context bound to `@TransactionScoped` needs to be active, before the `@TransactionScoped`-`EntityManager` gets resolved (internally). The following examples illustrate the described usages: .@TransactionScoped EntityManager combined with a simple repository [source,java] --------------------------------------------------------------------------------------- public class EntityManagerProducer { @Produces @TransactionScoped public EntityManager create() { ... } public void close(@Disposes EntityManager em) { ... } } @ApplicationScoped public class MyService { @Inject private MyRepository myRepository; public void create() { //... this.myRepository.save(...); //executed in a transaction //... } } @Transactional @Repository public interface MyRepository extends EntityRepository { //... } --------------------------------------------------------------------------------------- .@TransactionScoped EntityManager combined with a simple repository called by a transactional bean [source,java] --------------------------------------------------------------------------------------- public class EntityManagerProducer { @Produces @TransactionScoped public EntityManager create() { ... } public void close(@Disposes EntityManager em) { ... } } @Transactional @ApplicationScoped public class MyService { @Inject private MyRepository myRepository; public void create() //executed in a transaction { //... this.myRepository.save(...); //... } } @Repository public interface MyRepository extends EntityRepository { //... } --------------------------------------------------------------------------------------- === Using Multiple EntityManagers While most applications will run just fine with a single `EntityManager`, there might be setups where multiple data sources are used. This can be configured with the `EntityManagerConfig` annotation: [source,java] -------------------------------------------------------------------------------------------------------------- @Repository @EntityManagerConfig(entityManagerResolver = CrmEntityManagerResolver.class, flushMode = FlushModeType.COMMIT) public interface PersonRepository extends EntityRepository { ... } public class CrmEntityManagerResolver implements EntityManagerResolver { @Inject @CustomerData // Qualifier - assumes a producer is around... private EntityManager em; @Override public EntityManager resolveEntityManager() { return em; } } -------------------------------------------------------------------------------------------------------------- Again, note that annotations on interfaces do not inherit, so it is not possible to create something like a base `CrmRepository` interface with the `@EntityManagerConfig` and then extending / implementing this interface. === Other EntityManager Methods While the `EntityRepository` methods should cover most interactions normally done with an `EntityManager`, for some specific cases it might still be useful to have one or the other method available. For this case, it is possible to extend / implement the `EntityManagerDelegate` interface for repositories, which offers most other methods available in a JPA 2.0 `EntityManager`: [source,java] ------------------------------------------------------------------------------------------------------- @Repository public interface PersonRepository extends EntityRepository, EntityManagerDelegate { ... } ------------------------------------------------------------------------------------------------------- Alternatively, you can extend the `FullEntityRepository` interface which is a short-hand for extending all of `EntityRepository`, `EntityManagerDelegate` and `CriteriaSupport`. [source,java] ------------------------------------------------------------------------------------------------------- @Repository public interface PersonRepository extends FullEntityRepository { ... } ------------------------------------------------------------------------------------------------------- For abstract classes, there is a convenience base class `AbstractFullEntityRepository` which also implements `EntityManagerDelegate` and `CriteriaSupport` and thus exposes most `EntityManager` methods: [source,java] ------------------------------------------------------------------------------------------------------- @Repository public abstract PersonRepository extends AbstractFullEntityRepository { ... } ------------------------------------------------------------------------------------------------------- == Query Method Expressions Good naming is a difficult aspects in software engineering. A good method name usually makes comments unnecessary and states exactly what the method does. And with method expressions, the method name is actually the implementation! === Using Method Expressions Let's start by looking at a (simplified for readability) example: [source,java] ------------------------------------------------------------------------ @Entity public class Person { @Id @GeneratedValue private Long id; private String name; private Integer age; private Gender gender; } @Repository public interface PersonRepository extends EntityRepository { List findByNameLikeAndAgeBetweenAndGender(String name, int minAge, int maxAge, Gender gender); long countByName(String name); void removeByName(String name); } ------------------------------------------------------------------------ Looking at the method name, this can easily be read as query all Persons which have a name like the given name parameter, their age is between a min and a max age and having a specific gender. The DeltaSpike Data module can translate method names following a given format and directly generate the query implementation out of it (in EBNF-like form): ---------------------------------------------------------------------------------- (Entity|Optional|List|Stream) (prefix)(Property[Comparator]){Operator Property [Comparator]} ---------------------------------------------------------------------------------- Or in more concrete words: * The query method must return an entity, an `Optional` of an entity, a list of entities or a stream of entities. * It must start with the `findBy` prefix (or related `findOptionalBy`, `findAnyBy`, `findAll`, `findFirst` or `findTop`). * Followed by a property of the Repository entity and an optional comparator (we'll define this later). The property will be used in the query together with the comparator. Note that the number of arguments passed to the method depend on the comparator. * You can add more blocks of property-comparator which have to be concatenated by a boolean operator. This is either an `And` or `Or`. You can also use the same way for delete an entity: * It must start with the `removeBy` keyword (or related `deleteBy`). or for counting: * It must start with the `countBy` keyword. * It must return a int or long. Other assumptions taken by the expression evaluator: * The property name starts lower cased while the property in the expression has an upper cases first character. Following comparators are currently supported to be used in method expressions: [options="header, autowidth"] |=== | Name |# of Arguments |Description | Equal |1 | Property must be equal to argument value. If the operator is omitted in the expression, this is assumed as default. | EqualIgnoreCase |1 | Property must be equal to argument value (case insensitive). | IgnoreCase |1 | Property must be equal to argument value (case insensitive). | NotEqual |1 | Property must be not equal to argument value. | NotEqualIgnoreCase |1 | Property must be not equal to argument value (case insensitive). | Like |1 | Property must be like the argument value. Use the %-wildcard in the argument. | LikeIgnoreCase |1 | Property must be like the argument value (case insensitive). Use the %-wildcard in the argument. | NotLike `*` |1 | Property must be not like the argument value. Use the %-wildcard in the argument. | GreaterThan |1 | Property must be greater than argument value. | GreaterThanEquals |1 | Property must be greater than or equal to argument value. | LessThan |1 | Property must be less than argument value. | LessThanEquals |1 | Property must be less than or equal to argument value. | Between |2 | Property must be between the two argument values. | IsNull |0 | Property must be null. | IsNotNull |0 | Property must be non-null. | In `*` |1 | Property must be in the list of values given as a single argument. The argument should be of Collection type (e.g. List, Set, etc.). | NotIn `*` |1 | Property must be not in the list of values given as a single argument. The argument should be of Collection type (e.g. List, Set, etc.). | True `*` |0 | Property must be true. | False `*` |0 | Property must be false. | Containing `*` |1 | Property must be like the argument value. Don't use the %-wildcard in the argument. The argument value would be automatically wrapped in a pair of %-wildcard. | StartingWith `*` |1 | Property must begin with the argument value. Don't use the %-wildcard in the argument. A %-wildcard would be added automatically to the end of the argument value. | EndingWith `*` |1 | Property must end with the argument value. Don't use the %-wildcard in the argument. A %-wildcard would be added automatically to the start of the argument value. |=== `*` Comparator available since 1.9.1 Note that DeltaSpike will validate those expressions during startup, so you will notice early in case you have a typo in those expressions. Also note that as of 1.7, the Entity type returned can either by the entity defined in this repository, or any other entity in your persistence unit, or any primitive type supported by your JPA implementation. === Query Ordering Beside comparators it is also possible to sort queries by using the `OrderBy` keyword, followed by the attribute name and the direction (`Asc` or `Desc`). [source,java] ------------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { List findByLastNameLikeOrderByAgeAscLastNameDesc(String lastName); } ------------------------------------------------------------------------------ === Query Limits Starting with Apache DeltaSpike 1.6.2, you can apply query limits using method expressions. They can be applied using `findFirst` or `findTop` prefixes in a method like this: [source,java] ------------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { List findFirst2ByLastNameOrderByAgeAscLastNameDesc(String lastName); List findTop2ByLastNameOrderByAgeAscLastNameDesc(String lastName); } ------------------------------------------------------------------------------ The number following the prefix indicates how many to limit by, when setting the `maxResults` attribute of the underlying query. You can pair this with a `@FirstResult` parameter to give consistent paging. Query Limits can be applied even when there is no where clause defined by your query. [source,java] ------------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { List findAllOrderByAgeAsc(); List findTop20OrderByLastNameDesc(); } ------------------------------------------------------------------------------ The first query finding all entries ordered by age, and the second only 20 ordered by last name. === Nested Properties To create a comparison on a nested property, the traversal parts can be separated by a `_`: [source,java] ------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { List findByCompany_companyName(String companyName); } ------------------------------------------------------------------------ === Query Options DeltaSpike supports query options on method expressions. If you want to page a query, you can change the first result as well as the maximum number of results returned: [source,java] ----------------------------------------------------------------------------------------------- @Repository public interface PersonRepository extends EntityRepository { List findByNameLike(String name, @FirstResult int start, @MaxResults int pageSize); } ----------------------------------------------------------------------------------------------- === Method Prefix In case the `findBy` prefix does not comply with your team conventions, this can be adapted: [source,java] -------------------------------------------------------------------------------------------------- @Repository(methodPrefix = "fetchWith") public interface PersonRepository extends EntityRepository { List fetchWithNameLike(String name, @FirstResult int start, @MaxResults int pageSize); } -------------------------------------------------------------------------------------------------- == Query Annotations While method expressions are fine for simple queries, they will often reach their limit once things get slightly more complex. Another aspect is the way you want to use JPA: The recommended approach using JPA for best performance is over named queries. To help incorporate those use cases, the DeltaSpike Data module supports also annotating methods for more control on the generated query. === Using Query Annotations The simplest way to define a specific query is by annotating a method and providing the JPQL query string which has to be executed. In code, this looks like the following sample: [source,java] ------------------------------------------------------------------------ public interface PersonRepository extends EntityRepository { @Query("select count(p) from Person p where p.age > ?1") Long countAllOlderThan(int minAge); } ------------------------------------------------------------------------ The parameter binding in the query corresponds to the argument index in the method. You can also refer to a named query which is constructed and executed automatically. The `@Query` annotation has a named attribute which corresponds to the query name: [source,java] -------------------------------------------------------------------------------------------- @Entity @NamedQueries({ @NamedQuery(name = Person.BY_MIN_AGE, query = "select count(p) from Person p where p.age > ?1 order by p.age asc") }) public class Person { public static final String BY_MIN_AGE = "person.byMinAge"; ... } @Repository public interface PersonRepository extends EntityRepository { @Query(named = Person.BY_MIN_AGE) Long countAllOlderThan(int minAge); } -------------------------------------------------------------------------------------------- Same as before, the parameter binding corresponds to the argument index in the method. If the named query requires named parameters to be used, this can be done by annotating the arguments with the `@QueryParam` annotation. TIP: Java does not preserve method parameter names (yet), that's why the annotation is needed. [source,java] --------------------------------------------------------------------------------------------- @NamedQuery(name = Person.BY_MIN_AGE, query = "select count(p) from Person p where p.age > :minAge order by p.age asc") ... @Repository public interface PersonRepository extends EntityRepository { @Query(named = Person.BY_MIN_AGE) Long countAllOlderThan(@QueryParam("minAge") int minAge); } --------------------------------------------------------------------------------------------- It is also possible to set a native SQL query in the annotation. The `@Query` annotation has a native attribute which flags that the query is not JPQL but plain SQL: [source,java] ------------------------------------------------------------------------------------ @Entity @Table(name = "PERSON_TABLE") public class Person { ... } @Repository public interface PersonRepository extends EntityRepository { @Query(value = "SELECT * FROM PERSON_TABLE p WHERE p.AGE > ?1", isNative = true) List findAllOlderThan(int minAge); } ------------------------------------------------------------------------------------ === Annotation Options Beside providing a query string or reference, the `@Query` annotation provides also two more attributes: [source,java] -------------------------------------------------------------------------------------- @Repository public interface PersonRepository extends EntityRepository { @Query(named = Person.BY_MIN_AGE, max = 10, lock = LockModeType.PESSIMISTIC_WRITE) List findAllForUpdate(int minAge); } -------------------------------------------------------------------------------------- [options="header, autowidth"] |=== | Name | Description | max | Limits the number of results. | lock | Use a specific LockModeType to execute the query. |=== Note that these options can also be applied to method expressions. === Query Options All the query options you have seen so far are more or less static. But sometimes you might want to apply certain query options dynamically. For example, sorting criteria could come from a user selection so they cannot be known beforehand. DeltaSpike allows you to apply query options at runtime by using the `QueryResult` result type: [source,java] ------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { @Query("select p from Person p where p.age between ?1 and ?2") QueryResult findAllByAge(int minAge, int maxAge); } ------------------------------------------------------------------------ Once you have obtained a `QueryResult`, you can apply further options to the query: [source,java] ----------------------------------------------------------- List result = personRepository.findAllByAge(18, 65) .orderAsc("p.lastName", false) .orderDesc("p.age", false) .lockMode(LockModeType.WRITE) .hint("org.hibernate.timeout", Integer.valueOf(10)) .getResultList(); ----------------------------------------------------------- IMPORTANT: Note that sorting is only applicable to method expressions or non-named queries. For named queries it might be possible, but is currently only supported for Hibernate, EclipseLink and OpenJPA. Note that the `QueryResult` return type can also be used with method expressions. IMPORTANT: `QueryResult` is based on our internal understanding of your query. DeltaSpike expects the alias used in your queries to refer to the entity as `e` You can disable this behavior by passing in false with your attribute, `.orderDesc("p.age", false)` which would add descending ordering to your existing query `select p from Person p` === Pagination We introduced the `QueryResult` type in the last chapter, which can also be used for pagination: [source,java] ----------------------------------------------------------- // Query API style QueryResult paged = personRepository.findByAge(age) .maxResults(10) .firstResult(50); // or paging style QueryResult paged = personRepository.findByAge(age) .withPageSize(10) // equivalent to maxResults .toPage(5); int totalPages = paged.countPages(); ----------------------------------------------------------- === Bulk Operations While reading entities and updating them one by one might be fine for many use cases, applying bulk updates or deletes is also a common usage scenario for repositories. DeltaSpike supports this with a special marking annotation `@Modifying`: [source,java] ------------------------------------------------------------------------------ @Repository public interface PersonRepository extends EntityRepository { @Modifying @Query("update Person as p set p.classifier = ?1 where p.classifier = ?2") int updateClassifier(Classifier current, Classifier next); } ------------------------------------------------------------------------------ Bulk operation query methods can either return void or int, which counts the number of entities affected by the bulk operation. === Optional Query Results The JPA spec requires to throw exceptions in case the `getSingleResult()` method does either return no or more than one result. This can result in tedious handling with try-catch blocks or have potential impact on your transaction (as the `RuntimeException` might roll it back). DeltaSpike Data gives the option to change this to the way it makes most sense for the current usecase. While the default behavior is still fully aligned with JPA, it is also possible to request optional query results. === Zero or One Result With this option, the query returns `null` instead of throwing a `NoResultException` when there is no result returned. It is usable with method expressions, `Query` annotations and `QueryResult` calls. [source,java] ---------------------------------------------------------------------------- @Repository(forEntity = Person.class) public interface PersonRepository { Person findOptionalBySsn(String ssn); @Query(named = Person.BY_NAME, singleResult = SingleResultType.OPTIONAL) Person findByName(String firstName, String lastName); } ---------------------------------------------------------------------------- For method expressions, the `findOptionalBy` prefix can be used. For `@Query` annotations, the `singleResult` attribute can be overridden with the `SingleResultType.OPTIONAL` enum. In case the query returns more than one result, a `NonUniqueResultException` is still thrown. === Any Result If the caller does not really mind what kind if result is returned, it is also possible to request any result from the query. If there is no result, same as for optional queries `null` is returned. In case there is more than one result, any result is returned, or more concretely the first result out of the result list. [source,java] ----------------------------------------------------------------------- @Repository(forEntity = Person.class) public interface PersonRepository { Person findAnyByLastName(String lastName); @Query(named = Person.BY_NAME, singleResult = SingleResultType.ANY) Person findByName(String firstName, String lastName); } ----------------------------------------------------------------------- For method expressions, the `findAnyBy` prefix can be used. For `@Query` annotations, the `singleResult` attribute can be overridden with the `SingleResultType.ANY` enum. This option will not throw an exception. === Java 8 Semantics Repositories support returning instances of `java.util.Optional` and `java.util.stream.Stream` for any method. [source,java] ----------------------------------------------------------------------- @Repository(forEntity = Person.class) public interface PersonRepository { Optional findBySsn(String ssn); Stream findByLocation(String location); } ----------------------------------------------------------------------- Queries returning `Optional` will behave like `SingleResultType.OPTIONAL`, if the data is present, return the single result, otherwise return `Optional.empty()`. You can override this by using `SingleResultType.ANY` which takes the first result of the list, or else `empty()`. Queries returning `Stream` act as a simple wrapper for `query.getResultList().stream()` to give back the results. === Entity Graphs EntityGraphs are a feature added in JPA 2.1. The Data module supports entity graphs for query operations, where the results will be limited based on a defined graph. This feature is only available if you are using a JPA 2.1 implementation. `@EntityGraph` can be used for either `fetch` or `load` operations, depending on the `EntityGraphType` used in the annotation. Most queries should use the `FETCH` option. ==== Named Graphs Entity graphs can be selected by name. A `@NamedEntityGraph` should be defined already within your persistence context to leverage this. When this graph is referenced on a repository method, it will be applied to the query. ==== Dyanmically built graphs If you want to dynamically build a graph, you can do that via the `paths` attribute of the annotation. The paths specified will be added as graph nodes. Each graph node will be used in the select. The format is the full path to the property, based on the property names. == Transactions If you call any method expression, `@Query`-annotated method or a method from the `EntityRepository`, the repository will figure out if a transaction is needed or not, and if so, if there is already one ongoing. The Data module uses the `TransactionStrategy` provided by the http://deltaspike.apache.org/documentation/jpa.html[JPA Module] for this. See the JPA module documentation for more details. IMPORTANT: Some containers do not support `BeanManagedUserTransactionStrategy`! As JTA has still some portability issues even in Java EE 7, it might be required that you implement your own `TransactionStrategy`. We will think about providing an acceptable solution for this. If you need to open a transaction on a concrete repository method, we currently recommend creating an extension (see next chapter) which uses `@Transactional` and might look like the following sample. [source,java] --------------------------------------------------------------------------------------- public class TxExtension implements DelegateQueryHandler, TxRepository // this is your extension interface { @Inject private EntityManager em; @Override @Transactional public List transactional(ListResultCallback callback) { return callback.execute(); } } --------------------------------------------------------------------------------------- Repositories can then implement the `TxRepository` interface and call their queries in the `transactional` method (where the callback implementation can be, for example, in an anonymous class). == Extensions === Query Delegates While several base interfaces are defined for repositories, there might still be the odd convenience method that is missing. This is actually intentional - things should not get overloaded for each and every use case. That's why in DeltaSpike you can define your own reusable methods. For example, you might want to use the QueryDsl library in your repositories: [source,java] --------------------------------------------------------- import com.mysema.query.jpa.impl.JPAQuery; public interface QueryDslSupport { JPAQuery jpaQuery(); } @Repository(forEntity = Person.class) public interface PersonRepository extends QueryDslSupport { ... } --------------------------------------------------------- === Implementing the Query Delegate The first step is to define an interface which contains the extra methods for your repositories (as shown above): [source,java] -------------------------------- public interface QueryDslSupport { JPAQuery jpaQuery(); } -------------------------------- As a next step, you need to provide an implementation for this interface once. It is also important that this implementation implements the `DelegateQueryHandler` interface (do not worry, this is just an empty marker interface): [source,java] -------------------------------------------------------------------------------------------- public class QueryDslRepositoryExtension implements QueryDslSupport, DelegateQueryHandler { @Inject private QueryInvocationContext context; @Override public JPAQuery jpaQuery() { return new JPAQuery(context.getEntityManager()); } } -------------------------------------------------------------------------------------------- As you see in the sample, you can inject a `QueryInvocationContext` which contains utility methods like accessing the current `EntityManager` and entity class. Note that, if you define multiple extensions with equivalent method signatures, there is no specific order in which the implementation is selected. == Mapping While repositories are primarily intended to work with Entities, it might be preferable in some cases to have an additional mapping layer on top of them, for example because the Entities are quite complex but the service layer needs only a limited view on it, or because the Entities are exposed over a remote interface and there should not be a 1:1 view on the domain model. DeltaSpike Data allows to directly plugin in such a mapping mechanism without the need to specify additional mapping methods: [source,java] ---------------------------------------------------- @Repository(forEntity = Person.class) @MappingConfig(PersonDtoMapper.class) public interface PersonRepository { PersonDto findBySsn(String ssn); List findByLastName(String lastName); } ---------------------------------------------------- The `PersonDtoMapper` class has to implement the `QueryInOutMapper` interface: [source,java] --------------------------------------------------------------------------------- public class PersonDtoMapper implements QueryInOutMapper { @Override public Object mapResult(Person result) { ... // converts Person into a PersonDto } ... @Override public Object mapResultList(List result) { ... // result lists can also be mapped into something different // than a collection. } @Override public boolean mapsParameter(Object parameter) { return parameter != null && ( parameter instanceof PersonDto || parameter instanceof PersonId); } @Override public Object mapParameter(Object parameter) { ... // converts query parameters if required } } --------------------------------------------------------------------------------- The mapper can also be used to transform query parameters. Parameters are converted before executing queries and calling repository extensions. Note that those mapper classes are treated as CDI Beans, so it is possible to use injection in those beans (e.g. you might inject an `EntityManager` or other mappers). As the `@MappingConfig` refers to the mapper class directly, the mapper must be uniquely identifiable by its class. It is also possible to combine mappings with the base Repository classes: [source,java] ------------------------------------------------------------------------------- @Repository(forEntity = Person.class) @MappingConfig(PersonDtoMapper.class) public interface PersonRepository extends EntityRepository { ... } ------------------------------------------------------------------------------- In this case, the `forEntity` attribute in the `@Repository` annotation is mandatory. Also it is up to the mapper to convert parameters correctly (in this example, a conversion from a `PersonDto` parameter to `Person` entity and from `PersonId` to `Long` is necessary). === Simple Mappings In many cases it is just required to map a DTO object back and forth. For this case, the `SimpleQueryInOutMapperBase` class can be subclassed, which only requires to override three methods: [source,java] ------------------------------------------------------------------------------- public class PersonMapper extends SimpleQueryInOutMapperBase { @Override protected Object getPrimaryKey(PersonDto dto) { return dto.getId(); } @Override protected PersonDto toDto(Person entity) { ... } @Override protected Person toEntity(Person entity, PersonDto dto) { ... return entity; } } ------------------------------------------------------------------------------- The first method, `getPrimaryKey`, identifies the primary key of an incoming DTO (this might need mapping too). If there is a primary key in the DTO, Data tries to retrieve the Entity and feed it to the `toEntity` method, so the entity to be mapped is **attached to the persistence context**. If there is no primary key, a new instance of the Entity is created. In any case, there is no need to map the primary key to the entity (it either does not exist or is already populated for an existing entity). == JPA Criteria API Support Besides automatic query generation, the DeltaSpike Data module also provides a DSL-like API to create JPA 2 Criteria queries. It takes advantage of the JPA 2 meta model, which helps creating type safe queries. TIP: The JPA meta model can easily be generated with an annotation processor. Hibernate or EclipseLink provide such a processor, which can be integrated into your compile and build cycle. Note that this criteria API is not intended to replace the standard criteria API - it is rather a utility API that should make life easier on the most common cases for a custom query. The JPA criteria API's strongest point is certainly its type safety - which comes at the cost of readability. We're trying to provide a middle way here. A less powerful API, but still type safe and readable. === API Usage The API is centered around the Criteria class and is targeted to provide a fluent interface to write criteria queries: [source,java] --------------------------------------------------------------------------- @Repository(forEntity = Person.class) public abstract class PersonRepository implements CriteriaSupport { public List findAdultFamilyMembers(String name, Integer minAge) { return criteria() .like(Person_.name, "%" + name + "%") .gtOrEq(Person_.age, minAge) .eq(Person_.validated, Boolean.TRUE) .orderDesc(Person_.age) .getResultList(); } } --------------------------------------------------------------------------- Following comparators are supported by the API: [options="header,autowidth"] |=== | Name | Description | .eq(..., ...) | Property value must be equal to the given value | .in(..., ..., ..., ...) | Property value must be in one of the given values. | .notEq(..., ...) | Negates equality | .like(..., ...) | A SQL `like` equivalent comparator. Use % on the value. | .notLike(..., ...) | Negates the like value | .lt(..., ...) | Property value must be less than the given value. | .ltOrEq(..., ...) | Property value must be less than or equal to the given value. | .gt(..., ...) | Property value must be greater than the given value. | .ltOrEq(..., ...) | Property value must be greater than or equal to the given value. | .between(..., ..., ...) | Property value must be between the two given values. | .isNull(...) | Property must be `null` | .isNotNull(...) | Property must be non-`null` | .isEmpty(...) | Collection property must be empty | .isNotEmpty(...) |Collection property must be non-empty |=== The query result can be modified with the following settings: [options="header,autowidth"] |=== | Name | Description | .orderAsc(...) | Sorts the result ascending by the given property. Note that this can be applied to several properties | .orderDesc(...) | Sorts the result descending by the given property. Note that this can be applied to several properties | .distinct() | Sets distinct to true on the query. |=== Once all comparators and query options are applied, the `createQuery()` method is called. This creates a JPA TypedQuery object for the repository entity. If required, further processing can be applied here. === Joins For simple cases, restricting on the repository entity only works out fine, but once the Data model gets more complicated, the query will have to consider relations to other entities. The module's criteria API therefore supports joins as shown in the sample below: [source,java] ------------------------------------------------------------------------------------- @Repository public abstract class PersonRepository extends AbstractFullEntityRepository { public List findByCompanyName(String companyName) { return criteria() .join(Person_.company, where(Company.class) .eq(Company_.name, companyName) ) .eq(Person_.validated, Boolean.TRUE) .getResultList(); } } ------------------------------------------------------------------------------------- Beside the inner and outer joins, also fetch joins are supported. Those are slighly simpler as seen in the next sample: [source,java] ------------------------------------------------------------------------------------- public abstract class PersonRepository extends AbstractFullEntityRepository { public Person findBySSN(String ssn) { return criteria() .fetch(Person_.familyMembers) .eq(Person_.ssn, ssn) .distinct() .getSingleResult(); } } ------------------------------------------------------------------------------------- === Boolean Operators By default, all query operators are concatenated as an and conjunction to the query. The DeltaSpike criteria API also allows to add groups of disjunctions. [source,java] ------------------------------------------------------------------------------------- public abstract class PersonRepository extends AbstractFullEntityRepository { public List findAdults() { return criteria() .or( criteria(). .gtOrEq(Person_.age, 18) .eq(Person_.origin, Country.SWITZERLAND), criteria(). .gtOrEq(Person_.age, 21) .eq(Person_.origin, Country.USA) ) .getResultList(); } } ------------------------------------------------------------------------------------- === Selections It might not always be appropriate to retrieve full entities - you might also be interested in scalar values or by modified entity attributes. The Criteria interface allows this with the selection method: [source,java] ------------------------------------------------------------------------------------------------------ public abstract class PersonRepository extends AbstractFullEntityRepository { public Statistics ageStatsFor(Segment segment) { return criteria() .select(Statistics.class, avg(Person_.age), min(Person_.age), max(Person_.age)) .eq(Person_.segment, segment) .getSingleResult(); } public List personViewForFamily(String name) { return criteria() .select(upper(Person_.name), attribute(Person_.age), substring(Person_.firstname, 1)) .like(Person_.name, name) .getResultList(); } } ------------------------------------------------------------------------------------------------------ There are also several functions supported which can be used in the selection clause: [options="header,autowidth"] |=== |Name | Description | abs(...) | Absolute value. Applicable to Number attributes. | avg(...) | Average value. Applicable to Number attributes. | count(...) | Count function. Applicable to Number attributes. | max(...) | Max value. Applicable to Number attributes. | min(...) | Min value. Applicable to Number attributes. | modulo(...) | Modulo function. Applicable to Integer attributes. | neg(...) | Negative value. Applicable to Number attributes. | sum(...) | Sum function. Applicable to Number attributes. | lower(...) | String to lowercase. Applicable to String attributes. | substring(int from, ...) | Substring starting from. Applicable to String attributes. | substring(int from, int to, ...) | Substring starting from ending to. Applicable to String attributes. | upper(...) | String to uppercase. Applicable to String attributes. | currDate() | The DB sysdate. Returns a Date object. | currTime() | The DB sysdate. Returns a Time object. | currTStamp() | The DB sysdate. Returns a Timestamp object. |=== == Auditing A common requirement for entities is tracking what is being done with them. DeltaSpike provides a convenient way to support this requirement. NOTE: DeltaSpike does not support creating revisions of entities. If this is a requirement for your audits, have a look at Hibernate Envers. === Activating Auditing DeltaSpike uses an entity listener to update auditing data before entities get created or update. The entity listener must be activated before it can be used. This can either be done globally for all entities of a persistent unit or per entity. Activation per persistence unit in `orm.xml`: [source,xml] ----------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------- Activation per entity: [source,java] ------------------------------------------- @Entity @EntityListeners(AuditEntityListener.class) public class AuditedEntity { ... } ------------------------------------------- Note that for this variant, you need a compile dependency on the impl module. Alternatively, also the per entity listener can be configured by XML. === Using Auditing Annotations All that has to be done now is annotating the entity properties which are used to audit the entity. ==== Updating Timestamps To keep track on creation and modification times, following annotations can be used: [source,java] ------------------------------------- @Entity public class AuditedEntity { ... @Temporal(TemporalType.TIMESTAMP) @CreatedOn private Date created; @Temporal(TemporalType.TIMESTAMP) @ModifiedOn private Date updated; ... } ------------------------------------- In case the modification date should also be set during entity creation, the annotation can be customized: ----------------------------- @ModifiedOn(setOnCreate=true) ----------------------------- ==== Who's Changing My Entities? Beside keeping track of when a change has happened, it is also often critical to track who's responsible for the change. Annotate a user tracking field with the following annotation: [source,java] ----------------------------- @Entity public class AuditedEntity { ... @ModifiedBy private String auditUser; ... } ----------------------------- Now a little help is needed. The entity listener needs to be able to resolve the current user - there must be a bean available of the matching type for the annotation property, exposed over a special CDI qualifier: [source,java] ---------------------------------- public class UserProvider { @Inject private User user; @Produces @CurrentUser public String currentUser() { return user.getUsername(); } ... } ---------------------------------- TIP: The JPA Spec does not recommend to modify entity relations from within a lifecycle callback. If you expose another entity here, make sure that your persistence provider supports this. Also you should ensure that the entity is attached to a persistent context. Also, be aware that the CDI container will proxy a scoped bean, which might confuse the persistence provider when persisting / updating the target entity. ================================================ FILE: documentation/src/main/asciidoc/encryption.adoc ================================================ = DeltaSpike Crypto Mechanism :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Introduction Many applications still use plaintext to store sensitive information. This should be avoided to not loose sensible user information in case of a security breach. Apache DeltaSpike provides a mechanism to encrypt and decrypt secured information to better guard such information. == The Algorithm DeltaSpike provides encryption based on a split secret approach. Many systems (like Maven, Jenkins) store the hash of a 'master password' in the users home folder. This master hash is then used to encrypt/decrypt the actual passwords. If an attacker manages to get his hands on the content of the database then he still cannot do much with the encrypted content stored therein. He would also need the content of the file containing the master password. DeltaSpike improves this mechanism by adding an additional secret (`masterSalt`) which needs to be provided by the application. With this approach we add an additional obstacle for any attacker. The attacker would now not only need the file from the users home folder but also need to debug and reconstruct the application. This approach additionally has the benefit to be able to store and use multiple different master passwords at the same time. That means that DeltaSpike needs 3 different pieces - the encryted content. E.g. a password stored in some property file or in the database - The `~/.deltaspike/master.hash` file containing the previously set master password. - the `masterSalt` provided by the application and while setting the master password. All that still does *not* create absolute security, mostly because there is no such thing like _absolute_ security! Each system which claims absolute security is to be taken with caution. But this handling will drastically improve the security of your application. See the section about the `masterSalt` for more tips to strengthten security. == Using the Command Line Interface Apache DeltaSpike also contains CLI commands to store the `masterPassword` and encrypt user values. The first step is to create a master hash. It is by default stored in the users home folder at `~/.deltaspike/master.hash`. For creating a master hash you need to use a `masterPassword` and a `masterSalt` [source,bash] ---- $> java -jar deltaspike-core-impl.jar encode -masterPassword myMasterPassword -masterSalt myMasterSalt A new master password got set. Hash key is cbd90f294dc4ed3d1113a98107fabbc370b303c4a5e3208c2df3e0326c31499c ---- You can now go on and encrypt your plaintext information: [source,bash] ---- $> java -jar deltaspike-core-impl.jar encode -plaintext textOneWantsToEncrypt -masterSalt myMasterSalt Encrypted value: 9d4196aa28d83a08b32752966aa5f4aa41c359fec847fdad3565241bb5e2df12 ---- The encrypted value can then be stored in the databas, config files, etc. == The masterPassword The masterPassword is used to protect the secret. Note that it's not possible to reconstruct the masterPassword from the master.hash file. == Providing a masterSalt The `masterSalt` is not used to encrypt the secrets but it only protects the `masterPassword` in the `master.hash` file. This means that the masterSalt could be either static or even change over time. The `masterSalt` could also be a combined local information. As an example we take the local IP address and the user name running the application. [source,java] ---- String localInformation = InetAddress.getLocalHost().getHostAddress() + System.getProperty("user.name"); String masterSalt = sha1(localInformation); ---- Note the usage of the hash. Otherwise it would be too obvious how the masterSalt gets constructed If this code is well hidden within the application code it is really hard for an attacker to find out how it is determined. Otoh this hash can easily be constructed on the command line with classic unix tools like `sha1sum` == Programmatic usage A program could either inject a CipherService or create a new DefaultCipherService to programmatically decrypt values. A usr could also provide a `ConfigFilter` to apply decryption on encrypted configuration values on the fly ================================================ FILE: documentation/src/main/asciidoc/index.adoc ================================================ :notoc: = Documentation :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ++++ ++++ ================================================ FILE: documentation/src/main/asciidoc/jpa.adoc ================================================ :moduledeps: core :moduleconf: api:org.apache.deltaspike.jpa.api.transaction.TransactionConfig = JPA Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The JPA module provides a transactional context and scope, enabling execution of methods within transactions. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare JPA Module Dependencies Add the JPA module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-jpa-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-jpa-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-jpa-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-jpa-module-api' ---- === 2. (Optional) Enable the Transaction Interceptor NOTE: If you are using CDI 1.0 or CDI 1.1+ with DeltaSpike v1.1.0 and earlier, you must enable the transaction interceptor in the project `beans.xml` file: [source,xml] ---- org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor ---- == @Transactional This annotation is an alternative to transactional EJBs and enables the execution of a method within a transaction. Before it is possible to start using the annotation, it is required to implement a CDI producer for an `EntityManager` and it is needed to inject the `EntityManager` in the bean which uses `@Transactional`. As shown later on, it is also possible to use multiple qualifiers for using different EntityManagers. === Basic usage The following example shows a simple producer for an `EntityManager` and the corresponding disposer method. Producing it as request scoped bean means that the disposer method will be called on finishing the request. Alternatively it is possible to use a special scope called <<__transactionscoped, `@TransactionScoped`>>. .Producer for the Default EntityManager (non-EE server) [source,java] ---------------------------------------------------------------------------- //... public class EntityManagerProducer { //or manual bootstrapping @PersistenceContext private EntityManager entityManager; @Produces @RequestScoped protected EntityManager createEntityManager() { return this.entityManager; } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } ---------------------------------------------------------------------------- .Producer for the Default EntityManager (EE server) [source,java] ----------------------------------------------------------------------- @ApplicationScoped public class EntityManagerProducer { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @Default @RequestScoped public EntityManager create() { return this.entityManagerFactory.createEntityManager(); } public void dispose(@Disposes @Default EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } ----------------------------------------------------------------------- The following examples show how to use the `EntityManager` produced by the example above. .Bean with a Transactional Method [source,java] ---------------------------------------- //... public class TransactionalBean { @Inject private EntityManager entityManager; @Transactional public void executeInTransaction() { //... } } ---------------------------------------- .Simple Transactional Bean (All Methods are Transactional) [source,java] ---------------------------------------- //... @Transactional public class TransactionalBean { @Inject private EntityManager entityManager; //... } ---------------------------------------- As illustrated in the following example it is also possible to use `@Transactional` for stereotypes. .Stereotype for Transactional Beans (+ Usage) [source,java] ---------------------------------------- @Stereotype @Transactional @ApplicationScoped public @interface Repository { } //... @Repository public class TransactionalBean { @Inject private EntityManager entityManager; //... } ---------------------------------------- === Multiple EntityManagers The default qualifier for `@Transactional` is `@Any` whereby a transaction gets started for every injected entity manager. Besides such simple usages, it is also possible to access multiple persistence units in parallel using qualifiers. First, the EntityManagers or EntityManagerFactories must be obtained from the JPA subsystem, then EntityManagers must be made available as CDI beans and finally injected into `@Transactional` beans for usage. ==== Obtaining EntityManagers from JPA In EE managed environments the EntityManager can be obtained directly or through an EntityManagerFactory using standard JPA annotations `@PersistenceContext` for an EntityManager or `@PersistenceUnit` for an EntityManagerFactory. When using `@PersistenceContext` the Container has the full control over the EntityManager. In this case transactions have to be conducted via a `TransactionManager` or `UserTransaction`. If the Database connection is set up to be JTA aware then please also see our <> section. .Container Managed EntityManager [source,java] ---- public class EntityManagerProducer { @PersistenceContext(unitName = "firstDB") private EntityManager firstEntityManager; @PersistenceContext(unitName = "secondDB") private EntityManager secondEntityManager; // ... } ---- An alternative for non-EE environments is available through DeltaSpike's `@PersistenceUnitName` qualifier allowing to inject EntityManagerFactories. .Unmanaged EntityManagerFactory [source,java] ---- public class EntityManagerProducer { @Inject @PersistenceUnitName("puA") private EntityManagerFactory emfA; @Inject @PersistenceUnitName("puB") private EntityManagerFactory emfB; // ... } ---- Obtaining an EntityManager from an EntityManagerFactory is just a matter of calling `emfA.createEntityManager()`. DeltaSpike provides a built-in producer for `@PersistenceUnitName` qualified EntityManagerFactories. This producer also looks up a property files with the name `persistence-{persistenceunit name}.properties` via the DeltaSpike `PropertyLoader`. For the example above this would be `persistence-puA.properties`. The properties in this file will be passed 1:1 to `Persistence#createEntityManagerFactory(properties)` by the built-in producer method. ==== Producing Multiple EntityManagers There are several ways to make multiple entity managers available for use in `@Transactional` methods, each suitable for a different situation. The simplest method employs a producer and a disposer for each EntityManager. .Deciding using qualifiers [source,java] ---- public class EntityManagerProducer { // ...entity managers or factories injected here @Produces @RequestScoped // or other @DbA //custom qualifier annotation public EntityManager createEntityManagerA() { return emfA.createEntityManager(); } public void closeEmA(@Disposes @DbA EntityManager em) { em.close(); } @Produces @RequestScoped @DbB //custom qualifier annotation public EntityManager createEntityManagerB() { return emfB.createEntityManager(); } public void closeEmB(@Disposes @DbB EntityManager em) { em.close(); } } ---- If there's the need to decide dynamically on which EntityManager should be used when it's possible to use the standard CDI facility of `InjectionPoint` to get information about the injection points and produce different EntityManagers with just one producer method. .Deciding using InjectionPoint [source,java] ---- public class EntityManagerProducer { // ...entity managers or factories injected here @Produces protected EntityManager createEntityManager(InjectionPoint injectionPoint) { CustomQualifier customQualifier = injectionPoint.getAnnotated().getAnnotation(CustomQualifier.class); return selectEntityManager(customQualifier); //selects firstEntityManager or secondEntityManager based on the details provided by CustomQualifier } } ---- The information necessary to make the decision about the EntityManager appropriate for the current situation and injection point may be available elsewhere, for example in a custom context. .Deciding using anything else [source,java] ---- public class EntityManagerProducer { // ...entity managers or factories injected here @Inject private CustomDatabaseContext customDatabaseContext; @Produces protected EntityManager createEntityManager() { if (customDatabaseContext.usePrimaryDb()) { return firstEntityManager; } return secondEntityManager; } } ---- ==== Using transactions with multiple EntityManagers One use case for multiple EntityManagers is their usage in nested transactions. When a transactional method is called from within a transactional method, it joins the existing transaction. .Nested transactions with multiple EntityManagers [source,java] ---- public class FirstLevelTransactionBean { @Inject private @First EntityManager firstEntityManager; @Inject private NestedTransactionBean nestedTransactionBean; @Transactional public void executeInTransaction() { //... this.nestedTransactionBean.executeInTransaction(); } } public class NestedTransactionBean { @Inject private @Second EntityManager secondEntityManager; @Transactional public void executeInTransaction() { //... } } ---- It's also easy to use multiple EntityManagers in the same bean in different transactional methods. By default, a `@Transactional` method would enroll all of the EntityManagers in the transaction. By using `@Transactional(qualifier=...)` it's easy to choose individual EntityManagers for each transactional method. .Selecting individual EntityManagers for a transactional method [source,java] ----------------------------------------------------------- public class MultiTransactionBean { @Inject private EntityManager defaultEntityManager; @Inject private @First EntityManager firstEntityManager; @Inject private @Second EntityManager secondEntityManager; @Transactional(qualifier = Default.class) public void executeInDefaultTransaction() {...} @Transactional(qualifier = First.class) public void executeInFirstTransaction() {...} @Transactional(qualifier = {First.class, Second.class}) public void executeInFirstAndSecondTransaction() {...} } ----------------------------------------------------------- The final transaction handling for all `EntityManager` s is also done after the outermost transactional method if `NestedTransactionBean` uses a different `EntityManager`. So it is possible to catch an exception in `FirstLevelTransactionBean`, for example, to try an optional path instead of an immediate rollback. == @TransactionScoped `@Transactional` also starts a context which is available as long as the transaction started by `@Transactional`. Besides other beans you can use this scope for the `EntityManager` itself. That means the `EntityManager` will be closed after leaving the method annotated with `@Transactional`. .Using a transaction-scoped EntityManager [source,java] ---------------------------------------------------------------------------- public class EntityManagerProducer { //or manual bootstrapping @PersistenceContext private EntityManager entityManager; @Produces @TransactionScoped protected EntityManager createEntityManager() { return this.entityManager; } protected void closeEntityManager(@Disposes EntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } ---------------------------------------------------------------------------- == Extended Persistence Contexts Frameworks like MyFaces Orchestra provide a feature which allows keeping an `EntityManager` across multiple requests. That means it is not required to call `EntityManager#merge` to add detached entities to the context. However, several application architectures do not allow such an approach (due to different reasons like scalability). In theory that sounds nice and it works pretty well for small to medium sized projects especially if an application does not rely on session replication in clusters. That also means that such an approach restricts your target environment from the very beginning. One of the base problems is that an `EntityManager` is not serializable. Beans which are scoped in a normal-scoped CDI context have to be serializable. So by default it is not allowed by CDI to provide a producer-method which exposes, for example, a conversation scoped `EntityManager` as it is. We *do not* recommend this approach and therefore it is not available out-of-the-box. However, if you really need this approach to avoid calling `#merge` for your detached entities, it is pretty simple to add this functionality. .Usage of a Simple extended EntityManager [source,java] ------------------------------------ @Inject private EntityManager entityManager; ------------------------------------ As you see the usage is the same. You *do not* have to use `ExtendedEntityManager` at the injection point. It is just needed in the producer-method: .Producer for an extended EntityManager (non-EE server) [source,java] ------------------------------------------------------------------------------------ //... public class ExtendedEntityManagerProducer { //or manual bootstrapping @PersistenceContext private EntityManager entityManager; @Produces @RequestScoped protected ExtendedEntityManager createEntityManager() { return new ExtendedEntityManager(this.entityManager); } protected void closeEntityManager(@Disposes ExtendedEntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } ------------------------------------------------------------------------------------ .Producer for an extended EntityManager (EE server) [source,java] ------------------------------------------------------------------------------------------ @ApplicationScoped public class ExtendedEntityManagerProducer { @PersistenceUnit private EntityManagerFactory entityManagerFactory; @Produces @Default @RequestScoped public ExtendedEntityManager create() { return new ExtendedEntityManager(this.entityManagerFactory.createEntityManager()); } public void dispose(@Disposes @Default ExtendedEntityManager entityManager) { if (entityManager.isOpen()) { entityManager.close(); } } } ------------------------------------------------------------------------------------------ .Implementation of a simple extended EntityManager [source,java] ------------------------------------------------------------------------- @Vetoed public class ExtendedEntityManager implements EntityManager, Serializable { private static final long serialVersionUID = 3770954229283539616L; private transient EntityManager wrapped; protected ExtendedEntityManager() { } public ExtendedEntityManager(EntityManager wrapped) { this.wrapped = wrapped; } /* * generated */ //delegate all calls to this.wrapped - most IDEs allow to generate it } ------------------------------------------------------------------------- This approach just works if it *does not come to serialization* of this wrapper, for example in case of session-replication. If those beans get serialized, you have to overcome this restriction by storing the persistence-unit-name and recreate the `EntityManager` via `Persistence.createEntityManagerFactory(this.persistenceUnitName).createEntityManager();` and sync it with the database before closing it on serialization. Furthermore, you have to intercept some methods of the `EntityManager` to merge detached entities automatically if those entities get serialized as well. However, as mentioned before *we do not recommend* such an approach. == JTA Support By default the transaction-type used by `@Transactional` is `RESOURCE_LOCAL`. If you configure `transaction-type="JTA"` in the persistence.xml file, you have to enable an alternative `TransactionStrategy` in the beans.xml which is called `org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy`. [source,xml] ---------------------------------------------------------------------------------------------------- org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy ---------------------------------------------------------------------------------------------------- Alternatively, you may expect that your transactions are started at a higher level, e.g. you're exposing a REST API and the endpoints themselves are either `@Transactional` or Stateless session beans, either with container managed Transactions, you would use `org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy`. This is the strategy to use if you are leveraging `@PersistenceContext` to inject your `EntityManager`. If you have multiple persistence units and you have to use both transaction types or the settings for development have to be different than the production settings, you can use `org.apache.deltaspike.jpa.impl.transaction.EnvironmentAwareTransactionStrategy` instead. NOTE: In case of some versions of Weld - including several versions of JBoss EAP/Wildfly and Websphere Liberty Profile - or OpenWebBeans in BDA mode - which is not the default one, you have to configure it as a <> instead of an `alternative` in `beans.xml`. That means you have to add, for example, `globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy =org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy` or `globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy = org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy` to `/META-INF/apache-deltaspike.properties`. ================================================ FILE: documentation/src/main/asciidoc/jsf.adoc ================================================ :moduledeps: core, security, proxy :moduleconf: api:org.apache.deltaspike.jsf.api.config.base.JsfBaseConfig, api:org.apache.deltaspike.jsf.api.config.JsfModuleConfig = JSF Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The JSF module provides CDI integration with JSF, with type-safe view config, multi-window handling, new scopes (WindowScoped, ViewScope, ViewAccessScoped, GroupedConversationScoped) and integration with DeltaSpike “core” messages and exception handling. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === Declare JSF Module Dependencies Add the JSF module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-jsf-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-jsf-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-jsf-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-jsf-module-api' ---- Some EE6 servers cannot handle optional classes. From DeltaSpike 1.0.1, if you do not like the corresponding log entries during startup or the deployment fails, you can use an alternative impl-module (instead of deltaspike-jsf-module-impl): [source,xml] ---- org.apache.deltaspike.modules deltaspike-jsf-module-impl-ee6 ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-jsf-module-impl-ee6' ---- .Support of EAR deployments IMPORTANT: Before using features described by this page, please ensure that you are aware of https://issues.apache.org/jira/browse/DELTASPIKE-335[DELTASPIKE-335] and the corresponding impact. == JSF Messages DeltaSpike provides an injectable component for typesafe FacesMessages. Is provides an integration with <> making the use of JSF messages and I18N simple and type-safe. Usage: [source,java] --------------------------------------------- @MessageBundle public interface Messages { @MessageTemplate("Welcome to DeltaSpike") String welcomeToDeltaSpike(); } @Model public class MyJSFBean { @Inject private JsfMessage messages; ... messages.addInfo().welcomeToDeltaSpike(); } --------------------------------------------- MessageBundle methods which are used as JsfMessage can return a `org.apache.deltaspike.core.api.message.Message` or a String. In case of a String we use it for both the summary and detail information on the FacesMessage. If a Message is returned, we lookup the 'detail' and 'summary' categories (see `org.apache.deltaspike.core.api.message.Message#toString(String)` for creating the FacesMessage. == Multi-Window Handling === Background ==== Historic Considerations Until the end of the 1990s web browsers are usually single threaded and only had one window. But in the last years browsers supporting multiple windows or even tab became the standard. Since those days lots of efforts went into uniquely identifying a single browser window on the server side. Sadly browser windows still lack of a native windowId, thus maintaining web application data in @SessionScoped backing beans is still used in most of the cases. ==== How JSF-2 Changed the World The MyFaces Orchestra community did a good summary about the various ways to handle multiple window support in JSF Applications. Those findings are still valid and up to date, but the environmental conditions have changed slightly since then. It is easy to pass a windowId around with a POST request, but it gets tricky with GET requests. Due to the new JSF-2 ability to use bookmarkable URLs and deep links, a typical JSF-2 application contains much more GET links than we used to see in JSF-1, thus we have far more href links to cope with. ==== Standard windowId Handling With a classical approach we would not be able to simply add a windowId parameter to such links because if the user would open the link in a new browser window or tab, we would carry the windowId - and thus the window scope - over to the new browser tab/window. The classic solution was to omit the windowId for all GET links, but by doing this we would now loose the window scope far too often with JSF-2! Marios summary also contains a method to prevent this problem by storing a value directly in the browser window via JavaScript. Usually this is rendered and executed in the same page as the user form. See the "Post-render window detection" paragraph for a more detailed description. The major downside of this solution is that we might already pollute 'foreign' beans (and destroy their information) while rendering the page, which means this is not feasible as general solution. === Available Modes ==== CLIENTWINDOW Each GET request results in an intermediate small HTML page (aka "windowhandler"). If the window.name is empty, a new windowId will stored into window.name. If the window.name is already set, the windowhandler checks if the window.name equals the requested windowId. When the windowId is valid, a unique token (called `dsrid`) will be generated for the current request and added to the URL. In addition a cookie with with the dsrid/dswid will be added. On the server side, the verified windowId will be extracted from the cookie. For POST request detection, the windowId will be added as hidden input to all forms. ===== Advantage * Covers all edge cases ===== Disadvantage * Having the windowhandler.html site rendered between requests sometimes leads to some 'flickering' if the destination page takes some time to load. The browser first renders our windowhandler and only after that the original page will get loaded. This effect may be minimized by branding the windowhandler.html page and providing an own one with a bgcolor which matches your application. For html-5 aware browsers we also got rid of this flickering by storing away a 'screenshot' of the first page in onclick() and immediately restore this 'screenshot' on the intermediate windowhandler.html page. Technically we do this by storing away the HTML DOM tree and css information into the html5 localStorage and restore them on the intermediate page. We also introduced a WindowConfig which is able to parse a request and decide upon the UserAgent or any other information if a client will get an intermediate page or if he gets the result page directly. ===== Configuration ====== Reduce windowhandler.html flickering Per default we only overwrite the onclick events of all links on the current page to make a 'screenshot' between requests. We also provide a mechanism to store the 'screenshot' on every button onclick: [source,java] ---------------------------------------------------------------------------- @Specializes public class MyClientWindowConfig extends DefaultClientWindowConfig { @Override public boolean isClientWindowStoreWindowTreeEnabledOnButtonClick() { return true; } } ---------------------------------------------------------------------------- ====== Change windowhandler.html To customize the look and feel of the windowhandler.html, you can simply provide a own via: [source,java] ---------------------------------------------------------------------------- @Specializes public class MyClientWindowConfig extends DefaultClientWindowConfig { @Override public String getClientWindowHtml() { return "Loading..."; } } ---------------------------------------------------------------------------- If you didn't copy the JS logic from our default windowhandler.html or if you would like to always show your custom html instead the 'screenshot', you should disable logic via: [source,java] ---------------------------------------------------------------------------- @Specializes public class MyClientWindowConfig extends DefaultClientWindowConfig { @Override public boolean isClientWindowStoreWindowTreeEnabledOnLinkClick() { return false; } @Override public boolean isClientWindowStoreWindowTreeEnabledOnButtonClick() { return false; } } ---------------------------------------------------------------------------- ====== Minimize windowhandler.html streaming It's possible to reduce the windowhandler.html streaming if we overwrite the onclick event of all links to mark the next request as 'valid'. The onclick handler appends a request token to the URL and creates a cookie for the request token. You can enable this via: [source,java] ---------------------------------------------------------------------------- @Specializes public class MyClientWindowConfig extends DefaultClientWindowConfig { @Override public String isClientWindowTokenizedRedirectEnabled() { return true; } } ---------------------------------------------------------------------------- ==== LAZY Always appends the windowId to all, from JSF generated, URLs. On the first GET request without a windowId, it will generate a new windowId and redirect, with the windowId in the URL, to the same view again. The current windowId will be stored in the `window.name` variable on the client side. For all further requests, a lazy check will be performed to check if the windowId in the URL is matching with the `window.name`. If it is not matching, the view will be refreshed with the right windowId in the URL. ===== Advantage * No windowhandler.html / loading screen required ===== Disadvantage * It could happen that 2 tabs will share the same windowId for 1 request because the `LAZY` mode will check lazily, after rendering the view, if the windowId matches the `window.name`. Therefore it could happen that scopes, which are based on the window handling (@ViewAccessScoped, @WindowScoped and @GroupedConversationScoped), will unintentionally be destroyed. ===== Workflow Example First GET request with windowId * Renders the view * Stores the windowId as `window.name` on the client side First GET request without windowId * Redirect to the same view with a new windowId in the URL * Renders the view * Stores the windowId as `window.name` on the client side Further GET request with windowId * Renders the view * Checks if the requested windowId matches the `window.name` * If it does not match, reload the URL with the right windowId taken from `window.name` Further GET request without windowId * Redirect to the same view with a new windowId in the URL * Renders the view * If it does not match, reload the URL with the right windowId taken from `window.name` ==== NONE Any window or browser tab detection will be disabled for the current request. Scopes like @WindowScoped, @GroupedConversationScoped or @ViewAccessScoped will not work. This is also the default mode if the current request does not support Javascript or if the user agent is a bot/crawler. ==== DELEGATED Delegates the complete window handling to the new JSF 2.2 ClientWindow (if not disabled). ==== CUSTOM Enables to use an complete own `org.apache.deltaspike.jsf.spi.scope.window.ClientWindow` implementation. === Configuration ==== ds:windowId The component `ds:windowId` (`xmlns:ds="http://deltaspike.apache.org/jsf"`) is required to enable the full control of the DeltaSpike window handling. It will import and render the required script parts for both `LAZY` and `CLIENTWINDOW` mode. The best way, to apply it for all views, is to add this component to all of your templates. ==== ds:disableClientWindow Similiar to JSF 2.2' `disableClientWindow` attribute, `ds:disableClientWindow` provides the ability to disable the rendering of the windowId to all links of all child components: [source,xml] ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ==== Number of Active Windows By default, DeltaSpike allows `1024` active windows per session. Anyway, this number is reduced inside this JSF module to `64` for JSF applications. Once that the limit number of active windows is reached, DeltaSpike will drop the oldest active window. You can change the default value by setting the property `deltaspike.scope.window.max-count` using <>. You can also provide this value via: [source,java] ----------------------------------------------------------------------------------- @Specializes public class MyClientWindowConfig extends DefaultClientWindowConfig { @Override public int getMaxWindowContextCount() { // return the max active windows per session } } ----------------------------------------------------------------------------------- ==== Switch Mode To switch the mode, just provide a `org.apache.deltaspike.jsf.api.config.JsfModuleConfig` and overwrite `#getDefaultWindowMode`: [source,java] --------------------------------------------------------------------------- @Specializes public class MyJsfModuleConfig extends JsfModuleConfig { @Override public ClientWindowConfig.ClientWindowRenderMode getDefaultWindowMode() { //... } } --------------------------------------------------------------------------- ==== Provide a Custom ClientWindow If you would like to provide an custom `org.apache.deltaspike.jsf.spi.scope.window.ClientWindow` implementation, you can just do it, for example, via CDI alternatives: [source,java] --------------------------------------------------- @ApplicationScoped public class MyClientWindow implements ClientWindow { //... } --------------------------------------------------- Do not forget to set the `ClientWindowRenderMode` to 'CUSTOM' via the `JsfModuleConfig`: [source,java] --------------------------------------------------------------------------- @Specializes public class MyJsfModuleConfig extends JsfModuleConfig { @Override public ClientWindowConfig.ClientWindowRenderMode getDefaultWindowMode() { return ClientWindowConfig.ClientWindowRenderMode.CUSTOM; } } --------------------------------------------------------------------------- === Based Scopes * @WindowScoped * @ViewAccessScoped * @GroupedConversationScoped == Scopes === @WindowScoped The window-scope is like a session per window. That means that the data is bound to a window/tab and it not shared between windows (like the session scope does). Usually you need the window-scope instead of the session-scope. There areis not a lot of use-cases which need shared data between windows. [source,java] ---------------------------------------------------- @WindowScoped public class PreferencesBean implements Serializable { //... } ---------------------------------------------------- === @ViewAccessScoped In case of conversations you have to un-scope beans manually (or they will be terminated automatically after a timeout). However, sometimes you need beans with a lifetime which is as long as needed and as short as possible - which are terminated automatically (as soon as possible). In such an use-case you can use this scope. The simple rule is, as long as the bean is referenced by a page - the bean will be available for the next page (if it is used again the bean will be forwarded again). It is important that it is based on the view-id of a page (it is not based on the request) so, for example, Ajax requests do not trigger a cleanup if the request does not access all view-access scoped beans of the page. That's also the reason for the name @__View__AccessScoped. [source,java] ----------------------------------------------- @ViewAccessScoped public class WizardBean implements Serializable { //... } ----------------------------------------------- TIP: @ViewAccessScoped beans are best used in conjunction with the `CLIENTWINDOW` window handling, which ensures a clean browser-tab separation without touching the old windowId. Otherwise a 'open in new tab' on a page with a @ViewAccessScoped bean might cause the termination (and re-initialization) of that bean. === @GroupedConversationScoped See (Grouped-)Conversations === @ViewScoped DeltaSpike provides an CDI context for the JSF 2.0/2.1 @javax.faces.bean.ViewScoped. You can simply annotate your bean with @javax.faces.bean.ViewScoped and @Named. === JSF 2.0 Scopes JSF 2.0 introduced new annotations as well as a new scope - the View Scope. DeltaSpike allows to use all the CDI mechanisms in beans annotated with: * javax.faces.bean.ApplicationScoped * javax.faces.bean.SessionScoped * javax.faces.bean.RequestScoped * javax.faces.bean.ViewScoped Furthermore, the managed-bean annotation (javax.faces.bean.ManagedBean) is mapped to @Named from CDI. All these annotations are mapped automatically. So you will not face issues, if you import a JSF 2 annotation instead of the corresponding CDI annotation. == Integration with DeltaSpike Type-safe Messages You can use <> with JSF to provide i18n messages and test to an JSF appplicaton. JSF module is also capable to use messages provided through in faces-config.xml file. The element allows you to override JSF default messages (Section 2.5.2.4 of the JSF specification contains the list of all JSF default messages that could be override.). DeltaSpike can also reuse the same file to provide type-safe messages so you do not have to use the naming convention nor `@MessageContextConfig`. If there is a config for supported locales it will be checked as well and fallback to the configured default locale. .Example [source,java] ------------------------------------------------------------------------------------------------------------ @MessageBundle public interface SimpleMessage { @MessageTemplate("{welcome_to_deltaspike}") String welcomeToDeltaSpike(); } @Model public class PageBean { @Inject private SimpleMessage messages; public void actionMethod(){ FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(messages.welcomeToDeltaSpike())); } } org.apache.deltaspike.example.message.SimpleMessage -> org/apache/deltaspike/example/message/SimpleMessage.properties org/apache/deltaspike/example/message/SimpleMessage.properties org/apache/deltaspike/example/message/SimpleMessage_en.properties org/apache/deltaspike/example/message/SimpleMessage_de.properties ... //content (as usual in message bundle files): welcome_to_deltaspike=Welcome to DeltaSpike //Overrided JSF messages javax.faces.component.UIInput.REQUIRED = {0}: Please enter a value ------------------------------------------------------------------------------------------------------------ .Faces-config.xml File [source,xml] -------------------------------------------------------------------------------------------- org.apache.deltaspike.example.message.SimpleMessage -------------------------------------------------------------------------------------------- == Type-safe View-Configs === Intro Type-safe view-configs are static configs which can be used in combination with every view-technology which is based on Java. Currently DeltaSpike itself provides an integration for JSF, however, the basic concepts are independent of it. (Since DeltaSpike provides the default integration only for JSF, the whole documentation for view-configs is located here.) Thanks to features like multiple (meta-data-)inheritance via interfaces, it provides a powerful approach to bind meta-data to one or multiple views. In case of the JSF integration it is possible to provide, for example, type-safe meta-data for security, navigation, callbacks for view-controllers. Beyond configuring view (/pages) via this concept, it is also possible to use the (view-)config classes for type-safe navigation. Since it is standard Java, you can benefit from any Java-IDE and you do not need special IDE-Addons to use it efficiently. Even the concepts provided by modules (of DeltaSpike itself) are based on the basic API provided by the Core. So it is possible to introduce custom concepts the same way DeltaSpike itself does. === Motivation Instead of learning the concepts and rules of view-configs provided by DeltaSpike, it might be easier for simple demos to just type some simple(r) strings. So why should you use something which is slightly more work **initially**? *The short answer is:* It gives a good return in case of real applications (especially beyond simple demos). *The long answer is:* You can benefit from it from the first second: * It is type-safe ** the Java compiler ensures that you do not have typos at the final usages (and the rest can be checked during bootstrapping of the application) ** you can benefit from the auto.complete features of any modern Java IDE. * If you change the name of a file/folder, you need only one (easy) code-change in a single place and your (standard Java-) IDE will do the rest for you (= update all usages) without a special plug-in * It is possible to restrict the navigation target -> you can ensure that the navigation target is still the intended one (e.g. after a refactoring) * You can configure meta-data in a central place (which can get inherited via *multiple* inheritance based on Java interfaces) * Easier for developers to find usages * Allows easy(er) refactorings and maintenance * You can use your IDE more efficiently especially in large projects (there are some users who initially switched to it, because their tools for displaying the config they had before open large config files very slowly...) * Modern Java IDEs show inheritance of interfaces and classes in a nice way. Since the view-config is based on standard classes and interfaces, you can benefit from it easily. Advantages which are planned for later (= currently not supported): * It is possible to check if the configured folders and files really exist during/after the bootstrapping phase of the application (currently it is not implemented, but it is possible to do it). * It is also easy(er) for tools (IDE plugins,...) to validate it * It is possible to validate the config (if the corresponding path (view or folder) really exists (after v0.5 it is done out-of-the-box) If you are still not convinced, you just have to try it. You will see how your daily workflow benefits from it pretty soon. === Bean-discovery-mode Annotated CDI 1.1 introduced a concept called bean-discovery-mode. If you would like to use the mode `annotated`, please have a look at the tip at @ViewConfigRoot === Basic API Usages While reading this section keep the following simple rules in mind: Meta-data gets inherited along the path of Java inheritance File-/Folder- paths are build based on nesting classes and interfaces Usually users do not need to be aware of all descriptors, SPIs,... which are described by this documentation. There are a lot of possibilities to configure views and some of them are optional. The following examples show some of them in combination with features provided by the JSF- and Security-Module of DeltaSpike. The following example shows the minimal syntax for providing a config for a view (/page). [source,java] ----------------------------------------- public class MyPage implements ViewConfig { } ----------------------------------------- Since it is a class (and not an interface), it is automatically recognized as config for a page (and not a folder) and the default settings get applied during bootstrapping. In case of JSF you can use it for navigation, for example, via action-methods. [source,java] ----------------------------------------------- public Class toNextPage() { return MyPage.class; } ----------------------------------------------- This leads to a forward to `/myPage.xhtml`. Information like base-path, file- (and folder-)name/s, file-extension, navigation mode, view-params,... can be customized with the corresponding (meta-data-)annotations. One of those annotations provided by the JSF module (which is optional) is `@View`. That means the following example leads to the same as the first one. [source,java] ----------------------------------------- @View //optional public class MyPage implements ViewConfig { } ----------------------------------------- But it is also possible to reflect the folder structure via nesting of interfaces and classes. An example for it is: [source,java] ------------------------------------------ public interface Pages { class Index implements ViewConfig { } interface AdminArea extends ViewConfig { class Index implements Admin { } } } ------------------------------------------ In case of the JSF integration it leads to the following view-ids: /pages/index.xhtml /pages/adminArea/index.xhtml Like the optional `@View` for pages represented by the classes, it is possible to use the optional `@Folder` annotation for directories represented by the (nested) interfaces. Furthermore, it is possible to inherit meta-data along with the normal inheritance. In the following example `Pages.Admin.Index`, `Pages.Admin.Home` and `Pages.Admin.Statistics.Home` inherit the meta-data from `Pages.Admin` because they implement the interface whereas `Pages.Admin.Statistics.Index` does not. However, `Pages.Admin.Home` overrides `View#navigation`. During the bootstrapping process the meta-data gets merged and at runtime you only see the final result (which is cached). [source,java] ------------------------------------------------------ public interface Pages { @View(name = "home", extension = JSP) class Index implements ViewConfig { } @View(navigation = REDIRECT, viewParams = INCLUDE) interface Admin extends ViewConfig { interface Statistics { @View //optional class Index implements ViewConfig { } class Home implements Admin { } } class Index implements Admin { } @View(navigation = FORWARD) class Home implements Admin { } } } ------------------------------------------------------ In this case `Pages.Admin.Statistics` is just an interface to reflect the folder structure. For sure it is also possible that it extends an existing view-config interface and other folders and/or pages inherit its meta-data (like `Pages.Admin`). Furthermore, inheritance can be used to ensure navigation to the correct area in the application. In the following example the return type of the action-method (and therefore the compiler of Java) ensures that the navigation target of this method is within the admin-area. [source,java] ------------------------------------------------ public Class toNextPage() { return Pages.Admin.Index.class; } ------------------------------------------------ ==== File (@View) and Folder (@Folder) Paths `@View` as well as `@Folder` are optional annotations. `@Folder` is only needed for using a different folder-name or for marking folder configs if they do not inherit from `org.apache.deltaspike.core.api.config.view.ViewConfig` *nor* have a view-config for a page nested into them (like Pages.Wizard1.Step1). If it is not used explicitly, it gets added automatically (so you can query the meta-data at runtime even in cases you haveis not placed the annotations explicitly). `@View` allows to customize a bit more and it also gets added automatically if it is not used explicitly. Whereas `@Folder` gets added to all nested interfaces (above a view-config class - like Pages and Pages.Wizard1), `@View` only gets added to classes which in-/directly inherit from `org.apache.deltaspike.core.api.config.view.ViewConfig` (like Pages.Wizard1.Step1). That means at runtime the following two configs lead to the same. [source,java] --------------------------------------------- public interface Pages { interface Wizard1 { class Step1 implements ViewConfig { } } } //leads to the same as @Folder public interface Pages { @Folder interface Wizard1 { @View class Step1 implements ViewConfig { } } } --------------------------------------------- The example above leads to the following paths: * /pages/ * /pages/wizard1 * /pages/wizard1/step1.xhtml To customize it you can use `@Folder#name`, `@View#basePath`, `@View#name` and `@View#extension` (or you register custom `NameBuilder`s inline or globally). ===== @Folder#name The rules are pretty simple. You will get what you write. There are only two additional features: * You do not have to care about duplicated '/' (e.g. /folder1//folder2/step1.xhtml would get corrected auto. to /folder1/folder2/step1.xhtml) * With "." at the beginning (e.g. "./") you can keep the path before. The following example [source,java] --------------------------------------------------------------------------------- interface Pages { @Folder(name = "/w1/") interface Wizard1 { class Step1 implements ViewConfig { } } @Folder(name = "./w2/") interface Wizard2 extends ViewConfig { class Step1 implements Wizard2 { } //ViewConfig is inherited indirectly } } --------------------------------------------------------------------------------- leads to the following paths: * /pages/ * /w1/ * /w1/step1.xhtml * /pages/w2/step1.xhtml ===== @View The same naming rules apply to `@View#basePath`. However, it is only valid to be used at view-config nodes which represent pages (-> classes and not interfaces). On interfaces always use `@Folder` (`@View#basePath` will get ignored there). [source,java] --------------------------------------------- interface Pages { interface Wizard1 { @View //optional class Step1 implements ViewConfig { } @View(basePath = "/") class Step2 implements ViewConfig { } @View(basePath = "./") //or just "." class Step3 implements ViewConfig { } @View(basePath = "/w1/") class Step4 implements ViewConfig { } @View(basePath = "./w1/") class Step5 implements ViewConfig { } } } --------------------------------------------- leads to the following paths: * /pages * /pages/wizard1/ * /pages/wizard1/step1.xhtml * /step2.xhtml * /pages/wizard1/step3.xhtml * /w1/step4.xhtml * /pages/wizard/w1/step5.xhtml and depending on additional meta-data you would like to inherit (e.g. `@View(navigation = REDIRECT)`), you can also use: [source,java] ------------------------------------------ @View(navigation = REDIRECT) interface Pages extends ViewConfig { interface Wizard1 extends Pages { @View class Step1 implements Wizard1 { } @View(basePath = "/") class Step2 implements Wizard1 { } @View(basePath = "./") class Step3 implements Wizard1 { } @View(basePath = "/w1/") class Step4 implements Wizard1 { } @View(basePath = "./w1/") class Step5 implements Wizard1 { } } } ------------------------------------------ It leads to the same paths, but in addition `@View#navigation` gets inherited along the inheritance path. ==== Navigation Parameters Since the view-config is static, an approach to add parameters is needed. The following part shows different possibilities to add parameters which end up in the final URL after '?' (in case of the integration with JSF). It is not needed to add all (types of) parameters that way. Some get added automatically based on special meta-data (e.g. `@View#navigation` and `@View#viewParams`). Instead of adding `"faces-redirect=true"` manually it is done for you as soon as you are using `@View(navigation = REDIRECT)`. The same goes for `"includeViewParams=true"` and `@View(viewParams = INCLUDE)`. ==== Static Configuration via @NavigationParameter In some cases, it is needed to add an information in any case. So you can annotate the view-config class with `@NavigationParameter`. Supported values are static strings or EL-expressions. [source,java] --------------------------------------------------------------------------- public interface Pages extends ViewConfig { @NavigationParameter(key = "param1", value = "staticValue1") class Index implements Pages { } @NavigationParameter.List({ @NavigationParameter(key = "param1", value = "staticValue1"), @NavigationParameter(key = "param2", value = "#{myBean.property1}") }) class Overview implements Pages { } } --------------------------------------------------------------------------- Instead of using parameters in any case, it is also possible to configure them statically for particular methods: [source,java] ----------------------------------------------------------------------- @Model public class PageBean { @NavigationParameter(key = "param2", value = "#{myBean.property1}") public Class actionMethod1() { return SimplePageConfig.class; } @NavigationParameter.List({ @NavigationParameter(key = "param1", value = "staticValue1"), @NavigationParameter(key = "param2", value = "staticValue2") }) public Class actionMethod2() { return SimplePageConfig.class; } } ----------------------------------------------------------------------- ===== Dynamic Configuration via NavigationParameterContext Instead of using parameters in a static fashion (as shown above), it is also possible to add them dynamically (e.g. in case of special conditions). [source,java] -------------------------------------------------------------------------------------- @Named @SessionScoped public class PageBean { private int currentValue = -10; @Inject private NavigationParameterContext navigationParameterContext; public Class actionMethod() { currentValue++; if (currentValue >= 0) { this.navigationParameterContext.addPageParameter("cv", this.currentValue); } return SimplePageConfig.class; } } -------------------------------------------------------------------------------------- ==== Security Integration via @Secured This annotation is a custom view-meta-data provided by the Security-module which allows to integrate third-party frameworks (or custom approaches) to secure pages as well as whole folders. You can annotate specific parts or a marker-interface. `CustomAccessDecisionVoter` used in the following example can be any implementation of `org.apache.deltaspike.security.api.authorization.AccessDecisionVoter` and needs to be a standard CDI bean which means you can use dependecy-injection to trigger any kind of security check. All parts which inherit from `SecuredPages` (`Pages.Admin`, `Pages.Admin.Index` and `Pages.Admin.Home`) are protected by `CustomAccessDecisionVoter`. (It is easy to check this hierarchy in a modern Java-IDE. Only for displaying the final meta-data for every node in the IDE a special plug-in would be needed.) [source,java] ----------------------------------------------- @Secured(CustomAccessDecisionVoter.class) public interface SecuredPages {} @View(navigation = REDIRECT) public interface Pages extends ViewConfig { class Index implements Pages { } interface Admin extends Pages, SecuredPages { class Index implements Admin { } @View(navigation = FORWARD) class Home implements Admin { } } } ----------------------------------------------- For sure it is also possible to use it without a special interface. In this case you would need: [source,java] --------------------------------------------- @View(navigation = REDIRECT) public interface Pages extends ViewConfig { class Index implements Pages { } @Secured(CustomAccessDecisionVoter.class) interface Admin extends Pages { class Index implements Admin { } @View(navigation = FORWARD) class Home implements Admin { } } } --------------------------------------------- or: [source,java] ------------------------------------------------- @View(navigation = REDIRECT) public interface Pages extends ViewConfig { class Index implements Pages { } interface Admin extends Pages { @Secured(CustomAccessDecisionVoter.class) class Index implements Admin { } @Secured(CustomAccessDecisionVoter.class) @View(navigation = FORWARD) class Home implements Admin { } } } ------------------------------------------------- ==== View-Controller Callbacks via @ViewControllerRef This annotation is a custom view-meta-data provided by the JSF-module which allows to configure beans which should act as view-controllers. That means they can use view-controller callbacks like `@InitView`, `@PreViewAction`, `@PreRenderView` and `@PostRenderView`. The following example shows the usage of `@PreRenderView`. [source,java] ------------------------------------------ //@View //optional @ViewControllerRef(MyPageController.class) public class MyPage implements ViewConfig { } @Model public class MyPageController { @PreRenderView protected void load() { //... } } ------------------------------------------ From DeltaSpike 0.7, it is possible to observe exceptions thrown by a @PreRenderView callback and use your configured Default-Error-View to display the exception. .Example [source,java] -------------------------------------------------------------------------------------------------------------- @ExceptionHandler public class ErrorViewAwareExceptionHandler { @Inject private ViewConfigResolver viewConfigResolver; public void onIllegalStateException(@Handles ExceptionEvent e) { FacesContext facesContext = FacesContext.getCurrentInstance(); String viewId = viewConfigResolver.getDefaultErrorViewConfigDescriptor().getViewId(); UIViewRoot viewRoot = facesContext.getApplication().getViewHandler().createView(facesContext, viewId); facesContext.setViewRoot(viewRoot); //... - e.g.: store the exception in a page-bean for the default-error-view } } -------------------------------------------------------------------------------------------------------------- ==== Referencing Views via @ViewRef With `@ViewControllerRef#value` you can annotate a view-config class to bind (/reference) a controller to it. `@ViewRef#config` allows the same in the other direction. Use an existing view-config to reference one or many view/s. .Example [source,java] ---------------------------------------------------- public interface Pages extends ViewConfig { class Index implements Pages { } } @ViewRef(Pages.Index.class) //... public class IndexController implements Serializable { @PreRenderView protected void preRenderView() { //... } //... } ---------------------------------------------------- The above example leads to the invocation of the pre-render-view logic before /pages/page1.xhtml gets rendered (and it will not be called for other pages). ==== Using the (Optional) ViewNavigationHandler With JSF you typically navigate with the action-method bound to a command-component. However, also JSF supports manual navigation via `javax.faces.application.NavigationHandler`. With `ViewNavigationHandler` DeltaSpike provides an equivalent optimized for type-safe view-configs which is easier to use (and can be used also for other (supported) view technology). .Simple Example [source,java] ----------------------------------------------------------------- public interface Pages { class Index implements ViewConfig { } } @Model public class AnyController { @Inject private ViewNavigationHandler viewNavigationHandler; public void anyMethod() { //navigates to /pages/index.xhtml this.viewNavigationHandler.navigateTo(Pages.Index.class); } } ----------------------------------------------------------------- Also in this case (optional) meta-data will be used for the navigation process, since `ViewNavigationHandler` just delegates to the active navigation-handler (of JSF). ==== Configuring a Default Error-View It is possible to mark one view-config class as default error-view. That means in case of errors it will be used as navigation target automatically. Furthermore, it is also possible to use it in your code instead of hardcoding your error-view across the whole application. In case of [source,java] ------------------------------------------------------ public interface Pages { class Index implements ViewConfig { } class CustomErrorPage extends DefaultErrorView { } } ------------------------------------------------------ it is possible to navigate with `DefaultErrorView.class` instead of hardcoding it to `Pages.CustomErrorPage.class`. [source,java] ------------------------------------------------------------------------- @Model public class PageController { public Class actionWithoutError() { return Pages.Index.class; } public Class actionWithError() { //navigates to the view which is configured as default error-view return DefaultErrorView.class; } } ------------------------------------------------------------------------- If you are outside of an action-method you can also use it in combination with `ViewNavigationHandler`. [source,java] ------------------------------------------------------------------------- @Model public class AnyController { @Inject private ViewNavigationHandler viewNavigationHandler; public void anyMethod() { //navigates to the view which is configured as default error-view this.viewNavigationHandler.navigateTo(DefaultErrorView.class); } } ------------------------------------------------------------------------- However, in case of JSF you have to ensure that you are at a valid point in the JSF request-lifecycle for a navigation, because invocation gets transformed to a standard (implicit) JSF navigation. ==== Using ViewConfigResolver If you would like to query view-meta-data yourself (for whatever reason), you can do that with `ViewConfigResolver`. [source,java] ---------------------------------------------------------------------------------------------------------------------------------------- @RequestScoped public class ApiDemoBean { @Inject private ViewConfigResolver viewConfigResolver; public String getViewId(Class viewConfigClass) { return viewConfigResolver.getViewConfigDescriptor(viewConfigClass).getViewId(); //or #getPath } public String getPath(Class pathConfigClass) { return viewConfigResolver.getConfigDescriptor(pathConfigClass).getPath(); } public List> getAllFolderDescriptors() { return viewConfigResolver.getConfigDescriptors(); } public List getAllPageDescriptors() { return viewConfigResolver.getViewConfigDescriptors(); } public ViewConfigDescriptor getCurrentViewConfig() { return viewConfigResolver.getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId()); } public Class getCurrentViewConfigClass() { return viewConfigResolver.getViewConfigDescriptor(FacesContext.getCurrentInstance().getViewRoot().getViewId()).getConfigClass(); } //... } ---------------------------------------------------------------------------------------------------------------------------------------- For folders it is optional to implement the `ViewConfig` interface, therefore you see 2 different types of API. `#getConfigDescriptor` as the general API and `#getViewConfigDescriptor` which is specific for pages (which have to implement the `ViewConfig` interface). *Besides* translating a config class to the final path of the folder or page, it is possible to get the implicitly as well as explicitly configured (view-)meta-data and get and/or execute configured callbacks. === Advanced API Usages ==== Creating Custom Meta-Data via @ViewMetaData This meta-annotation allows to create custom view-meta-data which can be used for view-configs. By default meta-data of a lower level overrides meta-data on a higher level which has the same type. That can be customized via annotating the final annotation as a whole via `@Aggregated(true)`. [source,java] ------------------- @ViewMetaData @interface InfoPage { } ------------------- By just using `@InfoPage` in view-configs, it can be queried via: [source,java] ---------------------------------------------------------------------------------------------------------- @Inject private ViewConfigResolver viewConfigResolver; //... ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Index.class); List metaDataList = viewConfigDescriptor.getMetaData(InfoPage.class) ---------------------------------------------------------------------------------------------------------- ==== Creating Custom Meta-Data via @Stereotype Like with CDI itself you can encapsulate multiple view meta-data annotation in one annotation. .Example [source,java] ------------------------------------------------------------- @Target({TYPE}) @Retention(RUNTIME) @Stereotype @Secured(CustomAccessDecisionVoter.class) //view meta-data #1 @View(navigation = REDIRECT) //view meta-data #2 @interface MySecuredView {} ------------------------------------------------------------- Instead of using the same combination of annotations in multiple places, you can use the stereotype annotation. If you query the meta-data at runtime (see `ViewConfigDescriptor#getMetaData`), you can access `@Secured` as well as `@View` (in the example above). however, you will not see `@MySecuredView` itself at runtime, because stereotype annotations are by default transparent. From DeltaSpike 1.0.1, it is possible to access such stereotype annotations as well, once you annotate them with `@ViewMetaData`. ==== Creating Custom Callbacks via @ViewMetaData Via a custom ConfigPreProcessor it is possible to register custom callbacks dynamically. The following listing shows a view-config which adds a simple callback including the corresponding `ConfigPreProcessor` and `ExecutableCallbackDescriptor`. [source,java] ---------------------------------------------------------------------------------------------------------- @ViewMetaData(preProcessor = MySecured.AnnotationPreProcessor.class) public @interface MySecured { Class[] value(); class AnnotationPreProcessor implements ConfigPreProcessor { @Override public MySecured beforeAddToConfig(MySecured metaData, ViewConfigNode viewConfigNode) { List descriptors = viewConfigNode.getCallbackDescriptors(MySecured.class); descriptors.add(new Descriptor(metaData.value(), DefaultCallback.class)); return metaData; } } static class Descriptor extends ExecutableCallbackDescriptor> { public Descriptor(Class[] beanClasses, Class callbackMarker) { super(beanClasses, callbackMarker); } public List> execute(String param1, String param2) { return super.execute(param1, param2); } } } ---------------------------------------------------------------------------------------------------------- By just using `@MySecured` in view-configs, it can be queried and executed via: [source,java] ------------------------------------------------------------------------------------------------------------------ @Inject private ViewConfigResolver viewConfigResolver; //... ViewConfigDescriptor viewConfigDescriptor = viewConfigResolver.getViewConfigDescriptor(Pages.Secured.Index.class); List /*return type of one callback*/> callbackResult = viewConfigDescriptor.getExecutableCallbackDescriptor(MySecured.class, MySecured.Descriptor.class) .execute("param1", "param2"); ------------------------------------------------------------------------------------------------------------------ It is also possible do register different callback-types per view-meta-data. An example can be found at `ViewControllerRef` which registers different callback-types for `InitView`, `PreViewAction`, `PreRenderView` and `PostRenderView`. In this case it is needed to use the type of the callback (= class of the annotation) as additional parameter for `#getExecutableCallbackDescriptor`. ==== Creating Custom inline Meta-Data via @InlineViewMetaData This annotation can be used for view-meta-data which can be placed on other classes than view-config-classes. It is used, for example, for `@ViewRef`. Via a `TargetViewConfigProvider` it is possible to point to the view-config the meta-data should get applied to and via `InlineMetaDataTransformer` it is possible to convert it to a different meta-data-representation (which allows that at runtime you only have to support one side since the inline-meta-data was converted to the same meta-data representation which is used for the normal view-meta-data). === Path-Validation DeltaSpike (after v0.5) validates your configs out-of-the-box. The application will fail to start, if there is an invalid config (e.g. a view-config without a corresponding view). Right now the validation is restricted to folders and view-ids with .xhtml or .jsp as suffix. Other view-ids (e.g. *.faces) do not get checked. In such cases a custom validator can be used (e.g. based on `ViewConfigPathValidator`). To disable the view-config (path) validation, add a `ClassDeactivator` which restricts `org.apache.deltaspike.jsf.impl.config.view.ViewConfigPathValidator`. === View-Config SPI ==== ConfigDescriptorValidator Allows to validate the final view-config descriptors before they get deployed. Since the config-descriptor contains, for example, the final path, it is also possible to validate if the corresponding file exists. Use `@ViewConfigRoot` to configure 1-n validators. ==== ConfigNodeConverter Allows to provide custom strategies to process the nodes of the built config-tree. Use `@ViewConfigRoot` to configure a custom converter. ==== ConfigPreProcessor Allows to change the found meta-data (e.g. replace default values, callbacks,...) or the `ViewConfigNode` itself. ==== InlineMetaDataTransformer Allows to transform an annotation annotated with `@InlineViewMetaData` to an annotation annotated with `@ViewMetaData`. This transformer is optional and only needed if it should result in the same at runtime, but the inline-meta-data needs a different syntax via a different annotation (compared to the view-config meta-data). See for example `@ViewRef` vs. `@ViewControllerRef`. ==== TargetViewConfigProvider Allows to provide a custom reference to `ViewConfig` classes (see for example `@InlineViewMetaData` and `@ViewRef`) ==== ViewConfigInheritanceStrategy Allows to customize the inheritance-strategy for meta-data. For example, inheritance via standard java inheritance vs. inheritance via nested interfaces. Use `@ViewConfigRoot` to configure a custom inheritance-strategy. ==== ViewConfigNode Node-type used for building the meta-data-tree during the bootstrapping process. ==== @ViewConfigRoot Optional annotation which allows to provide custom implementations. Only annotate one `ViewConfig` class which represents the root node. If you are using CDI 1.1+ with bean-discovery-mode `annotated`, you can use `@ViewConfigRoot` in combination with `@ApplicationScoped` as marker annotations. From DeltaSpike 1.0.1, this combination allows to add all nested interfaces and classes and therefore no additional annotations (required by bean-discovery-mode `annotated`) are needed. Minimal example: [source,java] ----------------------------------------- @ApplicationScoped @ViewConfigRoot public interface Pages extends ViewConfig { class Index implements Pages { } } ----------------------------------------- === Activation of Custom Naming Conventions DeltaSpike allows to customize the default naming convention via `View.DefaultBasePathBuilder` and/or `View.DefaultFileNameBuilder` and/or `View.DefaultExtensionBuilder`. It is possible to change it for one usage via `View.basePathBuilder` and/or `View.fileNameBuilder` and/or `View.extensionBuilder` or globally via the config mechanism provided by DeltaSpike. The same is supported for folders via `Folder.DefaultFolderNameBuilder`. In this case changing only one usage is possible via `Folder.folderNameBuilder`. == (Grouped-)Conversations DeltaSpike conversations are based on the window-scope. Therefore, do not forget to add the `ds:windowId` (`xmlns:ds="http://deltaspike.apache.org/jsf"`) component in case of `ClientWindowConfig#CLIENTWINDOW` to your page(/template) and ensure that the window-handling works properly (otherwise conversations will not work correctly). The base principle is similar to CODI-Conversations. CODI users just have to ensure that they have to add `ds:windowId` and the names are slightly different. First of all, it is important to mention that DeltaSpike starts (grouped) conversations automatically as soon as you access conversation scoped beans. Furthermore, the invocation of `GroupedConversation#close` leads to an immediate termination of the conversation. [source,java] ---------------------------------------------- @GroupedConversationScoped public class DemoBean1 implements Serializable { //... } ---------------------------------------------- ... leads to a conversation which contains just one bean with the group DemoBean1. TIP: If you would like to use the bean within your JSF pages, you have to add `@Named` (jakarta.inject.Named ). (In case of CDI standard conversations there is just one big conversation which contains all conversation scoped beans.) The grouped conversations provided by DeltaSpike are completely different. By default every conversation scoped bean exists in an "isolated" conversation. That means there are several parallel conversations within the same window. .Separated DeltaSpike Conversations [source,java] ---------------------------------------------- @GroupedConversationScoped public class DemoBean2 implements Serializable { //... } @GroupedConversationScoped public class DemoBean3 implements Serializable { //... } ---------------------------------------------- The above example leads to two independent conversations in the same window (context). If you close the conversation of DemoBean2, the conversation of DemoBean3 is still active. If you have an use-case (e.g. a wizard) which uses multiple beans which are linked together very tightly, you can create a type-safe conversation group. .Grouped Conversation Scoped Beans [source,java] ---------------------------------------------- interface Wizard1 {} @GroupedConversationScoped @ConversationGroup(Wizard1.class) public class DemoBean4 implements Serializable { //... } @GroupedConversationScoped @ConversationGroup(Wizard1.class) public class DemoBean5 implements Serializable { //... } ---------------------------------------------- You can use `@ConversationGroup` to tell DeltaSpike that there is a logical group of beans. Technically `@ConversationGroup` is just a CDI qualifier. Internally DeltaSpike uses this information to identify a conversation. In the previous example both beans exist in the same conversation (group). If you terminate the conversation group, both beans will be destroyed. If you do not use `@ConversationGroup` explicitly, DeltaSpike uses the class of the bean as conversation group. .Injecting a Conversation Scoped Bean with an Explicit Group [source,java] ------------------------------------ //... public class CustomBean1 { @Inject @ConversationGroup(Group1.class) private CustomBean2 demoBean; @Inject @ConversationGroup(Group2.class) private CustomBean2 demoBean; } ------------------------------------ Since `@ConversationGroup` is a standard CDI qualifier you have to use it at the injection point. You have to do that especially because it is possible to create beans of the same type which exist in different groups (e.g. via producer methods). .Producer Methods which Produce Conversation Scoped Beans with Different Groups [source,java] ------------------------------------------------ interface Group1 {} interface Group2 {} public class CustomBean2 { @Produces @GroupedConversationScoped @ConversationGroup(Group1.class) public CustomBean2 createInstanceForGroup1() { return new CustomBean2(); } @Produces @GroupedConversationScoped @ConversationGroup(Group2.class) public CustomBean2 createInstanceForGroup2() { return new CustomBean2(); } } ------------------------------------------------ === Terminating Conversations You can inject the conversation via `@Inject` and use it to terminate the conversation immediately or you inject the `GroupedConversationManager` which can be used to terminate a given conversation (group). All conversations within a window are closed automatically, once `WindowContext#closeWindow` gets called for the window. .Injecting and Using the Current Conversation [source,java] -------------------------------------------------------------------------------------------------------------------- @GroupedConversationScoped public class DemoBean6 implements Serializable { @Inject private GroupedConversation conversation; //injects the conversation of DemoBean6 (!= conversation of DemoBean7) //... public void finish() { this.conversation.close(); } } @GroupedConversationScoped public class DemoBean7 implements Serializable { @Inject private GroupedConversation conversation; //injects the conversation of DemoBean7 (!= conversation of DemoBean6) //... public void finish() { this.conversation.close(); } } -------------------------------------------------------------------------------------------------------------------- .Injecting and Using the Explicitly Grouped Conversation [source,java] ---------------------------------------------------------------------------------------------------------------------- interface Wizard2 {} @GroupedConversationScoped @ConversationGroup(Wizard2.class) public class DemoBean8 implements Serializable { @Inject private GroupedConversation conversation; //injects the conversation of Wizard2 (contains DemoBean8 and DemoBean9) //... public void finish() { this.conversation.close(); } } @GroupedConversationScoped @ConversationGroup(Wizard2.class) public class DemoBean9 implements Serializable { @Inject private GroupedConversation conversation; //injects the conversation of Wizard2 (contains DemoBean8 and DemoBean9) //... public void finish() { this.conversation.close(); } } ---------------------------------------------------------------------------------------------------------------------- .Terminating a Grouped Conversation Outside of the Conversation [source,java] ------------------------------------------------------------------------------------------------------------------------- //... public class DemoBean10 implements Serializable { @Inject private GroupedConversationManager conversationManager; //... public void finish() { this.conversationManager.closeConversationGroup(Wizard2.class); //closes the conversation of group Wizard2.class } } ------------------------------------------------------------------------------------------------------------------------- .Terminate All Conversations [source,java] ------------------------------------------------------------------------------------------------------------------------- //... public class DemoBean11 implements Serializable { @Inject private GroupedConversationManager conversationManager; //... public void finish() { this.conversationManager.closeConversations(); //closes all existing conversations within the current window (context) } } ------------------------------------------------------------------------------------------------------------------------- TIP: DeltaSpike conversations get closed/restarted immediately instead of keeping them until the end of the request like standard conversations do, because the behaviour of standard conversations breaks a lot of use-cases. However, if you really need to keep them until the end of the request, you can close them in a `@PostRenderView` callback. === Sub-Conversation-Groups Due to the parallel conversation concept of DeltaSpike there is no need of something like nested conversations. Just use them in parallel and terminate them in a fine-granular way as soon as you do not need them any longer. As described above, you can terminate a whole conversation-group. However, sometimes it is essential to have subgroups if you need to end just a part of an use-case instead of all beans related to an use-case. A sub-group is just a class or an interface used to identify a bunch of beans within a group. To terminate such a sub-group, it is just needed to pass the class/interface to the corresponding API for terminating a conversation. The sub-group gets detected automatically and instead of terminating a whole conversation-group, the beans of the sub-group get un-scoped. .Explicitly Listing Beans of a Sub-group [source,java] -------------------------------------------------------------------------------- public class MyGroup{} @GroupedConversationScoped @ConversationGroup(MyGroup.class) public class BeanA {} @GroupedConversationScoped @ConversationGroup(MyGroup.class) public class BeanB {} @GroupedConversationScoped @ConversationGroup(MyGroup.class) public class BeanC {} @ConversationSubGroup(subGroup = {BeanA.class, BeanB.class}) public class MySubGroup extends MyGroup {} //or @ConversationSubGroup(of = MyGroup.class, subGroup = {BeanA.class, BeanB.class}) public class MySubGroup {} -------------------------------------------------------------------------------- .Terminating a Sub-group [source,java] ------------------------------------------------------------------ @Inject private GroupedConversationManager conversationManager; //... this.conversationManager.closeConversationGroup(MySubGroup.class); ------------------------------------------------------------------ As you see the class/interface of the sub-group has to extend/implement the group or you specify it via the `@ConversationSubGroup#of`. With `@ConversationSubGroup#subGroup` you can list all beans which belong to the sub-group. If you have a lot of such beans or you would like to form (sub-)use-case oriented groups, you can use implicit groups: .Implicit Sub-group [source,java] ------------------------------------------------------------------------ public interface Wizard {} @ConversationSubGroup(of = MyGroup.class, subGroup = Wizard.class) public class ImplicitSubGroup { } @Named("myWizard") @GroupedConversationScoped @ConversationGroup(MyGroup.class) public class WizardController implements Serializable, Wizard { //... } this.conversationManager.closeConversationGroup(ImplicitSubGroup.class); ------------------------------------------------------------------------ In the listing above all beans which implement the Wizard interface will be closed as soon as you close the ImplicitSubGroup. == Injection in JSF Artifacts === Converter and Validator Per default the JSF module of DeltaSpike handles JSF converters and validators as std. CDI beans and therefore it's possible to use injection, lifecycle-callbacks, scope-annotations,... the same way as with any other CDI bean. The usage is the same as for `PhaseListener` s. === PhaseListener Once a std. JSF-`PhaseListener` is annotated with `@org.apache.deltaspike.jsf.api.listener.phase.JsfPhaseListener`, that `PhaseListener` gets active without additional config in `faces-config.xml`. Since such `PhaseListener` s are std. CDI beans, it's possible to use injection, lifecycle-callbacks as well as scope-annotations the same way as with any other CDI bean. Furthermore, it's possible to order `PhaseListener` s via `ordinal`. DeltaSpike itself uses it internally e.g. in case of `DoubleSubmitAwarePhaseListener` which looks like: .Example [source,java] ------------------------------------------------------------------------ @JsfPhaseListener(ordinal = 9000) public class DoubleSubmitAwarePhaseListener implements PhaseListener, Deactivatable { @Inject private PostRequestTokenManager postRequestTokenManager; @Override public void beforePhase(PhaseEvent event) { //... } @Override public void afterPhase(PhaseEvent event) { //... } @Override public PhaseId getPhaseId() { return PhaseId.RESTORE_VIEW; } } ------------------------------------------------------------------------ == Event broadcasting === Observe Faces-Requests It is possible to observe JSF-Requests via `@Observes` in combination with `@org.apache.deltaspike.core.api.lifecycle.Initialized` or `@org.apache.deltaspike.core.api.lifecycle.Destroyed` as qualifier for `javax.faces.context.FacesContext`. Such observer-methods look e.g. like: .Example [source,java] ------------------------------------------------------------------------ public void onBeforeFacesRequest(@Observes @Initialized FacesContext facesContext) { //... } public void onAfterFacesRequest(@Observes @Destroyed FacesContext facesContext) { //... } ------------------------------------------------------------------------ === BeforePhase / AfterPhase It is possible to observe JSF request-lifecycle phase-events via `@Observes` in combination with `@org.apache.deltaspike.jsf.api.listener.phase.BeforePhase` or `@org.apache.deltaspike.jsf.api.listener.phase.AfterPhase` as qualifier for `javax.faces.event.PhaseEvent`. Such observer-methods look e.g. like: .Example [source,java] ------------------------------------------------------------------------ public void onPhaseStart(@Observes @BeforePhase(JsfPhaseId.ANY_PHASE) PhaseEvent event) { //... } public void onPhaseEnd(@Observes @AfterPhase(JsfPhaseId.ANY_PHASE) PhaseEvent event) { //... } ------------------------------------------------------------------------ === JSF SystemEvents Following JSF SystemEvents can be observed via CDI: * javax.faces.event.PostConstructApplicationEvent * javax.faces.event.PreDestroyApplicationEvent * javax.faces.event.ExceptionQueuedEvent .Example [source,java] ------------------------------------------------------------------- @ApplicationScoped public class ApplicationConfig { public void init(@Observes PostConstructApplicationEvent event) { // ... } } ------------------------------------------------------------------- == Integration with Exception Control Whenever a unhandled exception occurs within the JSF lifecycle, our JSF ExceptionHandler provides a integration to the DeltaSpike Exception Control. === Examples ==== Basic ----------------------------------------------------------------------------- @ExceptionHandler public class ApplicationExceptionHandler { public void handleELException(@Handles ExceptionEvent event) { // ... // no other JSF ExceptionHandler should handle this exception... event.handled(); } } ----------------------------------------------------------------------------- ==== Redirect [source,java] ----------------------------------------------------------------------------------------------------------------------------------- @ExceptionHandler public class ApplicationExceptionHandler { public void handleELException(@Handles ExceptionEvent event) { FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(...); // or ExternalContext etc. // required - "stops" the JSF lifecycle FacesContext.getCurrentInstance().responseComplete(); // no other JSF ExceptionHandler should handle this exception... event.handled(); } } ----------------------------------------------------------------------------------------------------------------------------------- === Using a Custom Qualifier for JSF Exceptions In some cases, it is required to differentiate exceptions from JSF and normal exceptions. This is possible via a CDI qualifier: [source,java] ----------------------------------------------------------------------------------------------------------------------------------- @Target({ ElementType.TYPE, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @Documented @Qualifier public @interface Jsf { } @Specializes public class MyJsfModuleConfig extends JsfModuleConfig { public Class getExceptionQualifier() { return Jsf.class; } } @ExceptionHandler public class ApplicationExceptionHandler { public void handleELException(@Handles @Jsf ExceptionEvent event) { FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigation(...); // or ExternalContext etc. // required - "stops" the JSF lifecycle FacesContext.getCurrentInstance().responseComplete(); // no other JSF ExceptionHandler should handle this exception... event.handled(); } } ----------------------------------------------------------------------------------------------------------------------------------- == Double-Submit Prevention To avoid that the same content of a form gets submitted and therefore processed multiple times, it is possible to use the tag ``. As usual for DeltaSpike JSF-tags, the `ds` namespace is `http://deltaspike.apache.org/jsf`. Just add this tag within every JSF form-tag, you would like to safeguard. [source,xml] -------------------------------------------------- -------------------------------------------------- == Tips Using errorView, DefaultErrorView or ViewNavigationHandler will fail with Weld versions older than 1.1.10 due to https://issues.jboss.org/browse/WELD-1178[WELD-1178]. ================================================ FILE: documentation/src/main/asciidoc/modules.adoc ================================================ :notoc: = Overview of DeltaSpike Modules :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike consists of ready-to-use modules. These include a core module and a number of optional modules for providing additional enterprise functionality to your applications. An overview of each module is provided here and for more information see the linked individual module pages. [cols="1,3a"] |=== |<> | For fundamental and defining DeltaSpike API and utility classes |<> | For adding CDI support in Bean Validation, enabling creation of CDI aware `ConstraintValidator` methods that can use business objects (EJBs, ManagedBeans) to support validation needs |<> | For CDI container booting and shutdown and associated context lifecycle management |<> | For an enhanced JPA experience with declarative queries, reducing boilerplate to a minimum |<> | For transactional context and scope |<> | For CDI integration with JSF, with type-safe view config, multi-window handling, new scopes (WindowScoped, ViewScope, ViewAccessScoped, GroupedConversationScoped) and integration with DeltaSpike “core” messages and exception handling |<> | For implementing a generic handler to replace manual implementations of interfaces (or abstract classes) |<> | For simple integration with Quartz v2 (default) or any other scheduler that supports cron-expressions for job-classes |<> | For intercept and security checking on method calls |<> | For integration with the Java Servlet API, enabling injection of common servlet objects and propagation of servlet events to the CDI event bus |<> | For writing CDI-based tests easily |=== ================================================ FILE: documentation/src/main/asciidoc/overview.adoc ================================================ = Overview of DeltaSpike :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache DeltaSpike is a collection of portable CDI extensions. These ready-to-use modules enable you to integrate tested API extensions into your Java projects. DeltaSpike consists of a core module and a number of <> for providing additional enterprise functionality to your applications. The modules include features for enhanced security with type-safe control over method invocations, integration with schedulers, injection of CDI objects into validators, a transactional context and scope, and much more. DeltaSpike also provides boot and shutdown control over CDI containers in Java SE applications. As a CDI extension, DeltaSpike must be used in conjunction with a CDI implementation and supports both JBoss Weld and Apache OpenWebBeans. DeltaSpike is tested on a range of application servers and CDI-enabled containers including Apache TomEE, JBoss AS, WildFly, Oracle GlassFish, and Jetty. DeltaSpike provides a number of link:http://deltaspike.apache.org/examples.html[examples] to show you how to use and get the most from this technology. == Features === Java EE 7 without Java EE 7! *Transactional support for non-EJB beans:* The Transactional Interceptor in DeltaSpike paved the way for `@Transactional` in Java EE 7. Although we not only support JTA transactions but also resource local transactions and use a slightly different Exception handling. *Injectable resources:* Configuration, resource bundles,... are easy to inject when using CDI and Apache DeltaSpike. *@Exclude annotation:* Lets you prevent classes from being treated as CDI beans even if they are in a CDI-enabled archive in a Jakarta EE project. You can even exclude classes based on ProjectStages or configuration expressions. *Scheduling tasks*: handle Async processes in a non-JakartaEE environment. *BeanProvider:* Easy Access to the BeanManager and CDI beans even in non-managed classes like JPA 2.0 EntityListeners or Spring Beans. === JSF Improvements *Multi-window handling:* Management of logical windows for batch jobs, browser tab separation in JSF and more. *Type-safe view-config:* Lets you bind metadata (e.g. for security) to views with a flexible type-safe approach. It provides a more solid navigation in case of JSF and helps a lot in the maintenance phase. *View-Controller:* Based on type-safe view-configs, view-controller annotations provide a type-safe alternative to standard tags. *JSF event broadcasting to CDI:* Allows CDI to be notified about JSF events === Productivity Improvements *Security based on annotations:* The foundation for building a robust, capable and non-invasive security solution. *New CDI scopes:* TransactionScoped, WindowScoped, ViewScoped, ViewAccess scope, Grouped conversation scope. *Container Control and Test Control:* Java SE with CDI, all with a unifying API. Start, stop, add classes to a running CDI container. *Data Module:* An out of the box entity framework solution complete with support for container or application managed persistence contexts, as well as JDBC. *JMX integration:* Any CDI bean can be exposed via JMX easily with a single annotation. *Type-safe i18n messages:* Localized messages are easy to use with an interface and a resource bundle, no more boilerplate and your messages now have context within the code. *Type-safe ProjectStages:* Compared to ProjectStages in JSF, DeltaSpike provides a type-safe, but still extensible approach which can be used in CDI-based applications. == Background === CDI Java Contexts and Dependency Injection for the Java EE platform (link:https://jcp.org/en/jsr/detail?id=299[JSR 299]), abbreviated _CDI_ was introduced as part of Java EE 6 and is now part of Jakarta Enterprise. The core features of CDI are as follows: * improved stateful object lifecycles with an additional context named _Conversation_ that encompasses a series of requests within one session and lifecycle management by the container according to well-defined contexts * dependency injection conducted in a type-safe manner, with type checking conducted at compilation time so errors are exposed earlier and debugging is easier * event notification facility for object interaction * a better approach for interceptors with annotations binding interceptors to objects and with a new interceptor named _decorator_ that knows about individual bean attributes through inheritance and is more appropriate for use in solving business problems * a Service Provider Interface (SPI) for developing portable extensions to the CDI container CDI is a link:https://jcp.org/en/home/index[Java Community Process (JCP)] standard. All Java EE 6 compliant application servers must provide support for CDI. link:http://weld.cdi-spec.org/[JBoss Weld] is a reference implementation of the CDI specification and other spec-compliant implementations exist such as link:http://openwebbeans.apache.org/[Apache OpenWebBeans (OWB)]. While CDI is a Java EE 6 essential, CDI can also be used in Java SE environments with the aid of standalone CDI implementations. === Portable CDI Extensions The CDI Service Provider Interface (SPI) is exposed to enable extension of the CDI feature set by third parties. Portable CDI extensions extend CDI implementations and improve existing Java EE APIs by enabling integration of different technologies. As set out in the CDI specification, a portable CDI extension may integrate with a CDI container as follows: * providing its own beans, interceptors and decorators to the container * injecting dependencies into its own objects using the dependency injection service * providing a context implementation for a custom scope * augmenting or overriding the annotation-based metadata with metadata from some other source As indicated by the name, _portable_ CDI extensions can be used with any spec-compliant CDI implementation. == Next For instructions on how to start using DeltaSpike, see <> and <>. ================================================ FILE: documentation/src/main/asciidoc/partial-bean.adoc ================================================ :moduledeps: core, proxy = Partial-Bean Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Partial-Bean module provides means for implementing a generic handler to replace manual implementations of interfaces (or abstract classes). == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === Declare Partial-Bean Module Dependencies Add the Partial-Bean module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-partial-bean-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-partial-bean-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-partial-bean-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-partial-bean-module-api' ---- IMPORTANT: Currently CDI Interceptors applied via @Interceptors, @Intercepted and @Decorator are not supported by our proxies! == @PartialBeanBinding Partial beans allow you to implement a generic handler to replace manual implementations of interfaces (or abstract classes). `@PartialBeanBinding` is the binding-annotation for creating a custom interface (/abstract class) to generic handler binding. [source,java] ------------------------------------------------------------------------------------- @PartialBeanBinding @Retention(RUNTIME) @Target(TYPE) public @interface MyPartialBeanBinding {} ------------------------------------------------------------------------------------- [source,java] ------------------------------------------------------------------------------------- //scope is optional @MyPartialBeanBinding public interface PartialBean { String getValue(); } ------------------------------------------------------------------------------------- [source,java] ------------------------------------------------------------------------------------- //scope is optional @MyPartialBeanBinding public class MyPartialBeanHandler implements java.lang.reflect.InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //generic handler logic } } ------------------------------------------------------------------------------------- ================================================ FILE: documentation/src/main/asciidoc/projectstage.adoc ================================================ = DeltaSpike ProjectStage :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Introduction Project stages allow to use implementations depending on the current environment. For example, you can implement a bean which creates sample-data for system tests which gets activated only in case of ProjectStage `SystemTest`. _Besides custom ProjectStages_ it is possible to use the following pre-defined ProjectStages: * UnitTest * Development * SystemTest * IntegrationTest * Staging * Production The core provides a pluggable and type-safe approach for using project stages in a project (it is also used within the framework). Furthermore, `@Exclude` allows use of, for example, implementations annotated with `jakarta.enterprise.inject.Alternative` for specific ProjectStages. Besides the out-of-the-box ProjectStages it is possible to implement _custom but type-safe_ ProjectStages which will be exposed by DeltaSpike. Resolving and using the ProjectStage: [source,java] ------------------------------------------------------------------------------- @Inject private ProjectStage projectStage; //... boolean isDevProjectStage = ProjectStage.Development.equals(this.projectStage); ------------------------------------------------------------------------------- == Custom Project Stages It is possible to provide custom project stage implementations. Therefore, you have to provide an implementation of the `ProjectStageHolder` interface. In this class you nest the custom ProjectStage implementations which have to be `public static final class` and it is required to extend `ProjectStage`. It is required to provide a `public static final` instance even though, you will not use it directly. ProjectStageHolder for custom project stage implementations: [source,java] ----------------------------------------------------------------------------------------- public class CustomProjectStageHolder implements ProjectStageHolder { public static final class CustomProjectStage extends ProjectStage { private static final long serialVersionUID = 1029094387976167179L; } public static final CustomProjectStage CustomProjectStage = new CustomProjectStage(); } ----------------------------------------------------------------------------------------- Configure your custom `ProjectStageHolder` in `META-INF/services/org.apache.deltaspike.core.api.projectstage.ProjectStageHolder`. NOTE: The file has to provide the _fully qualified_ class name of the custom implementation of the `ProjectStageHolder` interface. Usage of a custom project stage: [source,java] ---------------------------------------------------------------------------- ProjectStage customProjectStage; customProjectStage = ProjectStage.valueOf("CustomProjectStage"); //or customProjectStage = CustomProjectStageHolder.CustomProjectStage; //or @Exclude(ifProjectStage = CustomProjectStageHolder.CustomProjectStage.class) ---------------------------------------------------------------------------- == Setting the active ProjectStage For setting the ProjectStage which shall get used in your application you can specify it in a few ways. The underlying mechanism used to determine the string is the ConfigResolver. .Example ------------------------------------------------ -Dorg.apache.deltaspike.ProjectStage=Development ------------------------------------------------ == ProjectStageProducer (for Third-party Portable Extensions) `ProjectStageProducer` provides the producer method which allows to inject the current ProjectStage. However, in some cases it is needed to use ProjectStages also during the bootstrapping process of the CDI container and you can not use injection. In such cases you can use `ProjectStageProducer.getInstance().getProjectStage()` to resolve the current ProjectStage. This helper also contains helpers for unit-tests - e.g. `#setProjectStage`. However, those methods should not be needed for users (we just need them for testing different ProjectStage scenarios). ================================================ FILE: documentation/src/main/asciidoc/proxy.adoc ================================================ :moduledeps: core = Proxy Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Proxy Module provides a simple CDI based wrapper for creating dynamic proxies that can be used within other extensions. + The benefit of the DeltaSpike Proxy Module (compared to Javassist or any library) is that the DeltaSpike proxies will execute CDI interceptors. + The Proxy Module also provides the 'DeltaSpikeProxyContextualLifecycle', which enables you to dynamically register a proxy as CDI bean via the DeltaSpike 'BeanBuilder'. IMPORTANT: Currently CDI Interceptors applied via @Interceptors, @Intercepted and @Decorator are not supported by our proxies! === 1. Declare Proxy Module Dependencies Add the Proxy module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-proxy-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-proxy-module-impl-asm ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-proxy-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-proxy-module-api' ---- The currently provided implementation is a wrapper for ASM 5, which gets shaded into the implementation JAR. === 2. Extend `DeltaSpikeProxyFactory` The key to making the proxy module work is to provide an implementation of `DeltaSpikeProxyFactory` which will do your proxy work for you. + DeltaSpike ships 3 implementations which demonstrates how its meant to work: + - org.apache.deltaspike.partialbean.impl.PartialBeanProxyFactory - org.apache.deltaspike.proxy.util.EnableInterceptorsProxyFactory - org.apache.deltaspike.jsf.impl.injection.proxy.ConverterAndValidatorProxyFactory === 3. Using `@EnableInterceptors` `@EnableInterceptors` allows you to enable your bean interceptors for @Produces, which is not supported via the CDI API. + Both interceptors on method and class level are supported. [source,java] -------------------------------------- @MyCustomInterceptor public SomeServiceImpl implements SomeService { @Transactional public void doSomething() { .... } } -------------------------------------- [source,java] -------------------------------------- @Produces @EnableInterceptors public SomeService produce() { return new SomeServiceImpl(); } -------------------------------------- === 4. Using `EnableInterceptorsProxyFactory` `@EnableInterceptors` is just a API for producers which is built on `EnableInterceptorsProxyFactory`. + With `EnableInterceptorsProxyFactory` you can just proxy an existing object and let it execute CDI interceptors, if they are defined on the given object class. [source,java] -------------------------------------- @MyCustomInterceptor public SomeServiceImpl implements SomeService { @Transactional public void doSomething() { .... } } -------------------------------------- [source,java] -------------------------------------- public void init() { SomeServiceImpl myService = new SomeServiceImpl(); myService = EnableInterceptorsProxyFactory.wrap(myService, BeanManagerProvider.getInstance().getBeanManager()); myService.doSomething(); // will execute the interceptors } -------------------------------------- ================================================ FILE: documentation/src/main/asciidoc/scheduler.adoc ================================================ :moduledeps: core, container-control :moduleconf: impl:org.apache.deltaspike.scheduler.impl.SchedulerBaseConfig = Scheduler Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Scheduler module provides simple integration with Quartz v2 (default) or any other scheduler that supports cron-expressions for job-classes. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare Scheduler Module Dependencies Add the Scheduler module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-scheduler-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-scheduler-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-scheduler-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-scheduler-module-api' ---- === 2. Declare External Dependencies By default, the Scheduler module looks to integrate with Quartz. If this is the scheduler you would like to use, add Quartz 2.x to the list of project dependencies using this code snippet: [source,xml] ---- org.quartz-scheduler quartz 2.3.0 ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- compile 'org.quartz-scheduler:quartz' ---- === 3. Declare Container Control dependency Scheduled jobs can have built-in CDI contexts started for the duration of their execution using `@Scheduled#startScopes` which internally uses the <>. The dependency on the API and the appropriate implementation needs to be declared manually even if the feature is not used. An example for the Weld implementation: [source,xml] ---- org.apache.deltaspike.cdictrl deltaspike-cdictrl-api ${deltaspike.version} compile org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${deltaspike.version} runtime ---- Of ir you're using Gradle: [source] [source] ---- dependencies { runtime 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-weld' compile 'org.apache.deltaspike.cdictrl:deltaspike-cdictrl-api' } ---- == @Scheduled with org.quartz.Job or java.lang.Runnable Just annotate your Quartz-Jobs with `@Scheduled` and they will get picked up and passed to the scheduler automatically (during the bootstrapping process). .Scheduled task based on org.quartz.Job [source,java] --------------------------------------------------------------------------------- @Scheduled(cronExpression = "0 0/10 * * * ?") public class CdiAwareQuartzJob implements org.quartz.Job { @Inject private MyService service; @Override public void execute(JobExecutionContext context) throws JobExecutionException { //... } } --------------------------------------------------------------------------------- As an alternative it's possible to annotate an implementation of `java.lang.Runnable` (since DeltaSpike v1.5.3): .Scheduled task based on java.lang.Runnable [source,java] --------------------------------------------------------------------------------- @Scheduled(cronExpression = "0 0/10 * * * ?") public class CdiAwareRunnableJob implements java.lang.Runnable { @Inject private MyService service; @Override public void run() { //... } } --------------------------------------------------------------------------------- Behind the scenes DeltaSpike registers an adapter for Quartz which just delegates to the `run`-method once the adapter gets called by Quartz. Technically you end up with almost the same, just with a reduced API for implementing (all) your scheduled jobs. Therefore the main difference is that your code is independent of Quartz-classes. However, you need to select `org.quartz.Job` or `java.lang.Runnable` for all your scheduled-tasks, bot not both! In such scheduled-tasks CDI based dependency-injection is enabled. Furthermore, the request- and session-scope get started (and stopped) per job-execution. Therefore, the container-control module (of DeltaSpike) is required. That can be controlled via `@Scheduled#startScopes` (possible values: all scopes supported by the container-control module as well as `{}` for 'no scopes'). With 'false' for `@Scheduled#onStartup`, it is even possible to schedule/install jobs dynamically. The following example shows how to use it, if you are using `org.quartz.Job` (and not `java.lang.Runnable`). .Example [source,java] ------------------------------------------------------------------------------------- @ApplicationScoped public class ProjectStageAwareSchedulerController { @Inject private Scheduler jobScheduler; @Inject private ProjectStage projectStage; public void registerJobs() { if (ProjectStage.Production.equals(this.projectStage)) { //see 'false' for @Scheduled#onStartup this.jobScheduler.registerNewJob(ManualCdiAwareQuartzJob.class); } } @Scheduled(cronExpression = "0 0/10 * * * ?", onStartup = false) public class ManualCdiAwareQuartzJob implements org.quartz.Job { @Inject private MyService service; @Override public void execute(JobExecutionContext context) throws JobExecutionException { //... } } } ------------------------------------------------------------------------------------- == Configurable CRON expressions In some cases it might be useful to configure a cron-expression e.g. per Project-Stage. Therefore, DeltaSpike (v1.6.0+) allows to use keys instead of hardcoded expressions. In the previous examples we had e.g. `@Scheduled(cronExpression = "0 0/10 * * * ?")`. Instead of hardcoding it that way, it's possible to use e.g. `@Scheduled(cronExpression = "{myCronExpression}")` and in one of the active config-sources used by DeltaSpike a concrete expression can be defined e.g. via `myCronExpression=0 0/10 * * * ?`. Using e.g. `myCronExpression.Development=0 0/5 * * * ?` would allow to change the configured expression for Project-Stage development. == Manual Scheduler Control The SPI allows to control the scheduler (or integrate any other compatible scheduler as an alternative to Quartz2) Via standard injection like [source,java] ------------------------------------ @Inject private Scheduler jobScheduler; ------------------------------------ it is possible to manually start/stop the scheduler, pause/resume/interrupt/check scheduled jobs, register jobs manually or start a job once (without registering it permanently). **Attention**: To use a typed injection-point and avoid deployment failure with some versions of Weld, you must use [source,java] ------------------------------------------------------------------ public class QuartzSchedulerProducer { @Produces @ApplicationScoped protected Scheduler produceScheduler(Scheduler scheduler) { return scheduler; } } ------------------------------------------------------------------ or [source,xml] ----------------------------------------------------------------------------- org.apache.deltaspike.scheduler.impl.QuartzSchedulerProducer ----------------------------------------------------------------------------- == Manual scheduling If the SPI provided by `org.apache.deltaspike.scheduler.spi.Scheduler` doesn't provide a method you are looking for, you can use `#unwrap` to access the underlying scheduler. Per default DeltaSpike uses an implementation of `org.quartz.Scheduler`. Therefore, it's possible to inject `org.apache.deltaspike.scheduler.spi.Scheduler` and use it like in the following example: [source,java] ---------------------------------------------------------------------------------------------- public class ManualJobScheduler { @Inject private Scheduler scheduler; @Override public void scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException { this.scheduler.unwrap(org.quartz.Scheduler.class).scheduleJob(jobDetail, trigger); } } ---------------------------------------------------------------------------------------------- With that it's e.g. possible to schedule quartz-jobs based on the same quartz-job(-class), but with different triggers,... Also manually scheduled jobs benefit from DeltaSpike features like the support of `@Inject` in the job-instances. == Execute java.lang.Runnable with ManagedExecutorService If you would like to use e.g. the `ManagedExecutorService` (with EE7+) to run the jobs, you can provide a custom adapter by adding e.g. `deltaspike.scheduler.runnable-adapter-class=mypackage.DelegatingJobRunnableAdapter` to `META-INF/apache-deltaspike.properties`. Such an adapter just needs to implement `org.quartz.Job` and in case of EE7+ inject e.g. `ManagedExecutorService` as shown in the following example: [source,java] --------------------------------------------------------------------------------- public class DelegatingJobRunnableAdapter implements java.lang.Runnable { @Resource private ManagedExecutorService managedExecutorService; @Override public void run() { Class jobClass = ClassUtils.tryToLoadClassForName(context.getJobDetail().getKey().getName(), Runnable.class); Runnable runnableBean = BeanProvider.getContextualReference(jobClass); managedExecutorService.execute(runnableBean); } } --------------------------------------------------------------------------------- == Custom Scheduler It is possible to replace the default integration with Quartz. Any scheduler that supports cron-expressions for job-classes can be used. For more information, see link:https://deltaspike.apache.org/javadoc/{latestStable}/org/apache/deltaspike/scheduler/spi/Scheduler.html[Scheduler javadoc]. ================================================ FILE: documentation/src/main/asciidoc/security.adoc ================================================ :moduledeps: core = Security Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Security module provides APIs for authorization of method invocations. There are two different APIs provided for two different approaches -- one simple interceptor-style API and another for more complex scenarios. * *<<_simple_interceptor_style_authorization, Simple interceptor-style API>>:* the method that is to be secured is loosely coupled to a predicate method (called _authorizer_ method) which decides whether the secured method invocation should proceed. Similarly to CDI interceptors, the secured method and the authorizer are tied together using a binding annotation -- `@SecurityBindingType` in this case. * *<<_advanced_authorization, Advanced API>>:* this API offers fine-grained control over the authorization process. Multiple independent _voters_ can participate in making the authorization decision and possibly return _security violations_ and thus prevent the method invocation. The voters share a common context. This API is suitable for integration with third-party security frameworks. Also, this API can be used to <> when using the DeltaSpike JSF module. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare Security Module Dependencies Add the Security module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-security-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-security-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-security-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-security-module-api' ---- === 2. Enable the SecurityInterceptor For CDI 1.0 (or DeltaSpike v1.1.0 and earlier together with CDI 1.1+), you must enable the security interceptor in the project `beans.xml` file: [source,xml] ---- org.apache.deltaspike.security.impl.extension.SecurityInterceptor ---- == Simple interceptor-style authorization This feature of the Security module intercepts method calls and performs a security check before invocation is allowed to proceed. The first piece of code required to use this API is a _security binding_ annotation. This is what we will use to add security behavior to our business classes and methods. .Create the security binding annotation [source,java] ---- @Retention(value = RUNTIME) @Target({TYPE, METHOD}) @Documented @SecurityBindingType public @interface UserLoggedIn {} ---- Next, we must define an _authorizer_ class to implement behavior for our custom security binding type. This class is simply a CDI bean which declares a method annotated `@Secures`, qualified with the security binding annotation we created in the first step. This method has access to the `InvocationContext` of the method call, so if we need to access parameter arguments, we can do so using the given context. Note that we may also inject other beans into the parameter list of our authorizer method. .Create the authorizer [source,java] --------------------------------------------------------------------------------------------------------------------------------- @ApplicationScoped public class LoggedInAuthorizer { @Secures @UserLoggedIn public boolean doSecuredCheck(InvocationContext invocationContext, BeanManager manager, Identity identity) throws Exception { return identity.isLoggedIn(); // perform security check } } --------------------------------------------------------------------------------------------------------------------------------- We can then use our new annotation to secure business or bean methods. This binding annotation may be placed on the entire class (securing all methods) or on individual methods that you wish to secure. .Secure a bean method [source,java] ---------------------------------------- @ApplicationScoped public class SecuredBean1 { @UserLoggedIn public void doSomething(Thing thing) { thing.doSomething(); } } ---------------------------------------- Next, we may access parameter values from the method invocation directly in our authorizer bean by creating custom `@SecurityParameterBinding` types; this is a simple step once we have completed the work above: .Create a parameter binding annotation [source,java] -------------------------------- @Retention(value = RUNTIME) @Target({PARAMETER}) @Documented @SecurityParameterBinding public @interface CurrentThing { } -------------------------------- Now, when a secured method is invoked, we can inject actual parameter values as arguments into our authorizer method, providing domain-level security in our applications: .Update the authorizer to use parameter binding [source,java] ------------------------------------------------------------------------------------------------------------------------------------------------------------ @ApplicationScoped public class CustomAuthorizer { @Secures @UserLoggedIn public boolean doSecuredCheck(InvocationContext invocationContext, BeanManager manager, Identity identity, @CurrentThing Thing thing) throws Exception { return thing.hasMember(identity); // perform security check against our method parameter } } ------------------------------------------------------------------------------------------------------------------------------------------------------------ Note that our business method must also be annotated. .Complete the Parameter Binding [source,java] ------------------------------------------------------ @ApplicationScoped public class SecuredBean1 { @UserLoggedIn public void doSomething(@CurrentThing Thing thing) { thing.doSomething(); } } ------------------------------------------------------ Our method is now secured, and we are able to use given parameter values as part of our security authorizer! There may be cases where you may want to base your authorization logic on the result of the secured method and do the security check after the method invocation. Just use the same security binding type for that case: [source,java] ---------------------------------- @ApplicationScoped public class SecuredBean1 { @UserLoggedIn public Thing loadSomething() { return thingLoader.load(); } } ---------------------------------- Now you need to access the return value in the authorizer method. You can inject it using the `@SecuredReturn` annotation. Update the authorizer to use a secured return value: [source,java] --------------------------------------------------------------------------------------------------- @ApplicationScoped public class CustomAuthorizer { @Secures @UserLoggedIn public boolean doSecuredCheck(@SecuredReturn Thing thing, Identity identity) throws Exception { return thing.hasMember(identity); // perform security check against the return value } --------------------------------------------------------------------------------------------------- Now the authorization will take place after the method invocation using the return value of the business method. == Advanced authorization This is an alternative to the simple annotation-based interceptor-style API. This API uses the annotation `@Secured` and is mainly a hook for integration of custom security concepts and third-party frameworks. The DeltaSpike Security module is _not_ a full application security solution, but some of the other DeltaSpike modules are security-enabled and use this API (e.g. correct behaviour within custom scope implementations,...). Internally, this `@Secured` API uses the `@Secures`/`@SecurityBindingType` API. (In MyFaces CODI it was originally a CDI interceptor. This part changed a bit, because between the interceptor and `@Secured` is the `@SecurityBindingType` concept which triggers `@Secured` as on possible approach. Therefore the basic behaviour remains the same and you can think about it like an interceptor.) The entry point to this API is the `@Secured` annotation placed either on the whole class -- enabling security for all methods -- or on individual methods. The only other prerequisite is at least one `AccessDecisionVoter` implementation, explained in the next section. .Securing All Intercepted Methods of a CDI Bean [source,java] ----------------------------------------- //... @Secured(CustomAccessDecisionVoter.class) public class SecuredBean { //... } ----------------------------------------- .Securing Specific Methods [source,java] --------------------------------------------- //... public class SecuredBean { @Secured(CustomAccessDecisionVoter.class) public String getResult() { //... } } --------------------------------------------- === AccessDecisionVoter This interface is (besides the `@Secured` annotation) the most important part of the concept. Both artifact types are also the only required parts: [source,java] -------------------------------------------------------------------------------------------------------- public class CustomAccessDecisionVoter implements AccessDecisionVoter { @Override public Set checkPermission(AccessDecisionVoterContext accessDecisionVoterContext) { Method method = accessDecisionVoterContext.getSource().getMethod(); //... } } -------------------------------------------------------------------------------------------------------- //// [TODO] tip about the changed parameter/s //// === SecurityViolation In case of a detected violation a `SecurityViolation` has to be added to the result returned by the `AccessDecisionVoter`. === AbstractAccessDecisionVoter You can also implement the abstract class `AbstractAccessDecisionVoter`. This is a convenience class which allows an easier usage: [source,java] ----------------------------------------------------------------------------------------- public class CustomAccessDecisionVoter extends AbstractAccessDecisionVoter { @Override protected void checkPermission(AccessDecisionVoterContext accessDecisionVoterContext, Set violations) { // check for violations violations.add(newSecurityViolation("access not allowed due to ...")); } } ----------------------------------------------------------------------------------------- === @Secured and stereotypes with custom metadata If there are multiple `AccessDecisionVoter` and maybe in different constellations, it is easier to provide an expressive CDI stereotypes for it. Later on that also allows to change the behaviour in a central place. .Stereotype Support of @Secured [source,java] ------------------------------------------- @Named @Admin public class MyBean implements Serializable { //... } //... @Stereotype @Secured(RoleAccessDecisionVoter.class) public @interface Admin { } ------------------------------------------- Furthermore, it is possible to provide custom metadata easily. .Stereotype of @Secured with custom metadata [source,java] ------------------------------------------------------------------------------------------ @Named @Admin(securityLevel=3) public class MyBean implements Serializable { //... } //... @Stereotype @Secured(RoleAccessDecisionVoter.class) public @interface Admin { int securityLevel(); } @ApplicationScoped public class RoleAccessDecisionVoter implements AccessDecisionVoter { private static final long serialVersionUID = -8007511215776345835L; public Set checkPermission(AccessDecisionVoterContext voterContext) { Admin admin = voterContext.getMetaDataFor(Admin.class.getName(), Admin.class); int level = admin.securityLevel(); //... } } ------------------------------------------------------------------------------------------ === AccessDecisionVoterContext Because the `AccessDecisionVoter` can be chained, `AccessDecisionVoterContext` allows to get the current state as well as the results of the security check. There are several methods that can be useful * `getState()` - Exposes the current state : INITIAL, VOTE_IN_PROGRESS, VIOLATION_FOUND, NO_VIOLATION_FOUND * `getViolations()` - Exposes the found violations * `getSource()` - Exposes, for example, the current instance of `javax.interceptor.InvocationContext` in combination with `@Secured` used as interceptor. * `getMetaData()` - Exposes the found meta-data, for example the view-config-class if `@Secured` is used in combination with type-safe view-configs * `getMetaDataFor(String, Class)` - Exposes meta-data for the given key === SecurityStrategy SPI The `SecurityStrategy` interface allows to provide a custom implementation which should be used for `@Secured`. Provide a custom implementation as bean-class in combination with `@Alternative` or `@Specializes` (or as global-alternative). In case of global-alternatives an additional configuration needs to be added to `/META-INF/apache-deltaspike.properties`. .Example ---- globalAlternatives.org.apache.deltaspike.security.spi.authorization.SecurityStrategy=mypackage.CustomSecurityStrategy ---- TIP: The configuration for global alternatives is following the pattern: `globalAlternatives.__=__` === Examples ==== Redirect to requested page after login DeltaSpike can be combined with pure CDI or with any other security frameworks (like PicketLink) to track the denied page and make it available after user logs in. An example of this use case is available in the examples module in the DeltaSpike repository: * link:https://github.com/apache/deltaspike/tree/master/deltaspike/examples/security-requested-page-after-login-cdi[Making initially requested secured page available for redirect after login with CDI] * link:https://github.com/apache/deltaspike/tree/master/deltaspike/examples/security-requested-page-after-login-picketlink[Making initially requested secured page available for redirect after login with PicketLink] The relevant classes are `AuthenticationListener` and `LoggedInAccessDecisionVoter`. ================================================ FILE: documentation/src/main/asciidoc/servlet.adoc ================================================ :moduledeps: core = Servlet Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Servlet module provides CDI integration with the Java Servlet API. It enables injection of common servlet objects and propagation of servlet events to the CDI event bus. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare Servlet Module Dependencies Add the Servlet module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-servlet-module-api ${deltaspike.version} compile org.apache.deltaspike.modules deltaspike-servlet-module-impl ${deltaspike.version} runtime ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- runtime 'org.apache.deltaspike.modules:deltaspike-servlet-module-impl' compile 'org.apache.deltaspike.modules:deltaspike-servlet-module-api' ---- === 2. Configure Listeners and Filters In most cases there is no need for any additional configuration beside adding the required dependencies to your project, because all required listeners and filters are automatically registered in the container. However there are certain situations in which you will have to manually register the listeners and filters in your `web.xml`: * Your container does not support Servlet 3.0 or newer. * You have set `metadata-complete=true` in your `web.xml`. * You packaged the servlet module in the `lib` directory of an EAR archive. In these cases you will have to add the following section manually to the project `web.xml`: [source,xml] ------------------------------------------------------------------------------------------------------------- EventBridgeContextListener org.apache.deltaspike.servlet.impl.event.EventBridgeContextListener EventBridgeSessionListener org.apache.deltaspike.servlet.impl.event.EventBridgeSessionListener ServletContextHolderListener org.apache.deltaspike.servlet.impl.produce.ServletContextHolderListener RequestResponseHolderListener org.apache.deltaspike.servlet.impl.produce.RequestResponseHolderListener RequestResponseHolderFilter RequestResponseHolderFilter org.apache.deltaspike.servlet.impl.produce.RequestResponseHolderFilter RequestResponseHolderFilter /* EventBridgeFilter EventBridgeFilter org.apache.deltaspike.servlet.impl.event.EventBridgeFilter EventBridgeFilter /* ------------------------------------------------------------------------------------------------------------- == Injectable Servlet Objects The DeltaSpike Servlet module contains producers for many objects of a Servlet environment. All produces are using the special qualifier `@DeltaSpike` for compatibility with CDI 1.1, which supports the injection of some Servlet objects out of the box. The following code shows the general injection pattern to use for all objects. [source,java] ------------------------------------ @Inject @DeltaSpike private ServletObject servletObject; ------------------------------------ === ServletContext The `ServletContext` is made available in the application scope. It can be injected into any CDI bean like this: [source,java] -------------------------------------- @Inject @DeltaSpike private ServletContext servletContext; -------------------------------------- === ServletRequest / HttpServletRequest The `ServletRequest` is made available in the request scope. The current request can be injected into a CDI bean like this: [source,java] ------------------------------- @Inject @DeltaSpike private ServletRequest request; ------------------------------- In case of HTTP requests you can also inject the `HttpServletRequest`: [source,java] ----------------------------------- @Inject @DeltaSpike private HttpServletRequest request; ----------------------------------- === ServletResponse / HttpServletResponse The `ServletResponse` is made available in the request scope. The current response can be injected into a CDI bean like this: [source,java] --------------------------------- @Inject @DeltaSpike private ServletResponse response; --------------------------------- In case of HTTP requests you can also inject the `HttpServletResponse`: [source,java] ------------------------------------- @Inject @DeltaSpike private HttpServletResponse response; ------------------------------------- === HttpSession The `HttpSession` is made available in the session scope. You can inject the current session of a user into a CDI bean like this: [source,java] ---------------------------- @Inject @DeltaSpike private HttpSession session; ---------------------------- Please note that injecting the session this way will force the creation of a session. === Principal The `Principal` is made available in the request scope. The current principal can be injected into a CDI bean like this: [source,java] ---------------------------- @Inject @DeltaSpike private Principal principal; ---------------------------- The `Principal` is obtained by calling `getUserPrincipal()` on the `HttpServletRequest`. == Servlet Event Propagation The DeltaSpike Servlet module propagates a number of Servlet object lifecycle events to the CDI event bus. This allows regular CDI beans to observe these events and react accordingly. In most cases the event type is the object whose lifecycle is observed. To distinguish between construction and destruction of the corresponding object, DeltaSpike uses the qualifiers `@Initialized` and `@Destroyed`. The following sections shows which concrete Servlet objects are supported and how their lifecycle can be observed. === Servlet Context Lifecycle Events The Servlet module supports initialization and destruction events for the `ServletContext`. These events can for example be used to detect application startup or shutdown. The following code shows how these events can be observed: [source,java] ----------------------------------------------------------------------------------------- public void onCreate(@Observes @Initialized ServletContext context) { System.out.println("Initialized ServletContext: " + context.getServletContextName()); } public void onDestroy(@Observes @Destroyed ServletContext context) { System.out.println("Destroyed ServletContext: " + context.getServletContextName()); } ----------------------------------------------------------------------------------------- The events are emitted from a `ServletContextListener` called `EventBridgeContextListener`. You can disable lifecycle events for the `ServletContext` by deactivating the following class: [source,java] ------------------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeContextListener ------------------------------------------------------------------- If you manually registered the required filters and listeners, you can also simply remove the entry for the `EventBridgeContextListener` from your `web.xml` to disable the events. === Request and Response Lifecycle Events The Servlet module also supports initialization and destruction events for the `HttpServletRequest` and `HttpServletResponse`. These events can for example be used for initialization work like invoking `setCharacterEncoding` on the request. The following example shows how to observe lifecycle events for the request: [source,java] -------------------------------------------------------------------------------------- public void onCreate(@Observes @Initialized HttpServletRequest request) { System.out.println("Starting to process request for: " + request.getRequestURI()); } public void onDestroy(@Observes @Destroyed HttpServletRequest request) { System.out.println("Finished processing request for: " + request.getRequestURI()); } -------------------------------------------------------------------------------------- Observing lifecycle events for the response works the same way: [source,java] --------------------------------------------------------------------------- public void onCreate(@Observes @Initialized HttpServletResponse response) { System.out.println("HttpServletResponse created"); } public void onDestroy(@Observes @Destroyed HttpServletResponse response) { System.out.println("HttpServletResponse destroyed"); } --------------------------------------------------------------------------- All events of this category are emitted from a servlet filter called `EventBridgeFilter`. If you want to disable events for this category, just use DeltaSpike's deactivation mechanism to deactivate the following class: [source,java] ---------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeFilter ---------------------------------------------------------- If you manually registered the required filters and listeners you can also simply remove the entry for the `EventBridgeFilter` from your `web.xml` to disable the events. === Session Lifecycle Events The last category of events supported by the DeltaSpike Servlet module are the lifecycle events for the user's HTTP session. The following example shows how these events can be observed from a regular CDI bean. [source,java] ------------------------------------------------------------------ public void onCreate(@Observes @Initialized HttpSession session) { System.out.println("Session created: " + session.getId()); } public void onDestroy(@Observes @Destroyed HttpSession session) { System.out.println("Session destroyed: " + session.getId()); } ------------------------------------------------------------------ The lifecycle events for the HTTP session are sent from a `HttpSessionListener` called `EventBridgeSessionListener`. To disable this event category, deactivate the following class: [source,java] ------------------------------------------------------------------- org.apache.deltaspike.servlet.impl.event.EventBridgeSessionListener ------------------------------------------------------------------- If you manually registered the required filters and listeners you can also simply remove the entry for the `EventBridgeSessionListener` from your `web.xml` to disable the events. ================================================ FILE: documentation/src/main/asciidoc/snapshots.adoc ================================================ = Use DeltaSpike Snapshots :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. If you want to be at the bleeding edge, you can work with DeltaSpike snapshots. These are available from the Apache Snapshot Repository for use in Maven-based projects. To begin using them, you must configure Maven with the repository location and your projects with the snapshot version. WARNING: Snapshots provide previews of DeltaSpike during development. Snapshots are subject to change and may not yet include all expected features of the final release. Snapshots should not be used in production environments. == 1. Configure Maven to Use the Apache Snapshot Repository You must add the Apache Snapshot Repository to your Maven configuration `settings.xml` file. This ensures Maven can find the repository when it searches for your project DeltaSpike dependencies. . Open your Maven configuration `settings.xml` file for editing . Add the Apache Snapshot Repository to the list of repositories + [source,xml] ---- apache-snapshot-repository http://repository.apache.org/snapshots/ false true ---- + . Save the `settings.xml` file changes == 2. Configure Your Project with the Snapshot Version With Maven configured for the Apache Snapshot Repository, you can specify DeltaSpike snapshot versions in your Maven-based projects. . Open the project `pom.xml` file for editing . Add the DeltaSpike snapshot version to the list of properties + [source,xml,subs="+attributes"] ---- {latestSnapshot} ---- + . Save the `pom.xml` file changes ================================================ FILE: documentation/src/main/asciidoc/spi.adoc ================================================ = DeltaSpike Service Provider Interface (SPI) :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike provides an Service Provider Interface (SPI) to enable you to extend it. == Deactivatable This mechanism is only used for artifacts *like* implementations of (`jakarta.enterprise.inject.spi.Extension`) which *can not* be deactivated with standard CDI mechanisms. This interface is just a marker interface which is implemented by all pre-configured DeltaSpike artifacts which can be deactivated manually (e.g. to improve the performance if a part isis not needed, to provide a custom implementation if the default implementation isis not pluggable by default or to bypass an implementation which causes an issue (in this case please also *contact us* and we will fix it)). To deactivate a class it is required to implement `ClassDeactivator`. Returning 'false' or 'true' allows to de-/activate the class in question. Retuning null means that the current class-deactivator does not have information about the class in question and can not provide a result. Since `ClassDeactivator` implementations are configured with the low-level configuration of DeltaSpike, the class-deactivator with the highest ordinal has the final decision. DeltaSpike itself does not deactivate an implementation, however, an add-on or a third-party portable CDI extension based on DeltaSpike (Core+) can use the concept to deactivate a default implementation of DeltaSpike in favour of its own implementation. IMPORTANT: Due to the ordinal feature of the low-level configuration approach it is possible that a class-deactivator with a higher ordinal, for example used in a concrete project, can re-activate a deactivated implementation. *Please note* that you might have to deactivate the parts of the add-on or third-party CDI extension which relies on its own implementation. Therefore, you should **be really careful with re-activation**.) The implementation should be stateless because the result will be cached and as soon as everything is initialized the class-deactivators will not be used any longer. === ClassDeactivator A class-deactivator allows to specify deactivated classes. [source,java] ---------------------------------------------------------------------------- //This class needs to be configured via one of the supported configuration sources! public class CustomClassDeactivator implements ClassDeactivator { @Override public Boolean isActivated(Class targetClass) { if (targetClass.equals(MyClass.class)) { return Boolean.FALSE; } return null; //no result for the given class } } ---------------------------------------------------------------------------- A class-deactivator will be resolved from the environment via the default resolvers or via a custom resolver which allows to use any type of configuration-format. (see `org.apache.deltaspike.core.api.config.ConfigResolver`). The key is the fully qualified name of the interface (`org.apache.deltaspike.core.spi.activation.ClassDeactivator`). Starting with (TBD v1.5.1), Apache DeltaSpike ships a default Class Deactivator. It is designed mostly for testing purposes, but is meant to reduce code overhead and allow configuration to drive classes to deactivate. It is built upon the `ConfigSource` paradigm, which allows for configuration based keys to deactivate your classes. If you're not using any other ConfigSource, you can simply add entries to `META-INF/apache-deltaspike.properties` to disable classes at runtime. Here's an example configuration [source] ---------------------------------------------------------------------------- org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.apache.deltaspike.core.impl.activation.DefaultClassDeactivator deactivate.org.apache.deltaspike.test.core.impl.activation.DeactivatedClass=true ---------------------------------------------------------------------------- By listing the class in the properties file and setting the value to `true`, the class will be deactivated. This is valid for anything where `Boolean.valueOf` returns true. == ConfigSource [TODO] === ConfigSourceProvider [TODO] === BaseConfigPropertyProducer [TODO] == InterceptorStrategy [TODO] == Global Alternative There are several application servers (using CDI 1.0) which can not handle alternative CDI beans correctly (e.g. due to a too strict interpretation or a broken implementation). Therefore, DeltaSpike allows to use the standard `@Alternative` annotation and an additional configuration entry for DeltaSpike which allows to use the alternative implementation as a global alternative. .Standard CDI alternative implementation (without the required XML config) [source,java] ---- public class CustomBean { } @Alternative //... public class AlternativeCustomBean extends CustomBean { } ---- Instead of configuring the alternative in the beans.xml, a global alternative needs to be configured in /META-INF/apache-deltaspike.properties. CDI 1.1 should fix this issue and migrating to it means to remove the configuration entry for DeltaSpike again and move to the standard CDI configuration approach. [source] ---- custom.CustomBean=custom.AlternativeCustomBean ---- ================================================ FILE: documentation/src/main/asciidoc/test-control.adoc ================================================ :moduledeps: core, container-control :moduleconf: api:org.apache.deltaspike.testcontrol.api.junit.TestBaseConfig, impl:org.apache.deltaspike.testcontrol.impl.jsf.MyFacesTestBaseConfig = Test-Control Module :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Overview The Test-Control module enables you to write CDI-based tests easily. Calls to stop and start the CDI container are built into the Test-Control API, with simplified commands for customizing the management of contexts and other aspects during testing. == Project Setup The configuration information provided here is for Maven-based projects and it assumes that you have already declared the DeltaSpike version and DeltaSpike Core module for your projects, as detailed in <>. For Maven-independent projects, see <>. === 1. Declare Test-Control Module Dependencies Add the Test-Control module to the list of dependencies in the project `pom.xml` file using this code snippet: [source,xml] ---- org.apache.deltaspike.modules deltaspike-test-control-module-api ${deltaspike.version} test org.apache.deltaspike.modules deltaspike-test-control-module-impl ${deltaspike.version} test ---- Or if you're using Gradle, add these dependencies to your `build.gradle`: [source] ---- testCompile 'org.apache.deltaspike.modules:deltaspike-test-control-module-impl' testRuntime 'org.apache.deltaspike.modules:deltaspike-test-control-module-api' ---- === 2. Declare CDI-implementation-specific dependencies The Test-Control module depends on the Container-Control module, which provides adapters for several major CDI implementations. Therefore, to use Test-Control, declare dependency on a CDI implementation and a corresponding Container Control implementation in the `pom.xml`. ==== OpenWebBeans If you are using OpenWebBeans, add an OpenWebBeans implementation and the OpenWebBeans-specific Container Control module to the list of dependencies: [source,xml] ----------------------------------------------------- org.apache.deltaspike.cdictrl deltaspike-cdictrl-owb ${deltaspike.version} test org.apache.openwebbeans openwebbeans-impl ${owb.version} test ----------------------------------------------------- ==== Weld If you are using Weld, add a Weld implementation and the Weld-specific Container Control module to the list of dependencies: [source,xml] ---------------------------------------------------- org.apache.deltaspike.cdictrl deltaspike-cdictrl-weld ${deltaspike.version} test org.jboss.weld.se weld-se-core ${weld.version} test ---------------------------------------------------- ==== OpenEJB If you are using OpenWebBeans as the CDI implementation and you need to test EJBs as well, add the OpenEJB-specific Container Control module to the list of dependencies instead of the OpenWebBeans-specific Container Control module: [source,xml] ---------------------------------------------------- org.apache.deltaspike.cdictrl deltaspike-cdictrl-openejb ${deltaspike.version} test org.apache.openejb openejb-core ${openejb.version} test ---------------------------------------------------- === 3. Complete Additional Project Configuration Add a `beans.xml` file in the project test module (e.g. src/test/resources/META-INF/beans.xml). == Automated Container Booting and Shutdown === CdiTestRunner Start and stop the CDI container automatically per test class with CdiTestRunner, a JUnit Test-Runner. This also starts and stops one request and session per test-method. .Example of CdiTestRunner Usage [source,java] -------------------------------------------------------- @RunWith(CdiTestRunner.class) public class ContainerAndInjectionControl { @Inject private ApplicationScopedBean applicationScopedBean; @Inject private SessionScopedBean sessionScopedBean; @Inject private RequestScopedBean requestScopedBean; //test the injected beans } -------------------------------------------------------- === CdiTestSuiteRunner Extend automated CDI container start and stop actions to whole test suites with CdiTestSuiteRunner, a JUnit Test-Suite-Runner. .Example of CdiTestSuiteRunner Usage [source,java] --------------------------------------- @RunWith(CdiTestSuiteRunner.class) @Suite.SuiteClasses({ TestX.class, TestY.class }) public class SuiteLevelContainerControl { } --------------------------------------- === Optional Shutdown Configuration You can set `deltaspike.testcontrol.stop_container` to `false` (via the standard DeltaSpike config), resulting in the CDI Container being started just once for all tests. == Test Customization === @TestControl Customize the default behavior of CdiTestRunner with @TestControl. In the following case only one session for all test-methods (of the test-class) will be created. .Example of @TestControl Usage [source,java] ----------------------------------------------- @RunWith(CdiTestRunner.class) @TestControl(startScopes = SessionScoped.class) public class CustomizedScopeHandling { //inject beans and test them } ----------------------------------------------- === ProjectStage Control Override the default ProjectStage for unit tests with `ProjectStage.UnitTest.class`. .Example of projectStage Usage [source,java] --------------------------------------------------------------- @RunWith(CdiTestRunner.class) @TestControl(projectStage = CustomTestStage.class) public class TestStageControl { //tests here will see ProjectStage CustomTestStage.class @Test @TestControl(projectStage = ProjectStage.Development.class) public void checkDevEnv() { } //tests here will see ProjectStage CustomTestStage.class } --------------------------------------------------------------- == Optional Configuration From DeltaSpike 1.2, it is possible to provide a configuration for the underlying test-container. However, currently only the adapter for OpenEJB embedded (available in CDI-Control) supports it out-of-the-box. To pass properties to the underlying test-container, you have to add `/META-INF/apache-deltaspike_test-container.properties` to the resources-directory of your test-classpath. The content of the file are key/value pairs which get passed to the container. Therefore, it is a configuration which is not used by DeltaSpike itself (it is just forwarded (as it is) to the underlying test-container). === Reconfigure the config-file Name or Location If you would like to point to an existing config-file, you have to add for example: [source,Properties] --------------------------------------------------------------- deltaspike.testcontrol.test-container.config-file=META-INF/existingConfig.properties --------------------------------------------------------------- to `/META-INF/apache-deltaspike.properties`. If you would like to do it per ProjectStage, you can use for example: [source,Properties] --------------------------------------------------------------- deltaspike.testcontrol.test-container.config-file.UnitTest=META-INF/unit-test/existingConfig.properties --------------------------------------------------------------- == Optional Integrations === Mock Frameworks From DeltaSpike 1.0, it is possible to mock CDI-Beans. Usually @Exclude (+ ProjectStage) is enough, however, for some cases mocked beans might be easier. Therefore it is possible to create (mock-)instances manually or via a mocking framework and add them, for example, via `DynamicMockManager`. **Attention:** Mocking CDI beans is not supported for every feature of CDI and/or every implementation version. For example, we can not mock intercepted CDI beans and with some implementations mocking specialized beans fails. Usually all features are active by default, however, due to those reasons we deactivated this feature by default. You can enable it by adding `deltaspike.testcontrol.mock-support.allow_mocked_beans=true` and/or `deltaspike.testcontrol.mock-support.allow_mocked_producers=true` to `/META-INF/apache-deltaspike.properties` in your test-folder. If you need dependency-injection in the mocked instances, you can use `BeanProvider.injectFields(myMockedBean);`. [source,java] ------------------------------------------------------------- @RunWith(CdiTestRunner.class) public class MockedRequestScopedBeanTest { @Inject private RequestScopedBean requestScopedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMock() { mockManager.addMock(new RequestScopedBean() { @Override public int getCount() { return 7; } }); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(7, requestScopedBean.getCount()); } } @RequestScoped public class RequestScopedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } ------------------------------------------------------------- Using a mocking framework makes no difference for adding the mock. .Example via Mockito [source,java] ---------------------------------------------------------------------------------- @RunWith(CdiTestRunner.class) public class MockitoMockedRequestScopedBeanTest { @Inject private RequestScopedBean requestScopedBean; @Inject private DynamicMockManager mockManager; @Test public void mockitoMockAsCdiBean() { RequestScopedBean mockedRequestScopedBean = mock(RequestScopedBean.class); when(mockedRequestScopedBean.getCount()).thenReturn(7); mockManager.addMock(mockedRequestScopedBean); Assert.assertEquals(7, requestScopedBean.getCount()); requestScopedBean.increaseCount(); Assert.assertEquals(7, requestScopedBean.getCount()); } } ---------------------------------------------------------------------------------- Since CDI implementations like OpenWebBeans use a lot of optimizations, it is required to handle mocks for application-scoped beans differently, for example: [source,java] -------------------------------------------------------------------------------------------------------------------------- @RunWith(CdiTestRunner.class) public class MockedApplicationScopedBeanTest { @Inject private ApplicationScopedBean applicationScopedBean; @BeforeClass public static void init() { ApplicationMockManager applicationMockManager = BeanProvider.getContextualReference(ApplicationMockManager.class); applicationMockManager.addMock(new MockedApplicationScopedBean()); } @Test public void manualMock() { Assert.assertEquals(14, applicationScopedBean.getCount()); applicationScopedBean.increaseCount(); Assert.assertEquals(14, applicationScopedBean.getCount()); } } @ApplicationScoped public class ApplicationScopedBean { private int count = 0; public int getCount() { return count; } public void increaseCount() { this.count++; } } @Typed() //exclude it for the cdi type-check public class MockedApplicationScopedBean extends ApplicationScopedBean { @Override public int getCount() { return 14; } } -------------------------------------------------------------------------------------------------------------------------- However, `ApplicationMockManager` can be used for adding all mocks, if they should be active for the lifetime of the CDI-container. It is also possible to mock qualified beans. Just add the literal-instance(s) as additional parameter(s), for example: [source,java] ------------------------------------------------------------- @RunWith(CdiTestRunner.class) public class MockedQualifiedBeanTest { @Inject @MyQualifier private QualifiedBean qualifiedBean; @Inject private DynamicMockManager mockManager; @Test public void manualMockWithQualifier() { mockManager.addMock(new QualifiedBean() { @Override public int getCount() { return 21; } }, AnnotationInstanceProvider.of(MyQualifier.class)); Assert.assertEquals(21, qualifiedBean.getCount()); qualifiedBean.increaseCount(); Assert.assertEquals(21, qualifiedBean.getCount()); } } ------------------------------------------------------------- In some cases it is necessary to use `@jakarta.enterprise.inject.Typed`. Mocking such typed beans can result in an `AmbiguousResolutionException`. Therefore it is necessary to exclude the mocked implementation via `@Exclude` or `@Typed()` (or a parametrized constructor) and specify the target-type via `@TypedMock`. === JSF (via MyFaces-Test) add one of * org.apache.deltaspike.testcontrol.impl.jsf.MockedJsf2TestContainer * org.apache.deltaspike.testcontrol.impl.jsf.MockedJsfTestContainerAdapter * org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerAdapter * org.apache.deltaspike.testcontrol.impl.jsf.MyFacesContainerPerTestMethodAdapter as content to `/META-INF/services/org.apache.deltaspike.testcontrol.spi.ExternalContainer` (in your config-folder for tests, e.g. test/resources) == Using jersey-test with test-control Jersey-test starts jetty which answers requests in a separated thread. Since ds test-control just handles the thread of the test itself, it's needed to integrate jetty and jersey with the cdi-container. Usually that's done via a ServletRequestListener - the following part describes an alternative approach for jersey-test: [source,java] ------------------------------------------------------------------------------------------- //use: -Djersey.config.test.container.factory=custom.CdiAwareJettyTestContainerFactory @RunWith(CdiTestRunner.class) public class SimpleCdiAndJaxRsTest extends JerseyTest { //... } ------------------------------------------------------------------------------------------- or [source,java] ------------------------------------------------------------------------------------------- public class CdiAwareJerseyTest extends JerseyTest { static { System.setProperty("jersey.config.test.container.factory", CdiAwareJettyTestContainerFactory.class.getName()); } } @RunWith(CdiTestRunner.class) public class SimpleCdiAndJaxRsTest extends CdiAwareJerseyTest { //... } ------------------------------------------------------------------------------------------- [source,java] ------------------------------------------------------------------------------------------- public class CdiAwareJettyTestContainerFactory implements TestContainerFactory { @Override public TestContainer create(final URI baseUri, final DeploymentContext context) throws IllegalArgumentException { return new CdiAwareJettyTestContainer(baseUri, context); } } ------------------------------------------------------------------------------------------- CdiAwareJettyTestContainer is a copy of JettyTestContainerFactory.JettyTestContainer but with [source,java] ------------------------------------------------------------------------------------------- HandlerWrapper cdiHandlerWrapper = new CdiAwareHandlerWrapper(); cdiHandlerWrapper.setHandler(this.server.getHandler()); this.server.setHandler(cdiHandlerWrapper); ------------------------------------------------------------------------------------------- after the line with JettyHttpContainerFactory#createServer [source,java] ------------------------------------------------------------------------------------------- //activate the request-context e.g. via: public class CdiAwareHandlerWrapper extends HandlerWrapper { @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); try { cdiContainer.getContextControl().startContext(RequestScoped.class); super.handle(target, baseRequest, request, response); } finally { cdiContainer.getContextControl().stopContext(RequestScoped.class); } } } ------------------------------------------------------------------------------------------- == Mixed Tests Usually you should have one kind of tests per test-module. However, if you need to add, for example, a test without an external-container to your test-module which uses external-containers, you can annotate your test with: [source,java] --------------------------------------------- @RunWith(CdiTestRunner.class) @TestControl(startExternalContainers = false) public class JsfContainerTest { //... } --------------------------------------------- == Known Restrictions === Liquibase Liquibase invokes `#toString` in a `AfterDeploymentValidation` observer. *that is not portable* and therefore you have to deactivate the mocking-support via: [source,java] ---------------------------------------------------------------------------------------------------------- public class LiquibaseAwareClassDeactivator implements ClassDeactivator { @Override public Boolean isActivated(Class targetClass) { return !"org.apache.deltaspike.testcontrol.impl.mock.MockExtension".equals(targetClass.getName()); } } ---------------------------------------------------------------------------------------------------------- and add `LiquibaseAwareClassDeactivator` to `/META-INF/apache-deltaspike.properties`, for example: --------------------------------------------------------------------------------------------------- org.apache.deltaspike.core.spi.activation.ClassDeactivator=myPackage.LiquibaseAwareClassDeactivator --------------------------------------------------------------------------------------------------- Further details are available at deactivatable. === Gradle Gradle by default does not put resources and compiled sources in to the same directory. When running a test using Gradle, this means your classes will not be in bean archives as defined by the CDI spec. To work around this, you need to set your main and test directories for resources to point to where the compiled code lives. This is an example of how to do that: [source,groovy] ---------------------------------------------------------------------------------------------------------- sourceSets { main { output.resourcesDir = output.classesDir } test { output.resourcesDir = output.classesDir } } // ensure you're excluding duplicates jar { duplicatesStrategy = 'exclude' } ---------------------------------------------------------------------------------------------------------- == SPI === MockFilter Please make sure that you are aware of <<__MockFrameworks, Integration of Mock Frameworks>> before you continue with this section. If you would like to exclude some parts of your application- and/or test-code so that they aren’t eligible for the mocking mechanism, you can provide an own implementation of `org.apache.deltaspike.testcontrol.spi.mock.MockFilter` and register it in `/META-INF/services/org.apache.deltaspike.testcontrol.spi.mock.MockFilter`. That's quite special and you need to know the CDI-SPI a bit. To get an idea about the required steps, you can have a look at the default implementation used by DeltaSpike-Test itself. Such a filter is also needed in case you would like to customize DeltaSpike-Test. For example to provide an `@Alternative` implementation for DynamicMockManager, you need to implement `org.apache.deltaspike.testcontrol.api.mock.DynamicMockManager`, annotate it with `@Alternative`, ensure that you keep the type-information with `@Typed`, configure the alternative bean in `/META-INF/beans.xml` (in the test-classpath) and provide a custom `MockFilter` (as described above) which excludes the custom mock-manager. (Otherwise DeltaSpike-Test will try to mock the custom mock-manager.) === ExternalContainer org.apache.deltaspike.testcontrol.spi.ExternalContainer allows to integrate containers which get started after the CDI container. Currently DeltaSpike provides: * MockedJsf2TestContainer (integration with MyFaces-Test) [TODO] ================================================ FILE: keys/KEYS ================================================ Gerhard Petracek -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.9 (GNU/Linux) mQGiBEkxsLERBACCYmhzgYx9Sp9ZrVWFl8kvFO9kitMltQGMzrpuYHSlW23hyzZa DSDvSqcML2cDeghtN9aFbRtSTrioOywsf7Egsykxjs1zV4HrUzwHsKdw2bFvdpLx Dwthrml8dNCezRe2HM2OSjatWhfHWbKwNFR2ueGSdNFematpktzD4W//EwCggSl6 P1o95XZod+ZsaLGY+wm+GesD/R/OQQ55ODTDjXwiHH+473WIUy56gC2zw9N3lLFL ygFkGpZX1RV65InEt1oecShae2gD6LrDbmrb8baZPc0dKwzc1zt+urHzhTxKEpDp p6WxE/SXJdh4tj3Zr2JU6Qmf98Q0TTupCdRNgn37pGZyWcgrdsMWoVasM/gF9Ofv ImfDA/93Lz07Jx0tam4GGXJWcNOjyq0ir4ACZ4GztMqNPIXgaPwwml5anoAS8QoN +EVWm//rVbnZSgPEVdWE/GKIsR2bI28IB7/Qh6ZqDWvVzomxh5bki5SeXFoDBP1g Z074iIK6aDNDIINVWTa+9a4a7ie13nj3yKshcZw+B0ys1fhwTLQnR2VyaGFyZCBQ ZXRyYWNlayA8Z3BldHJhY2VrQGFwYWNoZS5vcmc+iGAEExECACAFAkkxsLECGwMG CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRASw1tHbjtaJmQjAJ9qbQTWtGIgovks QNc71ast1utlcgCfXrCwDRj/nojmkodu9DNGBS2nwWS5Ag0ESTGwsRAIAJc8UzwN u1rAIgbGZhehqtnIiU1Rd4Xy0I4rp9/CieiAR8EUyQ1vUU+aiXJWkDaR0Epjmo8G Zg/B8T3dCfUBsFsRCR1ineawldsblb7BEjpy1DRByXBBIRke3z5LdvC22jP4HGw5 YnrLZp26KBp22UDLPaqh4/a90KofwaVeNRfONQrHhusZQkoqCwohOlbHMVL7cYbZ j44T+DKeufq1a4qBC89uSW266WH7yHS0EPIOQf9GK0TfL17Y2JfMVzyjbSm4ueCO Yp5Ot9dNlnJD8EeAzF/9xSDbG8s8EAQVt+cqpp9eK0z5d2Dv49pQHDMVmXgpMWOF 7Rk2CEEWFyJAaWMAAwYIAJGog3bEz63LG2wnyi44r7RPuhg7SgmcTcjY42r8cS2N dgC0mmnd1fePnwJ+G8QBHsmrMH63JbaDYZsrGyh5CZetCWkzvpMF39l/Kou60X+a UCqxPb4tXd27zpf7h3D0NHEjI4V0W5fnwOjM6x0lmi0QWR8RBUVgdYC5K0/MSqKk Z75K0SLGb8V40DUD0v0hWCvdac0jVfnfuiZBh5VOQNKKTdibnbCX3sxYfrT9DRpN 5SP9LZwTn8ELqGD4ETeO7wxS8LKyhOhEIeww66faj4Q8kb/4pPZeNH2CqI/aDbIU HLVML1V3+/RVrVbYEqRQex+pRH4ODmxvAsrq8leMZbeISQQYEQIACQUCSTGwsQIb DAAKCRASw1tHbjtaJrCtAJ9ea/IEAqj/baD493ZBSHaIZyra2gCfcRfH73p3rT9r tfGU4oK1mYYUs9M= =Q7EV -----END PGP PUBLIC KEY BLOCK----- Antoine Sabot-Durand -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (Darwin) Comment: GPGTools - http://gpgtools.org mQINBE70fBIBEAC6guBx2XpxRR5mafxpaVcz7+KXDNtJoHay7t4tOR1NrMq2iEQR tccXQ4t+9ALD7TSMJDKQaE0L567nHhPs8+gRz5W6lj/zjYyEnMqNJoV7E7Ej7ynI o+9IC7ixGMqHKjMr3bh1nGLARv+2XB2q9/GN3yvdQ/bmmVZDcP6nffo3RaHQxoGv j2eryQCcvUKDigtgFvepa9SysY3BDQcWkR9p8F3k7eUGy667Nl2TBE6B2PUuywra lhymMKHDbg7xHu1VLAkNBUmBUy2l0jQJ8jw4I6GKqG6zO//gmbVPcMgzqKAzkWGk PGUpNtL4Z/tLDuxHdB1PH86EYeIJdT5QDq+STBDJamRLFoaXIMiHFYA1iMf+vDC7 pgtSqQgeMNM4VJpyudmQzX9N8ZDB9q+IfFhTMlLbAR+I3lMIeNsLvmyBQsBACBSJ LVyR2UefVPV8rDoMcKU1Pzz2pDyCzo+H2ES81WxKZyxXGny35SxOj6FGeR8/aUj6 twYbXn5RNvdQ/Zi/yaoCq9bAVMvfZK/qIJ5RhOcujs4OamoygKumENxi5REjxy9E nJysNVB/YXUYNZK8u36wJKRjSjNTIXG6JIC6Wi8xEutrDOjZ4JqhImfZJLtAth9j 55y6IGwaZ3I64uM3upJffsl9uDcDUqEimuxm7TEGbxqZ/+Cr8EPCtSTvJQARAQAB tCtBbnRvaW5lIFNhYm90LUR1cmFuZCA8YW50b2luZXNkQGFwYWNoZS5vcmc+iQI4 BBMBAgAiBQJO9HwSAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRDw4T/Q PFZg4kDYEACfx74r+fu4GJIx8lmcbiAjBEUPlaYyOOTj7vnz1IgaNUMi+69SJdsp 4RUqaMPDNQW+zwXZ/ZtjN0kAxZUxbEhJBbLKhDteY7k0dfc6Y5IsnnXnfov6F//x LNx4NuOpyO7kuka781o0FiHuiD6Ja8Xu2Jd7MH2y+0P+Y8uIMJdXz4BTx1U2MdKq WBjBV9dzoTkQ6W1Iejk+jbS4lp8mXbMNxaz7M+Cp/5tc2eKjJIhziU0nDDsPzBh5 uR2CbgMUPUERc49CyZUGftKGffsuo+e7dyCHOaH12B6/uy0ww60yxpPUR2jdTofx tBTXZcVa2UV9mX7AJm6IdkJwBFmzHQGbNzVQgY8A7XYyrK0+NXdM/B6zKjlER2xQ rA/McfH5ci0AWV1FFqmnSTStuau6v7RvHarH2xYsgN+5Dl2eqwXJtTGzd6uICa87 tOqyfERbmrEVKldQjhSX8ky7k+6QcP7dKhn8+cSWimwN2H+Ofkd/NBTBVHIVx0Gv 56X/yhLr4e+HJfyYZz+s5UbFXbTBTm3yPbX6jzFvBCHhfJS3ol97gsBDKjAOo/Nc 4UFYbNMPLQ2uNWpVPEyMXETpftX75J7n8bhpdQH65an4jhRjVopr+gDpy+CDt6dE F3YevWmphfPtZju/Gy5JVqSOIo3Ilz7X6EF/JQSUDDMYaQvKlkyr7bkCDQRO9HwS ARAAoPcAaS7speOOfFl06+MHkWRS8Os7LvIl/BcwZujQLVPwwlEFUIwSLdJ+qH1L 8dhljQsDsyFA6rhZDivdg1R7P+kIkCemVzA6zeOi7U/x0i8L9+Abrpo9+qGEi7ip MqJ8GknCEmij3eVY9iBqHIQ7kHrNmUcqSSXizMkEAS5JFgq6bB7pbHe8bF6aOobq 2aYyWkYD6QVY1sAAT8+jOlum/LjGLTFOrvmrun6WAPyk55S7qWuaq07biTDyVO9X f0qVwc3czO8ad5YJfhFt6QMPCdkjcDcLvURpkNYNZrbGT1Zgul+EKFPYH1Fzj0o7 zQ+XwAANgNUMZD2vrfneQiUSW5NoC0Cx3EFZ2vWBtoE190D6DyaM3F2tekaAk8cy CquHhNZuWAg9Bu+qJxS+AeOjB2F02L7rA6+qr6QZzySCDFPZ6TOwPqocp3Xq+VhS NmCxLbaMyzN8JVPzODo1ZjzcVL0xKwdnQkjfiZTDBbyoMpK+NNKQQUmituB/cSsz 3d3+prR4SKlyuRLRTZqN5In5SrmI++tpyBVA0KjW+LWGwj+zY3EFszCpGs/PkG/9 ks9icSXPmGRVfjGlK43bTouweHxT/PY1DBgfXSA/oT/WbEjXDurNaioKPKpo5vml OLNJVlnxhMcOo7PfAS80Zwr+84bqGEoaNvKza39pEiRalskAEQEAAYkCHwQYAQIA CQUCTvR8EgIbDAAKCRDw4T/QPFZg4pfOD/93xVhBSMZZ92nsZyhcrsK4/pKmkJFT Vg2YN5SVsgI1fq8olSwZJgtYjc7/aj3nfDncctZ823OqlznpKm59Fm6C2i0xBEqQ /y3dxQq0G4VPP7DBA3nF4yvD4dewIRX5LOGM75Ec3m3e11BSTB3ldsJrBNxP370f C2ZL0nG+lcBxaBq/WwsmFiLNXrIS0abg7er6zMpyObte42IEkWOc1J3xgFm9Jall /6g9+A/b9ZWalE9oUnfzzR534g1/D2iZjQUkRFBE5GxXnhDS8AJdnHP8i5rOMl/W nwAe8OGBwV5kEYZ4dJM31Fe8rxuqFN+5DFttXdh5jYrRfXbfXvHYGPmxbU5iLVBv eowcyhIOLHPiZ1jaWcUNwETspwlg2F0HeYY8gQHX5A7ongk9WtCIPBFOreCen3S/ DrOgJo+LxhYTWgrjzrLcvHezg5+Ya7Mv8RGbinovgZiEuOYHMIsaQhV8HAif87Y0 /eM4BjpNcabpFRFM4rYMvwcnAQLuPpzdrGv6wXXGW/hUsQ2nR0zdM6W7v0L0AxLg P3L01I087Y+HTq+UZeQnkdbptK27D3yD4laq5te8B0PBwQd0UuCHFm22WMymcuHo w3Yq+kSWaqHqTHJmSEO/drQgj1vuJyfYRZ4AR/meq/8IOHhIWkVd6a7G8uSm0QAr m+khrP/HMmvTjw== =PkH4 -----END PGP PUBLIC KEY BLOCK----- Jakob Korherr -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG/MacGPG2 v2.0.12 (Darwin) mQENBEx/uP4BCADc013HRON8aGS5nix4KbkyRGQejP/VAHSQ1sh6ooVcWMxJSL1G 4c/lFhTNXZeFHmKbmPLJZ6tByvQJ+VLfUiRVZTyoMHYl/js6QFDDtUNZw8STZ1Kv W2BODUiqIUy8Z8rQfQFJg3Aj7Nnk7PMZlJwKjG3OiPwFn9bKTgwze/LanN8FuB4w 7LNQNiaUZ7897sPntCkWoRt1/WoKiygrJwZQRFMw4Sbpa36j7yT4J/CzrDtmse+E caITVFDppFuyiULyCIQ7jhztw3ZHQ3y0RgCFXSI0WPy8/gwqzu89ATtyYUm9aQne 0gZdO/NmKo0BLd3G617N2bFQ5+UmLCxarBD/ABEBAAG0IUpha29iIEtvcmhlcnIg PGpha29ia0BhcGFjaGUub3JnPokBNgQTAQIAIAUCTH+4/gIbAwYLCQgHAwIEFQII AwQWAgMBAh4BAheAAAoJEJ3NMsPsezNww5sH/166RxHA3NirQyKCiCPprBcYaMV2 AZ1tVMTM0TZIIM5Cxrd7jVHZjZkBU8wFP7Gk/Z5qkZifm3RxKMb/SR1CLyKwsdgg cAKsKszn6eh4XgtFgQQ+mTvIpuq3Cr6zSfPQNWpOQMocH/3Z8rcHsUfjH999add2 I6UGH8G02EzWcolv2EugV4GvfhGMvqcuHrjL75n41522DQkrN98pa8SaYJYD4fle x/HGStzb2pBDnRSx02xu28t1jC+6Tei5vtJ/7qLKlhNGXNVy7N41uDvIbLuDMZIN EaJJ1nm+sdrbc4CT968u1b3tB1xUO1AvxRoLZrSKRGL5dWPvL/Oj6BXdrCG5AQ0E TH+4/gEIAJQ5QdSqM/Mp0lH/xGG57yAyuqAOb2uy+anZwfoJv1H4wl+hCy8/HmMa WeEFBYDjSPU/QlAwMQU2qIgALQCj8LPOpsJN9b9qwgM4aaFCT694Vepo4S2QPQLq R198crk3dj0XkvdS4Gu3o6CKbNA6OEk6MTi50Z01hE+04eU9x8Rci+h7lWcFUEvA VwIIUlgxCtj/6qqf6af1N43TOYX7NvM29qjRwMVndvy7cO1mMZSbD6HOZ/6sy+wC DLdEaVgFAaQjt5dXA4Kg0lkYMKkxw1gfwLKIkF8rZ+6JjFoMDJsjptkuujoKiG/F kt/cFjK9bvc7VW7p6FeFHU3ybe5puHcAEQEAAYkBHwQYAQIACQUCTH+4/gIbDAAK CRCdzTLD7HszcDRCCACbKxdhS60DntVTzHYNfrtnVRGlGPYCiCzgNE2udTG6TN13 U0A1k2q/Z/xU3TpF7FrooYKIOYDMlBwXwYNOY/chQ++NPphTw0+tbzLgpKVooPYN moAe8ayIDO3AzloM1q2lewAKzpzNW/e+Z/p6SYYhyIEGVvFare9fqJ0lDbpbyfrO PiMVkaH90xQatYcW0Xo9LaTb0s0akyTK/k+llCc1QPcpEGYC/LPK52R5mTor5gqi V2TbyonLUBvMv5pgT8ZouNs2tRRH1CMe7aE+SiiT4SyVfBlNaQcGqpWspIb6TWlO b4YGjoC1yob1dwdT3CQ3Gkf6kgI6xXaxBfcD0llb =VXV2 -----END PGP PUBLIC KEY BLOCK----- Jason Porter -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.13 (GNU/Linux) mQINBFFQxyUBEADb7PTRa43AUSqgZW9CPJ4FFJQ4C4PYOgHxba61+m+Rm/HtGZWI pszDjyrhU/r4fmjTqg/LpwoyME0SjWFgLY5558RW3mJ5anB08MkSCId9nIhvzBqn 7+CN1714iYwNu9gvJgfwmG+YelNseT1yxh5vMcyPxZjHRLxnXdWlZ6PzJLc77CEb Qi6TM3CpPIEOSepjwicGuUzaQa0bEKt9GnQklWpgX3baRpY9ZQKC3es0S1mkCVHV IX7q/6cys2QChT2vZX7ROUh+P/4cQnvVTFEbJcn5uT0NHEtCbF/Ljh3Vkrcetkp8 22QjAYNfugq2Jzsj5QQsFAzZWzvjqgwwCgoRNxkFbijPw8sa0itFiq0kOCK+Yewg 6YgVyaHyrmB+eNxmS6smr3eEul6wQsh+wu2GZMLRJZqLDhN05qg4x6WLVgpm/P1F f7t+bmk1fkMzILAlDKR40qr6HBcAC+JcHPeyX9O/G97O0/NiCmUO8PRvv3ofLbLQ IC7Q8UOLw8NiPJhSQyxvv/RMsBgmzWu4750myTq3NwZJoOQsKZBHB4ydBjur8D4O MLojY7ag7LDxR3PfXa7Y1GmUrkwO84piU9N/3hS3nJm25IPPgW6QXSCTMwu6FQd8 eVgUEC9wi9jfry8G2e+4apz+wD15feThK4L4pPQeXcsjaWhPiqKt7nxGTwARAQAB tDdKYXNvbiBSb2JlcnQgUG9ydGVyIChuZXcga2V5KSA8bGlnaHRndWFyZC5qcEBn bWFpbC5jb20+iQI+BBMBAgAoBQJRUMclAhsDBQk4ZAkABgsJCAcDAgYVCAIJCgsE FgIDAQIeAQIXgAAKCRC+38+zD7ctEYHXEAC/2hz6twVDJvCLWOfIIQH52JbQky5k W2XdAZmVGoMO7lCJqOCdxvGXix5PPEJ8pm+gvYpCwg7+TnUjYx6g+DB5F5DUUnMp jTnOPYApLxpfAFmBzkoi536w6PcbOkWZkg+JYXPLRyul4M9NuNLi5VwuuBe7QG09 S7mEak2MK042fNucMc/oxlAvZ5A4WSrXbKKLMfBou3Y6xaHhmiAuftlJwr2SpsfJ tajvcM9o6dnoFg7T0UJ/9A2NC5AJghu7OY16dKpkN9nA7jDxY0O6KvaXkn436y7J 9rcuae+zW/ouhRIRuH4scLbFkRTOmqDCxu5vft4PMeWTgkyyxbsMmws6deETKvxA 0SAXrOZhi5OeJ+H+raZAFFUnOYs3GVklBW25SeL+jSsI851uH5WKrKVgq6NQd2HW TGe0ujUrU2Re1hJHw1zi2K0QpAYJHE8akpmkhLUoX6uwhkgrXyg5XllN/WMBjodj xlnK/J4yocyGBd6+gUgRFA3vqD1yIRPKkz9K2HStEw1vbWG2ndVj4QneCbOD8nBy zk29/bFLgb+wSomK1II9JMAGX7gjkzwhC86HS62oJ+do494/tdELbxwS66/2XRHB 0NLpo4qYxF9S8vwI8BYMILLDYUoJTIoM3bt2mjIySjnUjXQ3T5YD6ZmG3OZv5rTV JxNXikxVUH9PwLkCDQRRUMclARAA2LTWvRtZ8NAWlKqSCCu7XbNJ7avyaJXOxMjc du0BpbWyrbqHe7T/iO3fAmHqNJs/y+ENekXZq7B3qWiy9S52Ki13I/gZgUrWy+kD 5SXZuEdB18Js+XKkxU5UWXE7L8nxeMmRWvUyv97nFp4TQCxKq8Kmy2qOYTmWLJWz 13KaZ40Sij6bFY5X2zuXcRFLWP5fpzkY6yT6kBsXd54SL5+14fhSd3RkmPTT9E02 NeRD5dv77+Rhp+XKE9IfM5+mtHTIPHeAWWNXLRXWYi4GeJbron8vThhe0r1lajTk 5d1kBl30bUkPIS5ndE5YxmeDWgG6qFXyyMyfxejScNsV8ifEa0RcgzacBs7UcOeV ZG1UUtbyUSZ8hdiJX6m6vrxgyyH8ldbfRVY6AosW/T4lmqFQ7IN8Z0AVsq6kiZFp mMJosTqZk4cQHHC4dUViVcbnO30PwKi/GL0gHat5IFvI32fyWjZWqr2rxcillMDI siAC2J0PbKLJ0su6jPAd3mXf5SWOv9dfuQ1tu90deaISG2JQuqznx6Vp/HPNveXU zUySSR9l7Af01IOSmwFTFkr5coRbxv4aXP1uX5ZxFn7SXgBsl0zZO73E7NDbunzQ W8bJYsmu1SKumyasEkIyEejSAG6SiUXfWjYhEC/gG6xdBVyxsdihEx/+43JfRf8O yhbQwjEAEQEAAYkCJQQYAQIADwUCUVDHJQIbDAUJOGQJAAAKCRC+38+zD7ctEd+7 EACXXkIHBACuLgnMTRdmZlOaJom7wfSAD5IGYYvU1THPXwJoHq/aDn/Uz0XAydxD 32iPCjEI7MU9LJB0Aln96l4QhMuF0e0xfyPIpzR+anrFVwLH1dS2q8rAwleifWc/ mhHrJI/8P526WOB0PJ/QLMYYT/kHk78CbBWbz1RHJ+FQZog83mf8I48C2P5hRDdN TpbMxQbmQYaTqsKTcf6Q3h2tGdBo0wyPI92FUEyM3XGgKLIBxGg7CLg+Q4mPizDR 2hJQGAQLEJuxjGbpP5wZ/M4e+H9jqyoFSqP/e0l0vSuLymkA2mh2Lyp6LMRwXbj1 y3Rl6dv77CgD3KbGCVopUIpBim+TJfRv/ey2z0lRl/UKQkXidGxroDkwm8sdbWS6 uB/p318KzZWoVoJbFQn2XXkAwHoKAOZSoUhczpnB4ey/I9lr19jUn78x8K5O1nHe NCTyUB5kLKKsVAZm0m0SU4F9kTM+3fANy38d7vvpEOppPES6HWbrEIXNcwXqtek8 CcjcMh5KnTus/rpx+SAjIngBpv5arNU/3QOQbYjx5h598d6Qa4kQix8QZ254t+ih 9/5HXJbXSrbQ+X/4nJ6rfkKcZnXumlXpbeZrMTAc3I5BDoyVvJKVtOqqXWs4FN64 jv6Rzo6UXrIys5E5i/CcWOXtq49sYoBoRUu9yLcGVXM++Q== =l605 -----END PGP PUBLIC KEY BLOCK----- pub 1024D/1CE17EDC 2007-06-07 Key fingerprint = 0FEA 0B9C 3F6E D9EC 6A39 0AE8 40C2 AB1C 1CE1 7EDC uid Matthias Wessendorf sig 3 1CE17EDC 2007-06-07 Matthias Wessendorf sub 2048g/0E09593E 2007-06-07 sig 1CE17EDC 2007-06-07 Matthias Wessendorf -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (Cygwin) mQGiBEZoWa4RBADmTZh/tUjTdLfsP+u6VJ6hCU4/+YSXTJlLjjK4mm3l1OIS1rrW np0yHZpcuHZztZeV/+vnBM9eL6DIIwPlzcO3ZoBP1HKkrnEr1wtrzFl94MccYdR9 uO00scj/NIzF1Bi4spsk+xnfX+cRwSdmkdiM7C2+vE8VEBa+ux8ybLkSCwCgmhlY BStl6k5HKb6x2pVaGr9xDv8D/jO5sM4KoXuDDwzJmJf7sJlJX51crljXk9BYSEsZ KGpRVC6wnr8G4/irXZiXESf5jSBJ0G7upH9oTUn4PgXHZQfeIvwcEfNyXtbKUpa6 Pyn/qg4E25YEdhy086S4WPVjXF9+Ltiw4NnN78Jpqy4rmk55Ic1WEex1Rr4YW2um IDlHBADiF+d6Cs0ypu/bvWB8LyiyhmTsmgXs62RszkFq2xGhsZwVZbujcIxRkg68 cYloFkbsAlu1LMOOSkLL0xfMqV6hCoDCOqdq49GUbhBlS9kjeZm5bady4P6Wg7UW 2l6SsOp6lOzQ1slrCJEYFIMDssRuU7bSIsAt7/oXQDYDEoHJMLQnTWF0dGhpYXMg V2Vzc2VuZG9yZiA8bWF0emV3QGFwYWNoZS5vcmc+iGAEExECACAFAkZoWa4CGwMG CwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRBAwqscHOF+3Ed6AJ4z6GgPy5RKfFU5 9nz1TLiQAD8yHQCeK5iXWgMM7wJNRUNypPd0MgfuKf25Ag0ERmhZ0xAIAJgiGyU6 6pXbAQGHUcRpBr/+InpOcLGuMJ8ZA0jhVvXquWK0drqZsxcWqIkjyJRyJpGeosik ABOfypI6GDBhn4R1u8ek0WZQw69oIfXTsNCMGyzyUEnQzvgDMlxyzGY9Q7YVlM6A SlSvIKR7A/1ZQDLXlPgy4yK2LYx1iQoV4xlP0hJzXdM6yPc7v0BUgygrdK2xw7PM uU2egFWpXyVe/yTAOH6mF1ED0cDhRi+CyjeH67QpbRDBLb73hsOeME3f4353YQlk 7/4AG7hMDsiOP+V8hxoACMDDtdNqPMJx6vSRg2yVdZ5zp51Svh53WUNkGjq+pg7U yAOFHbfrtejzHj8ABRcH/21C5wkGRsqBp4BA4saLgFFhSfKFpucyFUV8MNvaUWPw XcXQsVR9GGUFe3T+LH3SchFOLU4zQLCKKTRRk9ZZPR8T7YMyray1KJF3JjzsyLQW Zrm4IN5DtTnFeoeirO4S+usQxDfEDv9g7l4etApcaBotUB8ZVu38RB0qsxtoFHi4 K08oCBQDXJQD5qksIXn+KMfBaVC0ILl0T7/O6eo4GdAlCQL61FMFnM2aeSUb5lZ3 lla4qeQwrVdATlCjaiDYlaywE1ClLwgXjf19tvmlwBbn+f7OjHrGyekA0T5BGyTu Q3UAOU3WYDDXSrFM7h0DdfVm/BjUa9G1fSjLHEBNc/WISQQYEQIACQUCRmhZ0wIb DAAKCRBAwqscHOF+3JVBAJ4nujxaQlT+QRA2hv3ACiOm9sfocwCfWMlcRX5WECOl Vg5GvJOlq5rVKKQ= =DKW+ -----END PGP PUBLIC KEY BLOCK----- John D. Ament (johndament) -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.12 (GNU/Linux) mQINBE9ThxEBEADb7OdA4C0b5vnMEAxRgi46MEslWGCIp7aY3Wce9tE1rm0xd9uW dGja/CI5Zt1eTjVd8sf5YtkGmEqH1f0dNObNekXhqLrzox9HxCLID3jU4jAW349p WxeryrAQcWArHROzck3sSvluu85WfTHjVeVimpUSI4K7VjrUCh06KFy99KDntTNf JxZxr0dey3WSWxlpaSSyS2vv2s4WNlJkVpOVBDruf7Ylyi42Sq/UQvGPmUbP1brO DBm9Re2i9oQOxg4M3eAXvc9dSk99Bqe7OAuYi+KQgo6oQiIk5lvhtfRG8PQUq5T4 /fkXWdVvdwrqszl0uCcFBahL8pU41C3BOSBU8eXILqm34irVz65QhrgbdgxU5jX9 SVVflZmax3gtxj9NjDTU7bS3aWN/Jbvz2gZts5Pk9ylzm1TLNpYAlS7ivcXU7M+C KzfDLpgQ7HMtEM9yXIUGisYsBS6P9sM2fsPhhBnwJE+S8rzqOdVRYLk4nkqmLSQs 4f7Pf+Ifdfe9Fc0rYotzCllHjlbu0xXv0i7qSJrLZpoGEK1l7sgcIrCKwJEhZZAN f6PIln5jZsN5LZDIYVqncls/ZFQorEXedtX1oH6zd04KSb76jnsr1J5yZB2elnlw XHdnesW5HalAf6WAri4vgA7mONBYly6rIJnTFNtDB25xecwpMd1V2qaJVwARAQAB tDNKb2huIEQuIEFtZW50IChqb2huZGFtZW50KSA8am9obi5kLmFtZW50QGdtYWls LmNvbT6JAjgEEwECACIFAk9ThxECGwMGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheA AAoJEF+XRWEINt6h02EQAM4ddj/UalT7eJdMgALLkO6XqXABJlSt1L/lWgCnNL9u GVMXpqXhGDdpoLQAFDedrpeutJD1NHAzH2Pe6e7c6lMi7HvJVIKVFUh57bjk/n5L M8gJsRp6hcmPmy5Dru4kiUM9fi6xSp2drjTbZkasnGNL3CbRyeMkwO8x6EF6dXgs y8oqG2kCkTyEceRmhImz98/MSR5YhbsN9DQ+7ceLTB8A1KHD3tv+rDSvgORUwj0r viY4nE6CH10RLu07PyTGF7PfN9MCDvkAl7fsia7hXL7cKKDhB8gr9buJFMRHsq6+ YajwZvYcUgOVCRmIwnCN6x1AJ5VffjzV35vy+nEe64jycS6VCaw+P8KIFR5r6d32 VXrmUcYHBOFP7wpAoU3iN+RSQv8QaSv6uy8Q75/X7ayqPhNf5LgvdICjSWbAYLwZ mQoHc0XLKU2DnoxVia5P6HaBGs6+b1Yk1KlUGkRgp/ZswQ/Rxo1t6/7ZYAhSCDLD s0icjWMchOsAlpGJzZO6gzWKO9ke5f1XRGO1vcMA1W9QL4gyGKR0rbVt/nt4i8VY 8TvXEIGvztP2aVkV1DR23jldDpy4mHRZAB9ba1l5RURYiIpOn74ftO0TaDH0keCJ TgKfkOemQhx3vxmOXhmeNeKU1bTDy9rhPKOMjNDShLDWExcCSLeml+ob1KqL0Xes uQINBE9ThxEBEADzZlphjr32vjZ34FG7OL7+tSwyCQg5j78lcUj/0M/lONHtfkL7 6HL7sUFvRNeD8tXi4Q5P5InWG/tb1lahC0MQ7rpLZDAhRf9CvZ4cA1vNXK86xily kvvQdACGzITPFJQodn0GowxwUirmRu2NrwPATYbaMc9gHMBSFb+fSfM/ZIjJpyha 1rZEvgGNzlypHtYFx54UQoyby2FO/btJdoLsKOktJMl+JNP4F+mRiwzSFiNm5ksW cttiu0thtkGy8jJ/2FcjmETb2M9eN+QReeulLT6HCSGFV/vles5i0pr44iEJF3mp F4+y6eR566RiXj2fR7U/FbhyaTH1+jsTYVaUO9h0Uzup+4oXJNEXJAdnyiSzZJ6z dxvh1L0+O9Zp+1mqEkP4X5oYoK9LrP44tU6pq7gQYq5pxBG1WXEENH9q+i6AYc+u 2TqQLDazPHTpYW7UYmzwvEsUazzdAed/UFl9Ma3xherEgTvlX0awC5HRTwX6Ff9z 0l25kV2rBsYsZp0WKNWIOG4SFO5uq337QvLw+k5gS20S3oDy2QddYLxL7bNMcL4e jBUQkvvWSpay3z5n2PqPmtDbWXP44IaZLH5vPqH0bFjomU09B7y030h5fiUgnd7o /oQ96jmTcZutoSRfDMtJk/+Q9NdDged/qQtLL+8gIrxMe0caTboyOAD+uwARAQAB iQIfBBgBAgAJBQJPU4cRAhsMAAoJEF+XRWEINt6ho2QP/io6+uas/sC2ay7NjuFH QdJ2YmYakglW7IPkyUdnqlcdH9X7O/QBCSFBtQGj6nylZmLIp4CI5HSecOouj+MA sLpZ12nz7pDw+IgjrDjOHACXDrOhi8mGmtFFyklYBXmZPGHN4ZQSyVfSHZaOQVwa q+sO0fwWDF6MEle68du5M7VqFEfKU03QDSQ3ByZlbm+oBLBMPw1D4A7M39UuaBZ+ Fe9aJSv3E6pV8xaWySMHL5Jl94UK/yahxZXXj94Udym0jmhXoS2n/bN2h5uLolmt SuN4bIqLTF4FfY588zyp214SYbyuIl8YOpN3yq1OmZ0wsKvwrpCTCGo2UtAjypwC kOM1dwLgg3PkCvHO23+L3MRkDwVc0hz16darkLmtO9kyFl3R3QqLlE9iirQrYfnT G6FT7w/y0TRQPZsfNliQbo+nl8VcqBCsdoKKLze9LaZ3Nso9gUIg+sqU4UIbaEg9 r0o4OyKRH8QmYb4F0ywuqmMFVb0B2ljUtsSFlCi3NVy/zWdrbapALy4BaDXEBMg+ wBIu1kYuPCnL8jQjOvsj84zPLgnznPAZx6l6+U2dzXfNYzi49oibBOXaCkdetxjt 98EzHGhF0dg24gSVeAMpU1AYuXEaUy3H8SQDwtPjd155Dq0wAst0i0okFr7NHJu9 asmE9bmSLBc/emgt4+DoJSfm =Q2Zq -----END PGP PUBLIC KEY BLOCK----- ---------------------------- pub 4096R/2FDB81B1 2010-02-01 uid Mark Struberg (Apache) sub 4096R/F24C5214 2010-02-01 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.9 (GNU/Linux) mQINBEtnVXUBEACz2CXck8rFZsqlmtZrwySHkCKdKQ3dO5fyya3ScYRofIS0OVi0 BwpWyVfzezq2jl4AkjEFGS/ja0shnr4hg6tWU6w3obZ4S8dQMyPm8x5kSTxj28mn lkNnR1mBr7S13n33ZtA6f5c1cPu4zMqzKEFvsqVoBwD/ru5WOB0buwGi9mG173Vi tkTi1MtzQ4aaIo8XiJyLsm/StTq1ylU1vfqtyFDZJUzoakdYSiA4NVfVFUL2LMTl gPq3hpWNZjVm41+YKWuzjIJ/lidH2Y2TmjivgtQToVbHMV3sHn/PtDKw91S6Ls2q kSLUm/Bs19H4ZGPMhWI1MnQnQiuMMPYvqIddIh2SIog2bSowPZz2FkZxrw04ej/t tYrSIfiR3sRegmWoeo/FCLYVWZ32mw5L8Tw0npHg3BSi0v5FoNd/GiD1Y6//Usy3 tQVFUI1zkh/PSWVImAgmgoE3qhcIjzlkVutsFY4NGr6LH2sUpIJBi/ECy0R38rLg sg5pjUPhs7QexH5M9FxshI+yDsvPOTeUjvpHysvemHhVJyPQSmpOa16ONFmx5xvz d90FmxKfaJJvmVMvNmGMdhdAzaAJ3XomFEJZDKfyBJoOJSoNvdOQRNBUt7aKEEKb 3BGypY2bzr0C3WxggpywPmlD1xDohurx/b3dLFoK39hmFiTek4db0tin1QARAQAB tCxNYXJrIFN0cnViZXJnIChBcGFjaGUpIDxzdHJ1YmVyZ0BhcGFjaGUub3JnPokC NwQTAQoAIQUCS2dVdQIbAwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRDpEoeC L9uBsTzGD/41kZMlyyzg6gsrQgDZPxzxVbsFWGqareqElLZ8MVTo8mEt9cKwS71T dHaEXO1BBukqPWpRjWp1TepRZ1i4PNscDwtDcGkv2lpaQICwo43MNW9GFFRJaGCr Ry4Tpov5yYwdbP1cdqNS+Q1TtwZcCTFiEL1xAAnR3nY2BzfdpL/fTXzHggmuLtRD OeiIPQrp+NaVzhk994t1MQ5wjevoZYGvH6oV6hQ3Nr4t0rA93F5fKb9vJiz3SnJU a97uPANCYzhYSb6IzNICLfSQCKi5AoK7fjENCTaq2Uqsvkl2hVZWmGYmJLRAZDFE 5RNE2OGU+x7hVCQnD1r/a0rnWpdODqM2EkqDpxkKkH5pJvzPepLeSYv4KmRu3+89 ljFtBM01pt9TPoBYRE2/sODZUFs+ct+AaxatHjs46U1Ks6g0ah7YmUnolENqsuF+ grpLtrCwgKrwfY3N4KHIMUnmq4Wmh0ooiL2o/DN0EciA2JDm+3xgK1giAXvzCbDS oHgJ/SJ6DAUtSb+t74Gd4GRvpDMoo7u82A7tZj/3h5cjmyuwms1uJc40D6v4/Ljp sbltrrWcJ/E1TokJlFT2QpRBJkMixHO4aaS7olOMJqI6/wrrzq7KjZOUfD3KwhDL DolhmshiFw1tx1sloa7RlibHAxxLKkcc+DVGVr1MBf4xus38QZT9R7kCDQRLZ1V1 ARAAstCgZH1oA9RwRaBJ21qKeOzOaB3iOQynBdjeDJGiaKuMQWgv+NpLCh+fqe8t QSj0j40fphOJq0dTNSqNExLd4P5hEhUXALkFWGmc8vki5InXkeUc8eMvvAILa8qX jXsR5Y13TES1hZGhAUQ9KPirJubrnIWOexoBndW6gEAS6N1awoQEFsTcB7wrV+Ae 7pBQHH2CrtvFYXePNjiWAHdV63uOTXkM8elozBMa0cIVznv4sgKzs9sdJlg9Q+5E iU6zLmEL+zsVgtUczAx5x9nIMRZsqgxlysalqj9GQHlnv49JcR4wyjHSLvuxUVgy YOOsRzpbizjyBZe3w+bo/J4K9covXmLIIHEaNm127Xq/pT/aB79cmRmyzXgD4EQ2 AhP82+c/UVr5GO8PBqPG8pydwMXpT1jzgTmMOwvEhj2hOtqA/HE5cEIpiwgcJOrB g2C1irnApXFTmA6xtPGAZjCAaHHouelNepA9T8x2LvzoOdfXIf6dOX218Y99VLRc Uwj37uyYTaEwbWvyEX7u+nHuKWXN7SaML/IYTv/rGu+TUVAQGlWTg2lJkY6vh/07 1EUmavR/BBUOP4NqmisNS0Xtx8OHwQ92x8+ayRixO3Kh6OC1nJH5Jylr/lqpVxXw HgA/hn/jX4/TWFpmv9JTvxXlYfnRr9UccEncK9/28eUz+CcAEQEAAYkCHwQYAQoA CQUCS2dVdQIbDAAKCRDpEoeCL9uBsRwVD/4ogReEt1w2ODA3SsypnrCettQtnV4J Vn7zjvDK0v0U+xZ+tB7VvUqkY7dQ4RmzhxETnORUZNgCWLZ6fs5Us2RB/yoOyYSJ c+SBN3YEpbFBwLBLoGlZTGsJPktYNo+nQ9KEIZ+OHFnhXGJLqBknMn0vu6T+pQv5 8hJzrfOh98TCtFLmKfZGGwoQfKeDAMEo71T69Yoz1NSSFHr5o39iHff8+mhp1WL1 hsiJI6MOlaUZAwNI1CRebZPQofvydTH+LWsBna1oAiFrO4KcorBJI/gUfGO1mmBq l5qjtoxhq5Tr2oBQtFoqbUaXJcwbDVxLSQhk6omNjNlolsRXj6TBy1eTFgd4Ww0Q B5mYo8cc8Et0wlzZ3UyhD2ix6EnKxWUqj0oFPIVzFfuQ/whmWuqBiMZcAN9RhCGP aovv1v0jP1i983QWptUwpr0m2UjxblFUz2GiQ9sXPCi1Cko978LKCiVseCKVEmbG fWdpq/h+sM4GokoYwa6ak5B5Dyu9/JywTAex/DgUvkuGQuBjtipmS84lb+Ah8wkj lxiWgAoxUUnVFRJb9bpH7sRNc8SXfy6dYcCDWURq73JYzPtmCVAE6stD5lSU+YvQ f+QZZLa4u84eh0skgAakDgkeL2cbOg4tzkUo4EmbXR5M0VRk/946s78/JtchwdNB zxrmkygs1IMB6Q== =8P8F -----END PGP PUBLIC KEY BLOCK----- Ron Smeral -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFQlQpsBEADzhLFSQSDlMeW9k8pKy85P0FehiDYE+Dezyq41Ay1i6lAk5OZJ BhI5FVDUQ8SC0pEsKwS77NAXVwV9PF2M0oH0NPFBXbMXlGdJxJasaMHOP52NE8IQ 6narUH8bAD6BONxxSdXonkjHjTIV3SlPmKlM7ub4FvX5snvrmUb39urlvF8Fpr0u QmykxwUk1Eg/n6l9pWMbRNhyc3caSEz7ASVwuLcHLLrhNYYQxTXePGMhxgwOnz+W AsI0UfJFqMOXDEWjT5XJ2oMcXUaG26ubn2J/SMPud/NzK3TbqpAbf48IL+lRpzGr CgWQRejwwOTha0bbLl+Yjl5lFgOPsY/Oz3pNpXSIrwvwIyWtiBmmKqaD6K8H3rTd kLkH3qWGNh6DBm9fLy2xL3sWRFuYLsQkP2ngF55QviuXWxt9Unsi2PL8BYD9QNLO 4eWvWoymkNXniGhZg5wMu6hzzpY51DWs1JoCZ3pc9kN4zjBrRlxS2t+NcGC4K4h4 StAvkNUZphgStvdwkrs7IQDZoUHJ2JPUWBI9HQT15urN6DK+ENPfDRnSJ1fxenKd C+4OOhd49N0u02CY6yR3lAmm8VlHDmF2uSq5EMJD6dAgDN3Egf+H8LOZGqd1498e F7nB//uZKUQ00jMf/Tk6YWuQo1Ty/SCJYpaXFAfftMbYoP8WMCFXokodNwARAQAB tB9Sb24gU21lcmFsIDxyc21lcmFsQHJlZGhhdC5jb20+iQI3BBMBCAAhBQJVLZas AhsDBQsJCAcDBRUKCQgLBRYDAgEAAh4BAheAAAoJEFEj7Ky6sLYRoocP/2YJ+orF /wrhxKOxGMdnPy553mZS/ZuU9Tfy0JgMf2q5pIuM9sTKopPrT/Fhi4Ja22z7IJTa WT8p5MeNkui8gNgfJ44Mvy7IJfAn8IvdlaAFxY4S8jd6jIvfWonpeDLg81Tv7iyE yg4L/MtKqdC2/bdeyyPtw0QaRbiikOiQ1vdutTSBJrM0OY4kJcuc5Ca4pKSIaSUt 2v3t8kpoNdIjricBOgK9wYCi/hb2996mdn0hZG0/E7B0S+KiDChmcNyaTB4Cxwzr mlkXs2OunjL8Zm5elT3iXnHeJOuklHHQnJ4OdC8bUwJMCkup7UwtE02E6/GGVccO btJWYaqx6PVuW8BVSjnxMPbYq5+cZtTdaB3c+7izzVoXVsUlPpX4sJK5Xxdn32Sp D8HUwd0pp+sZi0Rrpk1ttvEr8PVXZRi5PALSffMuPGwrYzxaGJyhc6cEZDBmDtGa PPcMOc7tM6krTGtgbXwGZHuINuFw9i5Ul+qFRLmIneThOPXqc1bZZy+AxiaC8unv 3KxfZb4KGOjhv8NScSTp+p+cyrEC9T55L8a6r6a/+ASqQn3+31iswcqd0nbvFlXj m17pG2AzE+PVfUNYUvppr9LECFI25Wr5mPf2Umq1KcFsnUMBvXuW3DVWVdj1kYCj /rsIPEFndIp5bHa/GjloWmxN4bjn9ta1QL75tCFSb24gU21lcmFsIDxyb24uc21l cmFsQGdtYWlsLmNvbT6JAjkEEwECACMFAlQlQpsCGwMHCwkIBwMCAQYVCAIJCgsE FgIDAQIeAQIXgAAKCRBRI+ysurC2EVgpD/95ZWYbB7Am+ta5vjewWyvIl/6+cLs+ iGCQzY9QaYPMTCoa4vCeoO5qJ7/duoT3iffDaQ3npS5eafNOFY9Lw1yvoDaEePZa c27w3razXfZaX4ZWyKTceVlmCd9MiQTPHuOrWTLBUNoFB54aZ1+8TlUD9bn5N4KD ZZ5H4Htlg5Ni5CJAlEC9zFznqFoMsLUaf0J8WsL9Kvt+uI+/97/mAQIdE/F0dlsk pCe/Gu10ebvRGSjPclN0bagkG4s93TwTAgS/pntvLFmn9TySfmFKPyIyOWIyWz2L r5AvJhHjA1w/8/LWaV5FVPQkHt9Ls7MpVrzvIEGJnHE3sJZea0/D7gPvpjC1EomA A6D3SjCObUyB3imRkiPGhkZRe9Gh1durDziUen4aAW8TjYGPXysEnjxJUs61iDXx BgvBlNdyvlS1EXfCVVh3N9FgauZ1QFr9KqoRR+2qLI1+kze3OuStMsAiJ+zSvPbC tqov0QtPTaQqVjKyrfl/+yxkxGW6wkIk/NunptUOFr0FZgklD2vz2cKNJvP4WKsL NSEEjTnZXX5KiC+Xi0G9H+ONoZ9r+fFFq7K9IPeTZS68AW4qH7cgUqSV4D927rV0 xRfisfw6M6E1Cc1UOd8n+3+BNER+m+/wGmFuOts3C6jw70tYLB5d+iJdQSWDk80X 9tMJ0TMwIxjrhbQfUm9uIFNtZXJhbCA8cnNtZXJhbEBhcGFjaGUub3JnPokCNwQT AQgAIQUCVTYOpgIbAwULCQgHAwUVCgkICwUWAwIBAAIeAQIXgAAKCRBRI+ysurC2 EXNKEADvGy5PDTF7XeRgcGY5eo7NVdWHwmUVURlY8uuRBR1PULC97S4CgI7Kxra8 hZ+BzHUrfWEU0ILisPsBK6C8XFFBPpqqhw5DEdnSKI5fh27MtsNrMaNX4dp9+hDY nyxlpj0gdXbNtOy8Cehot9ZDHE/OIfE+QbazML6ObC/TM0hETOjLK4P48HbYiWYO Zs0uVyZ1L4K993O/iIsuFWQPbWDTH6lXfaXmE/omqVtodhme3ORqp6WK3+knd1yk stPzVzhyrdigDeL+AsS2GiZTC2u7sNH8ZvgFpDZP9q5FU/nIfyMnlcQzFkunqGdI M+L0CCzZ6wKOs5j9T2PbwI5iPX4YMnoqPgem0dEYuxM8SrZGjpBAxAc+JlDrEwEX +OZndhB9Ap/DNNaMsWxKI5bzbuvT8hvB7sbBn8JhX77JfI0pMLwegWU56HpRE+fX zIQzwu5sKXwzXTRSYMRktnkynjf4bybZ+rg24fmZ5DiIMYEjxMuFa8mcK0AQWqf7 H4r51n47tu4VtHy612pWxCEW3V5V7qya+Pu9dze1hBDREBryB+6EPAI/7fu3BIon JAXMisby8OdmI77Nd09wyBn3j/OodW8khIKbvWNguq+jCalnzhHQGBXEUoiG0N0a AbOZqcP+dbROensiguEy7c8kyc8pTQypxzG4Kwtz8uLzQelw6rkCDQRUJUKbARAA pDvgTDKmLaIxhXqHbNWlsy34MvsLbdlGw71IF/0+rVpe2Z/eDAu5xMtnvUREVjnk fen4S7G8JlpixrZHz/PTrjN0CUnKiZuPeD6Yx5T2de8eDbV5Gs84ia5pgGQL/dJk rBnwhtt2Ayk7XgEGtHYG+OVObf7lLDvhESzBIvqE0/KNyQWJU8q+MCAUOwl4wO5g DvgG0dPx4PnkqU/F8YYw1sSiAryo5PTMEsZ3vEGUhbxdEWgnjcwuFbJq/O2U+lkv FgCYq7Py93JiInRAN8muly+HI/jEpEq0u6mYIeWxDK0iR9LNvcB2o74rYNk7d8S8 4OQkDdWriH0NzrzX4NuxpZoTwxZj6T7lqa5zB3tyR/CvIlL8QYdk0tq5c0P4/yUX 7q70duHwkBTuwCIrsjW5sriv85x7ErOJ1AUg/GZVU/DNWvEUq+PEygGcaWPcAqZ5 y3khuu0lLdVOzRXuomGPzyihW2mbP4TjuKny6eOfR0uAxuDRC1d0NZ/Hl6fMxasA n5beJB2WaIGm1fFMNt1BkicVjohcMZ/yPkEtK5uHTQREHBXvTc5DPm+mr3d1sglx sRpAriPE454bVWpEQYfg6LbKLPSHVg1hHivZCvlL/Q4I+23ao3n++pCg9pMytTNc C1+bd+ZeFaohgmlQ6XE1yx4PtQFQGA01cD6wVh9N2jMAEQEAAYkCHwQYAQIACQUC VCVCmwIbDAAKCRBRI+ysurC2ESZ3EADPYWDdoGQliTLeOtH6Kgxx0gOVizr44yvn A1Duj4AByCOLRffpHbltDFg4mpTIcpF1OsiPRl2Cz/FTUEKfLoJ0J/B92szLwlqf m2NMOFblqGCzeQ5BBR6oWzxfNkmr5gGTZqHzRDRLbv5CV4ZsT1Yb76nYy7l6JIOw OOeGoTAjIbxhQr3MzvQ6a2A3vydQGkBlPfMFE6fjZw71U3pwMniNh+QwT6vh6h03 s4UhrjTezw9ZBjhUuuXtERyXX+LSpdqANw1kGAkZS8uDXdQD2UmYO7x511S8zSL4 Fng8rE2TlgIHRv4GEnOujTo128BN3Ml+y+/M3pcUTnvasd+DlT/vILWLt2xrAh9V aVZedGC60n/ft80yhwO55FThl66XAIjYA8MRLbLNfgBlBi4oFLIqJ2QkVPn1uAeP 5pgDd6rmvHsPXH99UcIuA4pKU2vFsA7YMBkDlunHYtyoyy5r7r3TWMvAuV5SWvsk rHAKB+hVbNdhPo1BMbXoqHKcrdz8UV4THSyvcGJpqph2wtWcywigP4n9/cC+nd7b 3WthIWfJ0JrhnrSBn+SzJBlHOEBsG77jXd07hjcWVLpZsiMaEsevLCStHAogwBvY Z2iU24ZKLRKYA0/sO2Z7QCtnfT6yNwSsEvIM35fe4C5UK960SSRkJja8cpwjmrp9 K65CLoYVmbkCDQRVLZsKARAAu8ELHJVwC5C1oCbiaF+pef56mvaqqahWo5ld1sMh lLqHeQZ+nhnNe/6MP4bSR9qe66yKrn9sAeClvZgh7A9g1dEASVedWAyIUK9v0t3U ewRUAOknRkmpfjKbFLtTpzKwRdJvD899yk4f8TiurdUOim4PgSvEfcZ6q8OSB+5K HSZIGoM6+GtXJZYDsaQuOCF7pbu0VJaNRxkExPf3w8c40IYgtaahfJZ0QfbOWfOk vst33kh6TXZL/0vO2rDe4YLH1v0qHbf3rZqe3uMksVN3J/6JBIc2/sjaW8dcxPdn T3ouCq8501rJrUYIMENGtJesRaCqkGFet53bu+GGanTscxXWH2vOKhnmxqIZMOq/ xth/x0r4gdd1wxXdYT8PAVdnISkspKtHk8y4CXGwqVjZxuGFrgjKa0EhBbxloBCm No/ueVNvIE0Mp1wrl4dO+aEMZzXyPOrc+LSfH/BhuSo0uaA5FNrNdiuh7vbJNtzD VLjT1nKn1Ug1pV7o6Ir5SCYbpTkZg4ho2b1K4uN7u8RINclps5Ry0E6VMSm7fohi lyiCefWKz8zlPvcJ5pgiFqGe2F7elpLHOPMIldPYFRr4WKATS20548TlkltNRuVI YCvH6YBDOyISQWgTfYnphtcv4wtF9J+dWv/I0EF6JsK8296cvdj5ovolhof04MEp 9mMAEQEAAYkEPgQYAQgACQUCVS2bCgIbAgIpCRBRI+ysurC2EcFdIAQZAQgABgUC VS2bCgAKCRCa9YNvIENXIQrpEACBYKEE0VOCYP08Q5JzM0BOhH9vgc5tx59tE4Hz iTYWiPxd39q/5Wvftu4sXlKm7Jf0khTba6vToxalJmLqXGf9nf2L28CxkSJLccL0 nUKQP22Sk9MP/O6UHzev6WafommQk/ix+hFhLkOzuT6WxHBVpEh0PUzTZoxrO3uR tz7OrQpNAR+3l0RLsb0W5cg/ykuV2d9h41HefPYvqoL8UIYBvLO2F+HZ2UCtDQRs k/thJbROw5GZJgjSCUkJfsWkJMgk8Pm0muwk3LuC8tzhEDEYSVUeYnHcRWr8sVZj nyBwlEITjiyxiCnS75HfTnaVv3ZTL5YkZlNybQJnDglscHSQh26l3OeUywLzA9Tb ymUrJdkEPP9rf6MSF3THVkR7RTqpLN26hUX+HcYVy3yL8C6RuBwR2xnKaHxTXFD2 7NHXpl7vaM3odQ7ltL6BhpYEcprgADcqRZNOoAtd/3hd2Ts7CgTs39kwmSil7LSd L8+5N8KmTxK4nIeWEyS0F4Y9vOEAh87kBTh68aI4smbPJFbf/BCLGy95gdTgp0zA zHIdCu3AvRsFNn/uKJLK05xkJ9jJL3TOJM3jDS7iod6/MHCBUdW4z6vB7zPgm3sy +g8itI+S8RgGwrr1tVbWGstPRQbDFC6jvsiREYBS1c1KDr1Vh+wsgqjSst64pjlR Qydni4V6EACEHjP2u8WrY8BfssjLProtHBI64Ce2q9At3KAcT79H0npuBfX/GEpc l4LTvXjH2tAQym8enqUotXsXa57hmOVvqYYUeDrbNL80g5c0THalvbzmqwcrUvag TtqxKhi2Wqgr5nPK4/uoqgPQQ+qKuwTpImIpxgwAEpANaBPMWf/frnz82nBbmJFd 1xcI057kUm3fUz5AaGmciPHzPmj/oTprSGMIbjXDupuBwQjB2YpLydrNtZ5lE9JK QZ/HBboeC0QGSQHuKyB+5X4gbZuYR3CWcXdw7SOdnsg/Stm9X54XGB0+YtnORo3t X11MPOE3wyAIO+f7VFpZZEsf+5Y2iHwVSPhi1KZL8WDiRKZWuQy7DoZh9z8xGDRt frxiVNS0bPPfyepxxkrXO4OFRz+r63z5DbqCQBj13oDpo6ZOMb+ki67RARQMdqlW UyehzUrMXWHnjkwWWlDfl6kkJQT4aQB0J0nycb+sLnX3nK85ntuQF4XKOF1qc7S/ 1TLLedj4oSVkR6lsAm614U7JqCyQCTvRjhRB2RkWjbJEqYKi2Vh/8/m/Z9LWiZVc igD2l3a2liQPyFsXevVT5IJUUm9xUeuTnEw3TC5KsRkxLLBD4/9cqwNEeiw3299L NeHfSttzBO+0HisGUdYEoWP5HrIJc4BEUPzceOGe6BeX6l0PmT3Uvg== =CfmT -----END PGP PUBLIC KEY BLOCK----- Daniel Cunha -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1 mQENBFVu6bMBCAC1epJGKU7YAb6wz8JahM/X9pmyVEDA/YYdQF+YM/XQsKi4CuL+ gnoou+9hDGN5OCHu+bp/VUjk19YgAuSWcpLYIdMzv1gyF3LRDTUcyY4gHGxsQ+Kj 3dQcJS3AhRrrXGzJlujx+mp+HqsFpy6eBWYpzn7k2aWtOUUb/z8FaNOnIYzdsK8O j1ndY1T2s3tqdYR6ZPU7pTE2uV78O2sqo5S3xmecF9HTE/ocAOAGmKDVOO7SrArJ 4Gn7ElVbP7hPF1sp3f335BCJVnLEZ0Hh4Hwt8fwag2xVxt6l7RfR6nskGokt5u8+ F1GQ9SHCpZiAnLYpsGAxmROKDcSl56kNehBhABEBAAG0JERhbmllbCBDdW5oYSA8 ZGFuaWVsc29yb0BhcGFjaGUub3JnPokBOAQTAQIAIgUCVW7pswIbAwYLCQgHAwIG FQgCCQoLBBYCAwECHgECF4AACgkQi5zCuRk2g+TnzggAoTsal2mWB5KXLjQfm6qW BsKqj0QFvTsNUHzYbc5MtTlrkHFubcx+GW77M1I1kdzJnZPvHbqQslUTyKNz7WLO ger/oF1AVOvkl5SuX1ecF50TuSd8quMEHGtECWZr21T9rBSdVfzKoy24S9R0oF2u 8V5IPpY1jbMCjbITclY3rjXArv34gT59ALqr3h3C++zsyqwhZTC8x2eC8Qwmn3M7 dKW1lodIbT4OE+/XzkKpE/WFlNhT5lmtKawhnsK+lnEoxlCoOD0Kchh2RO9R2K01 tH1r8Ul/BaS7eTg/UARclX0Cp8CmC4rdk6ZvvmBn2OmYLWuspaxJ1gcTc4he/PXf 97kBDQRVbumzAQgAzvz0N1xFgfyyH7tqe1WIMOftNIWV+3NtpckRZYN6fFgt8XMM ExgZMR7Q5V4o9akRS9EWmIoAEIqb0JZ5lLC2w0Fzc7FBHjTaa5zat2JIBfChoMw4 azut7qwKvUk8RwkTrl2mn6nQLxkVVu5iJoZZomHbju0u7uVOXuChv6mmDqyKg6Zz gVJRv662rk9/bRH+A6dLwe+Kskvu2CR0FqeFw+UgBCx01wZ8pxATzgW2BxM+YYki dgPHb9hwsBlLBXFlOzNUozxsEIvbUSS7XLXIfaZh6JXxdJsqIT9kscVCfUcHsD20 SY4XQPgB9HOMHTVdY3JvFy3yLQP1U6CLRvmahwARAQABiQEfBBgBAgAJBQJVbumz AhsMAAoJEIucwrkZNoPkjTwH/0HZHkzSWIDdyCUFctUmbFW5qTnsN4qofpj2m4IV CKqB9OZcYK9TlK958mBEo2tmalzmuLcmTf93Hw1z5bMR7QETI1dcH25xxQrzuJm5 hf8Np8C2xfhHa3N9eoxjICt3+BsUZOu5bAahDcRa89A0KS7UMPx5Ue6cYu1EZTB0 kXjhUqyw+zc6k8Ca4tWzzPLqOQOcXZuv2x0tOprm8tyEJ89g+ddaUA4rvz9Q2uLW bahaZr/WJ9nmLWFm2nG1BPzszF/AWKImSbg9HkGA0Ye1CjTaViAqoYrVbUT/Q81r 36ERRFbtxEUCunGG5F9EcIvZaazqxmdXz8I2SDymz6yO3JI= =vfLb -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: pom.xml ================================================ 4.0.0 org.apache apache 38 org.apache.deltaspike deltaspike 2.0.2-SNAPSHOT pom Apache DeltaSpike Apache DeltaSpike CDI Extensions. http://deltaspike.apache.org 2.2.6 2.0.1 2.0.2-SNAPSHOT ${project.build.directory}/co-site 11 11 scm:git:https://git-wip-us.apache.org/repos/asf/deltaspike.git scm:git:https://git-wip-us.apache.org/repos/asf/deltaspike.git https://git-wip-us.apache.org/repos/asf/deltaspike.git deltaspike documentation site org.apache.maven.plugins maven-site-plugin true true org.apache.maven.plugins maven-scm-publish-plugin ${project.reporting.outputDirectory} scm:svn:${svn.scmPubUrl} true true ${svn.scmPubCheckoutDirectory} deltaspike-site org.asciidoctor asciidoctor-maven-plugin ${asciidoctor.version} src/main/asciidoc ${project.reporting.outputDirectory} html5 erb true ../template true true font ${version.deltaspike.latest.stable} ${version.deltaspike.latest.snapshot} coderay ./images org.apache.maven.plugins maven-release-plugin false true true clean install ================================================ FILE: site/README.md ================================================ title: Apache DeltaSpike Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. DeltaSpike site --------------- DeltaSpike site uses [Asciidoc](http://www.methods.co.nz/asciidoc/). You're welcome to contribute. License ------- Apache DeltaSpike is licensed under ALv2. See the LICENSE file for the full license text. Publish procedure ----------------- To publish the site content at [DeltaSpike Site](http://deltaspike.apache.org/) you have do the following steps: Put the following information in your ~/.m2/settings.xml file deltaspike-site To publish to [staging area](http://deltaspike.apache.org/staging/), run: mvn clean site-deploy -Pstaging To publish to [production area](http://deltaspike.apache.org/), run: mvn clean site-deploy After log in to and click on the `Submit` button. ================================================ FILE: site/pom.xml ================================================ 4.0.0 org.apache.deltaspike deltaspike 2.0.2-SNAPSHOT ../pom.xml org.apache.deltaspike deltaspike-site 2.0.2-SNAPSHOT pom Apache DeltaSpike Site Website content of DeltaSpike project. http://deltaspike.apache.org https://svn.apache.org/repos/infra/sites/deltaspike/ org.asciidoctor asciidoctor-maven-plugin output-html site process-asciidoc . org.apache.maven.plugins maven-scm-publish-plugin scm-publish site-deploy publish-scm ================================================ FILE: site/src/main/asciidoc/addons.adoc ================================================ :notoc: = Add-ons :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Add-ons extend the functionality of DeltaSpike and several have been developed external to the DeltaSpike project. Brief information is given here about each of the add-ons, with details of where they can be obtained from. == lbitonti@github This GitHub account contains e.g. a DBUnit Add-on for the Test-Control-Module of DeltaSpike. **Source code:** https://github.com/lbitonti/deltaspike-dbunit == os890@github This GitHub account contains several DeltaSpike Add-ons e.g. to integrate CDI with other frameworks. **Source code:** https://github.com/os890/ == rmannibucau@github This GitHub account contains several DeltaSpike Add-ons e.g. an integration with the TomEE PasswordCipher API. **Source code:** https://github.com/rmannibucau/ == Monitoring `ds-monitoring-addon` provides simple monitoring for several common use-cases (exceptions, performance, audits), collecting information about the monitored method-invocations during a request and enabling you to process the entries based on your requirements. For more information about its use and implementation, see http://os890.blogspot.com.au/2014/04/add-on-monitoring-lite-with-deltaspike.html[os890: [add-on\] monitoring lite with deltaspike]. **Source code:** https://github.com/os890/ds-monitoring-addon == Spring Bridge `ds-spring-bridge-addon` is a two-way cdi-spring bridge that allows spring-beans to be injected into cdi-beans and vice versa provided the concepts, for example qualifiers, are compatible. For more information about its use and implementation, see http://os890.blogspot.com.au/2013/12/add-on-spring-bridge-with-deltaspike.html[os890: [add-on\] spring-bridge with deltaspike]. **Source code:** https://github.com/os890/ds-spring-bridge-addon. == Disruptor `ds-disruptor-addon` improves CDI synchronous event-processing performance by creating a disruptor process for every observer method, enabling CDI synchronous events in conjunction with asynchronous observers. This add-on currently works with Apache TomEE and JBoss AS 7. For more information about its use and implementation, see http://os890.blogspot.com.au/2014/05/faster-cdi-like-events.html[os890: [add-on\] fast event processing with disruptor + deltaspike]. **Source code:** https://github.com/os890/ds-disruptor-addon ================================================ FILE: site/src/main/asciidoc/articles.adoc ================================================ :notoc: = Articles and Blogs :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. You can find lots of content related to DeltaSpike with a quick internet search. But here is a list of some useful articles and blogs to get you started. If you know of useful DeltaSpike articles or blogs that are not listed, link:https://deltaspike.apache.org/community.html[let us know]. == Ongoing * https://twitter.com/DeltaSpikeTeam[@DeltaSpikeTeam on Twitter] * https://twitter.com/hashtag/deltaspike[#deltaspike on Twitter] * http://os890.blogspot.com.au/search/label/deltaspike[os890 DeltaSpike posts] * http://rafabene.com/?s=deltaspike&submit=Search[Rafael Benevides DeltaSpike posts] * http://rmannibucau.wordpress.com/?s=deltaspike[RManiiBucau DeltaSpike posts] * https://struberg.wordpress.com/?s=deltaspike[Struberg DeltaSpike posts] == One-offs * https://blogs.oracle.com/theaquarium/entry/introducing_deltaspike_1_0[The Aquarium: Introducing DeltaSpike 1.0] * http://blog.arungupta.me/2014/06/deltaspike-1-0-extend-javaee-techtip32/[DeltaSpike 1.0 – Extend #JavaEE beyond #JavaEE] * http://www.tearsofaunicorn.com/articles/2014/06/10/configuring-deltaspike-through-environment-variables.html[Configuring Apache Deltaspike through environment variables] * http://blog.ctp.com/2013/11/27/bye-bye-cdi-query-hello-deltaspike-data/[Bye Bye CDI Query, Hello DeltaSpike Data] * http://rmannibucau.wordpress.com/2013/11/20/deltaspike-data-repositories-with-dtos/[DeltaSpike Data: repositories with DTOs!] * http://jaxenter.com/introducing-apache-deltaspike-42925.html[Closing the Gaps: Introducing Apache Deltaspike] * http://jsfcorner.blogspot.com.au/2013/01/deltaspike-jsf-message-system.html[DeltaSpike JSF message system] * https://medium.com/danieldiasjava/simplificando-persistencia-de-dados-com-apache-deltaspike-data-6fd27bb2d821[Simplificando persistência de Dados com Apache DeltaSpike Data - PT-BR] * https://medium.com/danieldiasjava/conhecendo-apache-deltaspike-configuration-a24516468a9b[Conhecendo Apache DeltaSpike: Configuration - PT-BR] * https://medium.com/danieldiasjava/conhecendo-apache-deltaspike-injecting-resources-fa4e5585c2ea[Conhecendo Apache DeltaSpike: Injecting Resources - PT-BR] ================================================ FILE: site/src/main/asciidoc/community.adoc ================================================ = Community :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Users If you are a new user and you would like to start using DeltaSpike, you can have a look at the link:documentation/[Documentation] and mailto:users-subscribe@deltaspike.apache.org[subscribe] our mailto:users@deltaspike.apache.org[mailing list for users]. If you have troubles to find the information you are looking for, you can also ask in our link:#_irc[IRC-Channel]. Furthermore, you can check our link:#_mailing_lists[mail-archives]. Before you file a ticket in our https://issues.apache.org/jira/browse/DELTASPIKE[Jira], please ask on the mailing list if it's a known issue in case of a bug or if there is an ongoing discussion in case of a feature. You are very welcome to follow our twitter account http://twitter.com/DeltaSpikeTeam[@DeltaSpikeTeam] and spread the word of DeltaSpike with Tweets, Blog-Entries,... == Getting Involved Everybody is welcome to get involved with our community. You can find general information at http://apache.org/foundation/getinvolved.html and http://apache.org/foundation/how-it-works.html. The following sections provides some details about the different levels of getting involved. If you want to contribute with link:/documentation/[DeltaSpike Documentation], please read the <> that adresses how to contribute, render and publish it. === Contributors Before you get a committer you have to contribute to our effort. E.g. you can help users, participate in discussions on the dev list, submit patches,... . For bigger contributions, it's essential to file a/n http://www.apache.org/licenses/icla.pdf[ICLA] or http://www.apache.org/licenses/cla-corporate.txt[CCLA] and send it to secretary at apache dot org (or fax it) as early as possible. If you would like to submit a patch through Jira, you can have a look at the link:suggested-git-workflows.html[suggested approach]. === Committers Before you read this section, please ensure that you have read the contributor section. All of you are welcome to join our development effort. mailto:dev-subscribe@deltaspike.apache.org[Subscribe] our mailto:dev@deltaspike.apache.org[mailing list for developers] and start contributing and help users. Optionally mailto:commits-subscribe@deltaspike.apache.org[subscribe] our mailto:commits@deltaspike.apache.org[mailing list for commits]. Furthermore, you can check our link:#_mailing_lists[mail-archives]. Further details are available at http://www.apache.org/dev/. == Mailing lists [.table] [cols="6*<", options="header"] |=== |List (Address) |Subscribe |Unsubscribe |Archive |Mirrors | |mailto:users@deltaspike.apache.org[User List] |mailto:users-subscribe@deltaspike.apache.org[Subscribe] |mailto:users-unsubscribe@deltaspike.apache.org[Unsubscribe] |link:++https://lists.apache.org/list.html?users@deltaspike.apache.org++[Archive] | | |mailto:dev@deltaspike.apache.org[Developer List] |mailto:dev-subscribe@deltaspike.apache.org[Subscribe] |mailto:dev-unsubscribe@deltaspike.apache.org[Unsubscribe] |link:++https://lists.apache.org/list.html?dev@deltaspike.apache.org++[Archive] | | |mailto:commits@deltaspike.apache.org[Committer List] |mailto:commits-subscribe@deltaspike.apache.org[Subscribe] |mailto:commits-unsubscribe@deltaspike.apache.org[Unsubscribe] |link:++https://lists.apache.org/list.html?commits@deltaspike.apache.org++[Archive] | | | |=== == JIRA Any kind of issue has to be filed in our https://issues.apache.org/jira/browse/DELTASPIKE[issue-tracker]. If you have any question, you can ask us (e.g. via the mailing list for users). == Spread the word You are very welcome e.g. to write blog entries, tweet (#DeltaSpike) about the project or just follow our twitter account http://twitter.com/DeltaSpikeTeam[@DeltaSpikeTeam], ... == IRC Usually discussions happen on the mailing list. Some informal discussions take place in our IRC-Channel irc://irc.freenode.net/deltaspike ------------------------------------- //with the irssi command-line client: $ irssi > /connect irc.freenode.net > /join #deltaspike ------------------------------------- If you are new to IRC you can use the pre-configures web-client you can find https://kiwiirc.com/client/irc.freenode.net/#deltaspike[here]. ================================================ FILE: site/src/main/asciidoc/documentation.adoc ================================================ :notoc: = Documentation :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Sources link:/documentation/[DeltaSpike Documentation] is available with <>. == Format The format used for DeltaSpike documentation is http://www.methods.co.nz/asciidoc/[ASCIIDOC] because it's easily exportable to PDF, HTML, and it's also easy to contribute. It can be used to export also to epub and also be used to write books == Rendering documentation as HTML _Requirenment:_ Have http://maven.apache.org/[Maven] installed. If you cloned the source repository and want to render the documentation as HTML, you just need to run the following command: ---------------------------- $ cd REPO_ROOT/documentation $ mvn site ---------------------------- The generate documentation will be available at `REPO_ROOT/documentation/target/site` == Contribute If you would like to submit a documentation patch through Jira, you can have a look at the <>. == Publish procedure (for committers only) If you're a committer and want to publish the documentation at http://deltaspike.apache.org/documentation/[DeltaSpike Site] you have do the following steps: Put the following information in your ~/.m2/settings.xml file [source,xml] -------------------------------------- deltaspike-site -------------------------------------- To publish to http://deltaspike.apache.org/staging/documentation[staging area], run: ---------------------------- $ mvn clean site-deploy -P staging ---------------------------- To publish to http://deltaspike.apache.org/staging/documentation[production area], run: ----------------- $ mvn clean site-deploy ----------------- Then run: After log in to https://cms.apache.org/deltaspike/publish and click on the `Submit` button. ================================================ FILE: site/src/main/asciidoc/download.adoc ================================================ :notoc: = Download :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. https://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. == Latest Release v{latestStable} == Prerequisits Apchache DeltaSpike-1.x supports JavaEE. The minimum JavaEE version is JavaEE 6. The minmium Java version until DeltaSpike-1.8.x is Java 6. The minimum Java version for DeltaSpike-1.9.x is Java8. Apache DeltaSpike 2.x targets JakartaEE. The minimum JavaEE version is JakartaEE version is 9. The minimum Java version for DeltaSpike-2.0.x is Java11. == Binary Distribution * https://www.apache.org/dyn/closer.lua/deltaspike/{latestStable}/distribution-full-{latestStable}.zip[distribution-full-{latestStable}.zip] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.zip.asc[distribution-full-{latestStable}.zip.asc] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.zip.sha512[distribution-full-{latestStable}.zip.sha512] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.zip.sha1[distribution-full-{latestStable}.zip.sha1] * https://www.apache.org/dyn/closer.lua/deltaspike/{latestStable}/distribution-full-{latestStable}.tar.gz[distribution-full-{latestStable}.tar.gz] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.tar.gz.asc[distribution-full-{latestStable}.tar.gz.asc] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.tar.gz.sha512[distribution-full-{latestStable}.tar.gz.sha512] * https://www.apache.org/dist/deltaspike/{latestStable}/distribution-full-{latestStable}.tar.gz.sha1[distribution-full-{latestStable}.tar.gz.sha1] == Source Distribution * https://www.apache.org/dyn/closer.lua/deltaspike/{latestStable}/deltaspike-{latestStable}-source-release.zip[deltaspike-{latestStable}-source-release.zip] * https://www.apache.org/dist/deltaspike/{latestStable}/deltaspike-{latestStable}-source-release.zip.asc[deltaspike-{latestStable}-source-release.zip.asc] * https://www.apache.org/dist/deltaspike/{latestStable}/deltaspike-{latestStable}-source-release.zip.sha512[deltaspike-{latestStable}-source-release.zip.sha512] * https://www.apache.org/dist/deltaspike/{latestStable}/deltaspike-{latestStable}-source-release.zip.sha1[deltaspike-{latestStable}-source-release.zip.sha1] == Maven Dependencies Details are available https://deltaspike.apache.org/documentation/configure.html#MavenProjects[here]. == Previous Releases See https://archive.apache.org/dist/deltaspike/[Release-Archive] == Verifying Releases It is essential that you verify the integrity of any downloaded files using the PGP or MD5 signatures. For more information on signing artifacts and why we do it, check out the https://www.apache.org/dev/release-signing.html[Release Signing FAQ]. The PGP signatures can be verified using PGP or GPG. First download the https://www.apache.org/dist/deltaspike/KEYS[KEYS] as well as the asc signature file for the artifact. Make sure you get these files from the https://www.apache.org/dist/deltaspike/[main distribution directory], rather than from a https://www.apache.org/dyn/closer.lua/deltaspike/[mirror]. Then verify the signatures using e.g.: [subs="+attributes"] ------------------------------------------------------ $ pgpk -a KEYS $ pgpv deltaspike-project-{latestStable}-source-release.zip.asc ------------------------------------------------------ or [subs="+attributes"] ----------------------------------------------------- $ pgp -ka KEYS $ pgp deltaspike-project-{latestStable}-source-release.zip.asc ----------------------------------------------------- or [subs="+attributes"] -------------------------------------------------------------- $ gpg --import KEYS $ gpg --verify deltaspike-project-{latestStable}-source-release.zip.asc deltaspike-project-{latestStable}-source-release.zip -------------------------------------------------------------- More information can be found at the https://www.apache.org/info/verification.html#CheckingSignatures[ASF Checking Signatures page] ================================================ FILE: site/src/main/asciidoc/examples.adoc ================================================ :notoc: = See DeltaSpike in Action :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. A collection of ready-to-build Maven-based projects are provided to demonstrate the inclusion of DeltaSpike in applications. Each example showcases a different DeltaSpike feature and explores the mechanics of DeltaSpike implementation. You can use these examples to see DeltaSpike in action and learn how to add these capabilities to your own projects. The Maven-based project examples are available in `deltaspike-project-{latestStable}-source-release.zip`. To begin using the projects, complete the following steps: . link:https://deltaspike.apache.org/download.html[Download `deltaspike-project-{latestStable}-source-release.zip`] . Extract the archive contents + [subs="+attributes"] ---- $ unzip deltaspike-project-{latestStable}-source-release.zip ---- + . Build the projects + [subs="+attributes"] ---- $ cd /path/to/deltaspike-project-{latestStable}/examples $ mvn clean package ---- == Next * To see more ready-to-deploy DeltaSpike examples and templates, see <>. * To read how DeltaSpike is being used by developers, see <>. ================================================ FILE: site/src/main/asciidoc/external.adoc ================================================ = External Examples and Templates :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. A number of DeltaSpike examples and templates have been developed external to the DeltaSpike project. These extend the DeltaSpike resources from which you can see DeltaSpike in action. Brief information is given here about the examples and templates, with details of where they can be obtained from. == Books (free/online) **CDI@Work (chapter about DeltaSpike):** http://cdiatwork.irian.at/ CDI@Work is a free online book about CDI as well as Apache DeltaSpike. It covers basic information about CDI and DeltaSpike up to more advanced use-cases. An example for the latter is a type-safe configuration (interface-only) which allows you to resolve the configured values even from dynamic config-sources like a database and store them in a custom Config-Scoped cache which can be refreshed via CDI-events or a CRON based task or manually via JMX. The https://github.com/CDIatWork/[GitHub account] contains repositories e.g. for the sample application called IdeaFork. The commit-history follows the steps in the book. In most cases every commit translates to one step in the book. (Chapters are released once they are ready.) == Presentations === Apache DeltaSpike: The CDI toolbox CDI portable extensions are one of greatest features of Java EE allowing the platform to be extended in a clean and portable way. But allowing extension is just part of the story. CDI opens the door to a whole new eco-system for Java EE, but it’s not the role of the specification to create these extensions. Apache DeltaSpike is the project that leads this brand new eco-system by providing useful extension modules for CDI applications as well as tools to ease the creation of new ones. In this session, we’ll start by presenting the DeltaSpike toolbox and show how it helps you to develop for CDI. Then we’ll describe the major extensions included in Deltaspike, including 'configuration', 'scheduling' and 'data'. **Slides:** http://www.slideshare.net/antoinesd/apache-deltaspike-the-cdi-toolbox **Video:** https://www.youtube.com/watch?v=QbNdFvNPvVU **Event:** http://www.meetup.com/JBoss-User-Group-Worldwide/events/218755922/ === DeltaSpike: CDI extensions of the world, unite! Several popular CDI extension frameworks like Seam 3 and MyFaces CODI have faded out over the years. But not to worry - their functionality is taken over by projects like Picketlink, Agorava, and mainly DeltaSpike, a new Apache project that wants CDI extension authors to unite in an effort to make the life of web application developers easier. Even without a five year plan! **Slides:** http://devconf.cz/filebrowser/download/414 **Video:** https://www.youtube.com/watch?v=2FUNpzd1Nb8 === Apache DeltaSpike Presentation about Apache DeltaSpike **Slides:** http://www.slideshare.net/os890/apache-deltaspike === MyFaces CODI and JBoss Seam3 become Apache DeltaSpike These slides show how to use type-safe mechanisms provided by MyFaces CODI for developing JSF applications which are more type-safe and easier to maintain as well as common pitfalls. Beyond that there is an basic overview of Apache DeltaSpike. **Slides:** http://www.slideshare.net/os890/myfaces-codi-and-jboss-seam3-become-apache-deltaspike === Migrating a JSF-Based Web Application from Spring 3 to Java EE 7 and CDI This talk is a detailed case study about the migration of a JSF-based web application from Spring 3 to Java EE 7 and CDI. It is presented at the JavaOne 2014 conference. **Slides:** http://www.slideshare.net/MarioLeanderReimer/migrating-a-jsfbased-web-application-from-spring-3-to-java-ee-7-and-cdi **Video:** https://parleys.com/play/543faae5e4b06e1184ae423a/about === [de] Flexibilitaet mit CDI und Apache DeltaSpike Presentation about DeltaSpike **Slides:** http://www.slideshare.net/os890/flexibilitaet-mit-cdi-und-apache-delta-spike === [pt-BR] Deixando de refazer a roda com Apache DeltaSpike CDI e DeltaSpike presentation in TDC - The Developers Conference 2015 **Video and Slides:** http://www.infoq.com/br/presentations/deixando-de-refazer-a-roda-com-apache-deltaspike === Apache Deltaspike the CDI Toolbox (Java One 2015) **Slides:** https://pt.slideshare.net/antoinesd/apache-deltaspike-the-cdi-toolbox-java-one-2015 === JavaOne 2015 - Rafael Benevides - Apache DeltaSpike, the CDI Toolbox **Video:** https://www.youtube.com/watch?v=3McmEi3cs_s === Simplificando la persistencia de datos con Apache DeltaSpike Data (Java User Group de Nicaragua) **Slide:** https://speakerdeck.com/danieldiasjava/simplificando-la-persistencia-de-datos-con-apache-deltaspike-data **Video:** https://youtu.be/djM51tlJuLs **Example:** https://github.com/Daniel-Dos/danieldiasjava-palestras/tree/master/JUGNicaragua == Examples === IdeaFork (full) This example is a Java EE6 application which illustrates several features of CDI and DeltaSpike. It covers features of all modules provided by DeltaSpike. There are profiles to create web-archives for Apache TomEE, JBoss AS7 (and WildFly) and Oracle GlassFish3. The complexity is mixed. There are some simple examples as well as some more advanced cases. The repository contains every step (one commit is one step) described in the online-book. **Source code:** https://github.com/CDIatWork/IdeaFork === IdeaFork (lite) This example is based on IdeaFork (full), but without some indirections which were needed to demonstrate different features of CDI and DeltaSpike (in a simple Application). **Source code (beta - work in progress):** https://github.com/CDIatWork/IdeaForkLite_Beta === Confess 2012 Workshop Demo This example was prepared for the Confess workshop and demonstrates how to use DeltaSpike instead of and side-by-side with MyFaces CODI. The secured web application demonstrates presenting users with differentiating content based on their account status. **Source code:** https://github.com/confess/confess2012_deltaspike === Fullstack EE6+ with DeltaSpike Simple example based on Java EE6+ and DeltaSpike (tested with EE6 and EE7). **Source code:** https://github.com/os890/ee6-ds-demo === Fullstack CODI to DeltaSpike This pair of examples show how to achieve the most important MyFaces CODI features with DeltaSpike and also how to migrate a CODI project to DeltaSpike. The examples are basic, compacting core CODI features into just a few JSF pages, and are intended for deployment with TomEE. **Source code:** https://github.com/os890/tomee_mf_stack_001 * CODI version in master branch * Migrated DeltaSpike version in codi2ds branch === JBoss Quickstarts The JBoss quickstarts are small working examples that demonstrate recommended practices for specific Java EE technology use cases. A subset of these quickstarts are dedicated to demonstrating DeltaSpike, including custom authorization restrictions using annotations, constructing and modifying beans, extending the influence of CDI using BeanManager, and deactivating DeltaSpike features. **Source code:** https://github.com/jboss-developer/jboss-wfk-quickstarts === DeltaSpike Examples A collection of example applications demonstrating the features of the DeltaSpike project. **Source code:** https://github.com/rsmeral/deltaspike-examples === [pt-BR] DeltaSpike microblog example Application that shows a microblog using DeltaSpike **Source code:** https://github.com/rafabene/demo_deltaspike === Why you should consider using Apache DeltaSpike Blog post demonstrating 5 features of Apache DeltaSpike **Blog post:** http://www.thedevpiece.com/why-you-should-consider-using-apache-deltaspike/ === [pt-BR] Rest Application with DeltaSpike Data Simple example based on MicroProfile(OpenApi,Payara-Micro) and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/DanielDiasjava-Blog/tree/master/ProjetoDeltaSpike === [pt-BR] CRUD-Deltaspike-CDI-Angular Simple CRUD example based on SparkJava and DeltaSpike-data **Source code:** https://github.com/SouJava-Rio/soujava-rio-labs/tree/master/microframeworks/spark-samples/CRUD-Deltaspike-CDI-Angular === [pt-BR] CRUD-Deltaspike-CDI-Angular Simple CRUD example based on JavaLin and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/DanielDiasjava-Blog/tree/master/Projeto-Cloud/javalin === [pt-BR] jax-rs-sample-cdi-deltaspike-data Simple CRUD example based on jax-rs(resteasy) and DeltaSpike-data for Tomcat **Source code:** https://github.com/SouJava-Rio/soujava-rio-labs/tree/master/jax-rs-samples/Jax-rs-deltaspike-angular2-4/jax-rs-sample-cdi-deltaspike-data === [spanish] Oracle Helidon with DeltaSpike-Data Simple CRUD example based on Helidon and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/danieldiasjava-palestras/tree/master/JUGNicaragua === [pt-BR] Eclipse vertx with DeltaSpike-Data Simple example based on vertx and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/DanielDiasjava-Blog/tree/master/Projeto-Cloud/vertx === [pt-BR] Eclipse vertx with DeltaSpike-Data Simple example based on vertx and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/DanielDiasjava-Blog/tree/master/Projeto-Cloud/vertx === [pt-BR] Javalin with DeltaSpike-Data Simple example based on Javalin and DeltaSpike-data **Source code:** https://github.com/Daniel-Dos/DanielDiasjava-Blog/tree/master/Projeto-Cloud/javalin == Magazines === [pt-BR] Brazilian Java Magazine Apache DeltaSpike: CDI Programável **Online article:** http://www.devmedia.com.br/apache-deltaspike-cdi-programavel/31982 == Interviews === [pt-BR] InfoQ Brazil Apache DeltaSpike, a API de extensions do CDI **Online interview:** http://www.infoq.com/br/interviews/entrevista-rafael-benevides-delta-spike === [pt-BR] InfoQ Brazil O que é DeltaSpike? **Online interview:** https://www.youtube.com/watch?v=jtCuxfPxDE8 == Templates === Java SE + CDI + DS **Source code:** https://github.com/os890/javase-cdi-ds-project-template === JSF + CDI + DS (Servlet-Container) **Source code:** https://github.com/os890/javaweb-cdi-ds-project-template === EJB + CDI + DS (Module) **Source code:** https://github.com/os890/javaee_cdi_ejb_ds_project_template === JSF + EJB + CDI + DS (EE-Server) **Source code:** https://github.com/os890/javaee_jsf_cdi_ejb_ds_project_template === JSF + JPA + CDI + DS-Data (diff. EE-Server-Profiles) **Source code:** https://github.com/os890/javaee_jsf_cdi_jpa_data_ds_project_template === JSF + JPA + CDI + DS-Data (Apache TomEE) **Source code:** https://github.com/os890/ds-data-project-template === JSF + CDI + DS (Apache TomEE) **Source code:** https://github.com/os890/tomee-ds-project-template ================================================ FILE: site/src/main/asciidoc/index.adoc ================================================ :notoc: [options="header,footer"] |=== || *About Apache DeltaSpike* | image:logo.png[image] | DeltaSpike consists of a number of portable CDI extensions that provide useful features for Java application developers. We will also ensure true portability! We are testing DeltaSpike on different CDI implementations like Apache OpenWebBeans and JBoss Weld, and also on different Java EE servers like Apache Tomcat and TomEE, JBoss Enterprise, WildFly, GlassFish, Liberty, Oracle WebLogic and others. link:documentation/overview.html[View details »] |=== [cols="1,3,4",options="header,footer"] |=== | |*Latest Award* | *Modules* | image:DukeChoice-100x176.png[image] | In 2014, DeltaSpike became a Duke’s Choice Award winner. The Duke’s Choice Awards celebrate extreme innovation in the world of Java technology and are granted to the most innovative projects using the Java platform. | CDI extensions created by the Apache DeltaSpike community are packaged as modules. They offer additional functionality not provided out of the box by the CDI spec (Security, JPA, …) link:/documentation/modules.html[View details »] |=== [options="header,footer"] |=== |*News* | *Examples* | Apache DeltaSpike 2.0.1 supporting JakartaEE is now out! link:/news.html[View details »] | See the following examples which are part of the project to discover how to use DeltaSpike project. link:examples.html[View details »] |=== ================================================ FILE: site/src/main/asciidoc/javadoc.adoc ================================================ :notoc: = Javadoc :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Latest version * link:/javadoc/{latestSnapshot}/[{latestSnapshot}] == Stable Release * link:/javadoc/{latestStable}/[{latestStable}] == Contribute If you would like to submit a javadoc patch through Jira, you can have a look at the <>. == Publish procedure (for committers only) If you're a committer and want to publish the javadoc, you have do the following steps: Put the following information in your ~/.m2/settings.xml file [source,xml] -------------------------------------- deltaspike-site -------------------------------------- Then run: [source,bash] ------------------------- $ cd REPO_ROOT/deltaspike $ ./javadoc.sh ------------------------- After log in to https://cms.apache.org/deltaspike/publish and click onthe `Submit` button. ================================================ FILE: site/src/main/asciidoc/migration-guide.adoc ================================================ = Migration Guide :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Apache MyFaces CODI to Apache DeltaSpike === Example Overview * http://s.apache.org/xA[Fullstack CODI to DeltaSpike @ os890] === Basically unchanged parts Here you can see features which were added and the concept itself didn't change (only the packages, config keys,...) ==== Project-stage Only the config key changed (TODO) ==== Deactivatable and ClassDeactivator The concept hasn't changed. ==== CodiConfig The concept hasn't changed. ==== Annotation literals The concept hasn't changed. We just added further implementations. ==== BeanManagerProvider The concept hasn't changed. We just splitted the functionality. The util methods are available in BeanProvider and their name and signature have been unified. === Extended concepts Here you can see features which were added and the concept itself changed a bit or got merged with concepts from Seam3 ==== ConfiguredValueResolver Here we added more flexibility (esp. re-ordering the default lookup mechanisms). See `ConfigResolver`, `ConfigSourceProvider` and `ConfigSource`. ==== ProjectStageActivated and ExpressionActivated We merged them with a feature of Seam3 and now it's called `@Exclude`. That means the basic functionality is still in place (nothing was removed), but the logic is now inverse. ==== DefaultAnnotation (In progress) We merge it with a similar helper of Seam-Solder to provide custom values for annotation attributes. === Postponed concepts We couldn't agree on these features. If you find them useful, please contact the mailing-list. If we see that users need it for reasons we might haven't seen so far, we will discuss it again. ==== BeanNames === Dropped concepts ==== Java 1.5 Support === JSF Module ==== Type-safe view config * Changed names * Annotations are optional ... (TODO) == JBoss Seam 2 to Java EE 6 + DeltaSpike + other Migration of a Seam 2 application to Java EE 6 technologies and some alternatives including DeltaSpike is described along with a complete migrated Seam 2 application in the https://github.com/mareknovotny/seam-migration/wiki[Seam 2 Migration Wiki]. == JBoss Seam 3 to Apache DeltaSpike (TODO) ================================================ FILE: site/src/main/asciidoc/news.adoc ================================================ :notoc: = Apache DeltaSpike News :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == DeltaSpike 2.0.1 (2025-08-11) The Apache DeltaSpike team is pleased to announce the release of Apache DeltaSpike-2.0.1. This is a JakartaEE based maintenance release. Release notes can be found https://s.apache.org/DeltaSpike2.0.1[here] == DeltaSpike 2.0.0 (2024-03-29) The Apache DeltaSpike team is pleased to announce the release of v2.0.0. This is the first release to target JakartaEE specifications and thus the ``jakarta.enterprise `` packages. Release notes can be found https://s.apache.org/DeltaSpike2.0.0[here] == 36th Release (1.9.4) (2020-06-12) The Apache DeltaSpike team is pleased to announce the 36th release (v1.9.4). Release notes can be found https://s.apache.org/DeltaSpike1.9.4[here] == 35th Release (1.9.3) (2020-01-27) The Apache DeltaSpike team is pleased to announce the 35th release (v1.9.3). Release notes can be found https://s.apache.org/DeltaSpike1.9.3[here] == 34th Release (1.9.2) (2019-12-13) The Apache DeltaSpike team is pleased to announce the 34th release (v1.9.2). Release notes can be found https://s.apache.org/DeltaSpike1.9.2[here] == 33th Release (1.9.1) (2019-08-19) The Apache DeltaSpike team is pleased to announce the 33th release (v1.9.1). Release notes can be found https://s.apache.org/DeltaSpike1.9.1[here] == 32th Release (1.9.0) (2018-09-18) The Apache DeltaSpike team is pleased to announce the 32th release (v1.9.0). Release notes can be found https://s.apache.org/DeltaSpike1.9.0[here] == 31th Release (1.8.2) (2018-06-01) The Apache DeltaSpike team is pleased to announce the 31th release (v1.8.2). Release notes can be found https://s.apache.org/DeltaSpike_1.8.2[here] == 30th Release (1.8.1) (2018-01-01) The Apache DeltaSpike team is pleased to announce the 30th release (v1.8.1). Release notes can be found https://s.apache.org/DeltaSpike_1.8.1[here] == 29th Release (1.8.0) (2017-06-01) The Apache DeltaSpike team is pleased to announce the 29th release (v1.8.0). Release notes can be found https://s.apache.org/DeltaSpike-1.8.0[here] == 28th Release (1.7.2) (06.11.2016) The Apache DeltaSpike team is pleased to announce the 28th release (v1.7.2). Release notes can be found https://s.apache.org/DeltaSpike-1.7.2[here] == 27th Release (1.7.1) (20.07.2016) The Apache DeltaSpike team is pleased to announce the 27th release (v1.7.1). Release notes can be found https://s.apache.org/DeltaSpike-1.7.1[here] == 26th Release (1.7.0) (19.06.2016) The Apache DeltaSpike team is pleased to announce the 26th release (v1.7.0). Release notes can be found https://s.apache.org/DeltaSpike-1.7.0[here] Please note that the previously announced end of Java 6 support has been postponed until the 2.0 line. == 25th Release (1.6.1) (23.04.2016) The Apache DeltaSpike team is pleased to announce the 25th release (v1.6.1). == 24th Release (1.6.0) (02.04.2016) The Apache DeltaSpike team is pleased to announce the 24th release (v1.6.0). == 23rd Release (1.5.4) (18.02.2016) The Apache DeltaSpike team is pleased to announce the 23rd release (v1.5.4). == 22nd Release (1.5.3) (05.02.2016) The Apache DeltaSpike team is pleased to announce the 22nd release (v1.5.3). == 21st Release (1.5.2) (06.12.2015) The Apache DeltaSpike team is pleased to announce the 21st release (v1.5.2). == 20th Release (1.5.1) (24.10.2015) The Apache DeltaSpike team is pleased to announce the 20th release (v1.5.1). == 19th Release (1.5.0) (10.08.2015) The Apache DeltaSpike team is pleased to announce the 19th release (v1.5.0). == 18th Release (1.4.2) (19.07.2015) The Apache DeltaSpike team is pleased to announce the 18th release (v1.4.2). == 17th Release (1.4.1) (12.06.2015) The Apache DeltaSpike team is pleased to announce the 17th release (v1.4.1). == New Committer (01.06.2015) Daniel Cunha joined our development community. == 16th Release (1.4.0) (21.05.2015) The Apache DeltaSpike team is pleased to announce the 16th release (v1.4.0). == New PMC Member (21.04.2015) Rafael Benevides joined our PMC. == New Committer (17.04.2015) Ron Smeral joined our development community. == 15th Release (1.3.0) (10.03.2015) The Apache DeltaSpike team is pleased to announce the 15th release (v1.3.0). The http://s.apache.org/DeltaSpike_1.3.0[release notes] contains 31 JIRA tickets. == 14th Release (1.2.1) (20.12.2014) The Apache DeltaSpike team is pleased to announce the 14th release (v1.2.1). The http://s.apache.org/DeltaSpike_1.2.1[release notes] contains 19 JIRA tickets. == 13th Release (1.2.0) (30.11.2014) The Apache DeltaSpike team is pleased to announce the 13th release (v1.2.0). The http://s.apache.org/DeltaSpike_1.2.0[release notes] contains 22 JIRA tickets. == New PMC Member (20.11.2014) Thomas Andraschko joined our PMC. == 12th Release (1.1.0) (01.11.2014) The Apache DeltaSpike team is pleased to announce the 12th release (v1.1.0). The http://s.apache.org/DeltaSpike_1.1.0[release notes] contains 24 JIRA tickets. == Duke's Choice Award (28.09.2014) We won a https://blogs.oracle.com/java/entry/2014_duke_s_choice_award[Duke's Choice Award]! == 11th Release (1.0.3) (21.09.2014) The Apache DeltaSpike team is pleased to announce the 11th release (v1.0.3). The http://s.apache.org/DeltaSpike_1.0.3[release notes] contains 20 JIRA tickets. == 10th Release (1.0.2) (17.08.2014) The Apache DeltaSpike team is pleased to announce the 10th release (v1.0.2). The http://s.apache.org/DeltaSpike_1.0.2[release notes] contains 15 JIRA tickets. == 9th Release (1.0.1) (13.07.2014) The Apache DeltaSpike team is pleased to announce the 9th release (v1.0.1). The http://s.apache.org/DeltaSpike_1.0.1[release notes] contains 18 JIRA tickets. == 8th Release (1.0.0) (14.06.2014) The Apache DeltaSpike team is pleased to announce the 8th release (v1.0.0). The http://s.apache.org/DeltaSpike_1.0.0[release notes] contains 48 JIRA tickets. == New Committer (18.05.2014) Rafael Benevides joined our development community. == 7th Release (0.7) (03.05.2014) The Apache DeltaSpike team is pleased to announce the 7th release (v0.7). The http://s.apache.org/DS-0.7-RNotes[release notes] contains 35 JIRA tickets. == 6th Release (0.6) (20.03.2014) The Apache DeltaSpike team is pleased to announce the 6th release (v0.6). The http://s.apache.org/DS-0.6-RNotes[release notes] contains 102 JIRA tickets. == New Committer (14.12.2013) Thomas Andraschko joined our development community. == 5th Release (0.5) (18.09.2013) The Apache DeltaSpike team is pleased to announce the 5th release (v0.5). The http://s.apache.org/DS-0.5-RNotes[release notes] contains 29 JIRA tickets. == 4th Release (0.4) (31.05.2013) The Apache DeltaSpike team is pleased to announce the fourth release (v0.4). This is our first release as a top level project! The http://s.apache.org/DS-0.4-RNotes[release notes] contains a large list of bug fixes and new features. == Graduation (28.05.2013) The Apache DeltaSpike team is pleased to announce that we have complete graduation as a top level project. == 3rd Release (0.3 incubating) (22.08.2012) The Apache DeltaSpike team is pleased to announce the second release (v0.3-incubating). The http://s.apache.org/DeltaSpike_03incubating[release notes] contains 104 JIRA tickets. == New Committer (21.08.2012) Bolesław Dawidowicz joined our development community. == New Committers (11.07.2012) Charles Moulliard and Romain Manni-Bucau joined our development community. == Apache CMS (30.05.2012) The setup of the project-site in Apache CMS started. == 2nd Release (0.2 incubating) (22.04.2012) The Apache DeltaSpike team is pleased to announce the second release (v0.2-incubating). The http://s.apache.org/DeltaSpike_02incubating[release notes] contains 61 JIRA tickets. == 1st Release (0.1 incubating) (10.02.2012) The Apache DeltaSpike team is pleased to http://s.apache.org/cTt[announce] the first release (v0.1-incubating). The first release contains about 5 000 lines of code (including tests and 10 000 including comments). The http://s.apache.org/DeltaSpike_01incubating[release notes] contains 42 JIRA tickets. == Execution of integration tests with remote servers (01.02.2012) C4J helps us with nightly builds which deploy our integration tests to remote-servers (AS7 and GF3). == New Committer (29.01.2012) Lukasz Lenart joined our development community. == New Committer (28.01.2012) Christian Kaltepoth joined our development community. == New Committer (27.01.2012) Rudy De Busscher joined our development community. == Nabble Mirror (21.01.2012) Dan Allen created a http://s.apache.org/deltaspike-dev_nabble[Nabble mirror] for the dev-list (based on http://incubator.apache.org/mail/deltaspike-dev/) == New Committers (13.01.2012) Dan Allen and Lincoln Baxter III are our first committers after the initial committers. == GitHub Mirror (12.01.2012) The infra team created our mirror (https://github.com/apache/incubator-deltaspike) == Creation of the Status Page (30.12.2011) We created an initial version of our status page (http://incubator.apache.org/guides/website.html) == Nightly builds (29.12.2011) The infra team added the GIT plugin to Jenkins and we created build jobs for nightly builds which get deployed to https://repository.apache.org/content/groups/snapshots/org/apache/deltaspike/ == Sonar build (29.12.2011) Gavin McDonald did the Sonar setup (https://analysis.apache.org/dashboard/index/org.apache.deltaspike:deltaspike-project) == First Commit (22.12.2011) The infra team created our GIT repository and we made the first commit. == First JIRA ticket (13.12.2011) We created our JIRA project and filed the first ticket. == First report 12.2011 (12.12.2011) We submitted the first report to http://wiki.apache.org/incubator/December2011 == Twitter Account We created our Twitter account https://twitter.com/deltaspiketeam[@DeltaSpikeTeam] == Mailing-lists (8.12.2011) Matt Benson created our https://s.apache.org/Kpg[mailing-lists]. == Vote closed (7.12.2011) The vote to join the incubator was closed. There were 8 binding +1 votes, 3 non-binding +1 votes and no -1 votes. In parallel several other folks showed up and told us that they are interested to join the effort. We start with the following initial committers (and therefore PPMC members): * Andy Gibson * Antoine Sabot-Durand * Arne Limburg * Brian Leathem * Cody Lerum * David Blevins * George Gastaldi * Gerhard Petracek * Jakob Korherr * Jason Porter * John Ament * Jozef Hartinger * Ken Finnigan * Marius Bogoevici * Mark Struberg * Matthias Wessendorf * Pete Muir * Pete Royle * Rick Hightower * Shane Bryzak * Stuart Douglas Our mentors are: * David Blevins * Gerhard Petracek * Jim Jagielski * Mark Struberg * Matt Benson * Matthias Wessendorf == Vote to join the Incubator (4.12.2011) Gerhard Petracek started the official http://s.apache.org/h8[vote]. == Proposal (30.11.2011) After some discussions between the teams (of Apache MyFaces CODI, Seam3 and CDISource), Mark Struberg submitted the http://wiki.apache.org/incubator/DeltaSpikeProposal[proposal]. Since Spike couldn't be used as project-name, we agreed on DeltaSpike as initial code name (delta because it closes several gaps). ================================================ FILE: site/src/main/asciidoc/release-preparation.adoc ================================================ :notoc: = Reviewing an Apache Release :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Once a Release has been staged on http://repository.apache.org it must be reviewed by each PMC member *before* casting his VOTE. The following points need to be checked: * is the GPG signature fine? * is there a source archive? * can the source archive really be built? * is there a correct LICENSE and NOTICE file in each artifact (both source and binary artifacts)? * does the NOTICE file contain all necessary attributions? * check the dependencies. We must not have any GPL dependencies and LGPL only if they are optional, etc! See http://www.apache.org/legal/3party.html * do all the tests work? * if there is a TCK to run, does it succeed? * if there is a tag in the SCM, does it contain reproduceable sources? ================================================ FILE: site/src/main/asciidoc/source.adoc ================================================ :notoc: = Contribute to the DeltaSpike Source :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. If you are looking to contribute to the DeltaSpike source, you must start with the latest version of the code base. DeltaSpike source is stored in the Apache Git repository at https://git-wip-us.apache.org/repos/asf/deltaspike.git It is also important that you follow the git workflows we have established for the project to ensure efficient and clean collaboration as detailed here. == 1. Get the Source . Checkout the source + [source] ---- git clone https://git-wip-us.apache.org/repos/asf/deltaspike.git ---- + or for a read-only mirror version + [source] ---- git clone https://github.com/apache/deltaspike ---- + . Update the repository clone + [source] ---- git pull --rebase ---- == 2. Make Additions and Changes to the Source Commits (and in the best case also patches), have to follow our "formatting rules". The following section provides settings for IDEs used by us. === IntelliJ link:http://deltaspike.apache.org/resources/files/settings.jar[Attached] you can find the settings for formatting the source code. Import them via File | Import Settings === Eclipse For Eclipse you can use this link:http://deltaspike.apache.org/resources/files/deltaspike-code-conventions.xml[Code Formatter Profile]. Import it via Window | Preferences | Java | Code Style | Formatter == 3. Build the Source Always build and test your changes before you make pull requests to the DeltaSpike repository. For instructions on building the source and running Arquillian tests, see link:http://deltaspike.apache.org/documentation/build.html[Build and Test DeltaSpike from Source]. == 4. Make a Pull Request Ensure your commits and pull requests follow the our established https://deltaspike.apache.org/suggested-git-workflows.html[DeltaSpike GIT workflow]. == Git Resources For general information about Git and using Git, see the following: * http://wiki.apache.org/couchdb/Git_At_Apache_Guide[Git At Apache Guide] * http://git-wip-us.apache.org[Git at The ASF] * http://git.or.cz/course/svn.html[Git - SVN Crash Course] * http://git-scm.com/book[Pro Git] * https://help.github.com/articles/which-remote-url-should-i-use[GitHub: Which remote URL should I use?] ================================================ FILE: site/src/main/asciidoc/steps_for_a_release.adoc ================================================ = Steps for a Release :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Preparations - Heads up on the mailing-lists e.g.: ----------------------------------------------------------------------------------------------------------------------- first steps for the next release hi @ all, if there are no objections, i'll start with the first steps for the next release (review, documentation,...). it would be great to start with the release procedure next week. regards, [name] ----------------------------------------------------------------------------------------------------------------------- - Check the jenkins builds - Create release notes and commit them to deltaspike/readme/ (format [ReleaseNotes][version].txt) test at least: ----------------------------------------------------------------------------------------------------------------------- mvn clean install -POWB mvn clean install -PWeld1 mvn clean install -Prat mvn clean install -Ptomee-build-managed mvn clean install -Pjbossas-build-managed mvn clean install -Pwildfly-build-managed mvn clean install -Pglassfish-build-managed ----------------------------------------------------------------------------------------------------------------------- deploy a demo app especially with jsf-impl-ee6 to an ee6 server and check the logs (if there are no optional ee7+ classes) (https://github.com/os890/ee6-ds-demo can be used for it e.g.) == First steps ----------------------------------------------------------------------------------------------------------------------- //install a version of git which is compatible with the release-plugin (e.g. v1.8.3.2) git checkout -b ds-[release version] mvn release:prepare -Pdistribution -DreleaseProfiles=distribution //copy prepared workspace (to continue faster if an upload fails in the next step) //hint: dois not use -DdryRun=true -- since it can break the next step mvn release:perform -Pdistribution -DreleaseProfiles=distribution //!!!check the created commits including user-name and email // Verify the release in the staging repository: //login to https://repository.apache.org/ and go to "Staging Repositories" //check esp. .../org/apache/deltaspike/deltaspike/[version]/deltaspike-[version]-source-release.zip //close the repository //push the release-branch and tag to a third-party git repo git remote add vote https://github.com/[user]/deltaspike-vote git push -u vote master git push vote ds-[release version] git push vote --tags ----------------------------------------------------------------------------------------------------------------------- == Vote === Start the Vote e.g.: ----------------------------------------------------------------------------------------------------------------------- [VOTE] Release of Apache DeltaSpike [version] Hi, I was running the needed tasks to get the ... release of Apache DeltaSpike out. The artifacts are deployed to Nexus [1] (and [2]). The tag is available at [3] and will get pushed to the ASF repository once the vote passed. Please take a look at the ... artifacts and vote! Please note: This vote is "majority approval" with a minimum of three +1 votes (see [4]). ------------------------------------------------ [ ] +1 for community members who have reviewed the bits [ ] +0 [ ] -1 for fatal flaws that should cause these bits not to be released, and why.............. ------------------------------------------------ Thanks, [name] [1] https://repository.apache.org/content/repositories/... [2] https://repository.apache.org/content/repositories/.../org/apache/deltaspike/deltaspike/[version]/deltaspike-[version]-source-release.zip [3] https://github.com/[user]/deltaspike-vote/tree/deltaspike-[version] [4] http://www.apache.org/foundation/voting.html#ReleaseVotes ----------------------------------------------------------------------------------------------------------------------- == Announce the Vote - Create a link to the release notes at http://s.apache.org (format DeltaSpike_[version]) - Tweet about the vote via @DeltaSpikeTeam. == Perform the final release === Close the Vote After 72 hours close the vote. e.g.: ----------------------------------------------------------------------------------------------------------------------- Result (was: Re: [VOTE] Release of Apache DeltaSpike [version]) thank you for voting! X binding +1 votes (pmc): [list] Y non-binding +1 votes: [list] Z -1 votes [list] ----------------------------------------------------------------------------------------------------------------------- If the binding majority approved the vote continue. - Login to https://repository.apache.org/ and release the repository - Merge release branch into master and push the branch and tag to the ASF repository Always do a merge in this case (not a rebase): ----------------------------------------------------------------------------------------------------------------------- git checkout master git merge ds-[version] git push origin ds-[version] git push origin deltaspike-[version] git push origin master ----------------------------------------------------------------------------------------------------------------------- - Close the the JIRA tickets for the newly released version - Close the release in JIRA - Ensure the next version is available in JIRA - Wait some minutes and check http://repo2.maven.org/maven2/org/apache/deltaspike === Upload Artifacts Apache releases get published via Subversion. ----------------------------------------------------------------------------------------------------------------------- svn co https://dist.apache.org/repos/dist/release/deltaspike mkdir [version] //add and commit the artifacts (at least *source-release.zip + asc, md5, sha1) //use the artifacts from: // http://repo1.maven.org/maven2/org/apache/deltaspike/deltaspike/[version]/ // http://repo1.maven.org/maven2/org/apache/deltaspike/distribution/distribution-full/[version]/ svn rm {old-version} svn add {version} svn commit -m "Removing {old-version}, adding {version}" ----------------------------------------------------------------------------------------------------------------------- The following `getrelease.sh` bash script can be used to download the release artifacts from maven.central: [script, getrelease.sh] ----------------------------------------------------------------------------------------------------------------------- #!/bin/sh mkdir $1 cd $1 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/deltaspike/${1}/deltaspike-${1}-source-release.zip curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/deltaspike/${1}/deltaspike-${1}-source-release.zip.asc curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/deltaspike/${1}/deltaspike-${1}-source-release.zip.md5 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/deltaspike/${1}/deltaspike-${1}-source-release.zip.sha1 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.tar.gz curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.tar.gz.asc curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.tar.gz.md5 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.tar.gz.sha1 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.zip curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.zip.asc curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.zip.md5 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}.zip.sha1 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}-tests.jar curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}-tests.jar.asc curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}-tests.jar.md5 curl -O https://repository.apache.org/content/groups/public/org/apache/deltaspike/distribution/distribution-full/${1}/distribution-full-${1}-tests.jar.sha1 for f in *.zip; do (sha1sum ${f}; cat ${f}.sha1;echo;echo;); done for f in *.tar.gz; do (sha1sum ${f}; cat ${f}.sha1;echo;echo;); done cd .. ----------------------------------------------------------------------------------------------------------------------- === Check Downloads - http://www.eu.apache.org/dist/deltaspike - http://www.us.apache.org/dist/deltaspike === Update CMS / site content ==== Publish Javadoc of release - git checkout deltaspike-{version} - cd deltaspike && ./javadoc.sh ==== Update site - git checkout master - Update the pom.xml (version.deltaspike.latest.stable and version.deltaspike.latest.snapshot) - Update site\src\main\asciidoc\index.adoc - Update site\src\main\asciidoc\news.adoc - git commit -m "site update" - git push ==== Publish Javadoc of SNAPSHOT - git checkout master - cd deltaspike && ./javadoc.sh ==== Publish site - git checkout master - mvn site deploy - mvn clean site-deploy -Pstaging - mvn clean site-deploy - Login to CMS - update workspace - publish content via https://cms.apache.org/deltaspike/publish === Update report - https://reporter.apache.org/?deltaspike === Announce the Release ==== E-mails ----------------------------------------------------------------------------------------------------------------------- [ANNOUNCE] Release of Apache DeltaSpike [version] The Apache DeltaSpike team is pleased to announce the 6th release of DeltaSpike. Apache DeltaSpike is a suite of portable CDI (Contexts & Dependency Injection) extensions intended to make application development easier when working with CDI and Java EE. Some of its key features include: - A core runtime that supports component configuration, type safe messaging and internationalization, and exception handling. - A suite of utilities to make programmatic bean lookup easier. - A plugin for Java SE to bootstrap both JBoss Weld and Apache OpenWebBeans outside of a container. - JSF integration, including backporting of JSF 2.2 features for Java EE 6. - JPA integration and transaction support. - A Data module, to create an easy to use repository pattern on top of JPA. - Quartz integration Testing support is also provided, to allow you to do low level unit testing of your CDI enabled projects. More can be found on our website - https://deltaspike.apache.org Documentation: https://deltaspike.apache.org/documentation/ Download: https://deltaspike.apache.org/download.html Release Notes: https://s.apache.org/DeltaSpike_[version] Enjoy! [name] ----------------------------------------------------------------------------------------------------------------------- Write the e-mails to: - announce@apache.org - dev@deltaspike.apache.org - users@deltaspike.apache.org ==== Twitter e.g.: ----------------------------------------------------------------------------------------------------------------------- [ANNOUNCE] The Apache #DeltaSpike team is pleased to announce http://s.apache.org/DeltaSpike_[version]. Feel free to test it! Feedback is very welcome! ----------------------------------------------------------------------------------------------------------------------- ================================================ FILE: site/src/main/asciidoc/suggested-git-workflows.adoc ================================================ = Suggested GIT workflows :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. == Avoid git-pull! git-pull should never get invoked if you have dirty files lying around or if your branch is ahead of master. This will always lead to some dirty artifacts in the commit history: ---------------------------------------------------------------------------- Merge branch 'master' of http://git-wip-us.apache.org/deltaspike into master ---------------------------------------------------------------------------- == git pull --rebase An easy version for getting rid of the auto-merges is using [source,bash] -------------------- $ git pull --rebase -------------------- Please note that this sometimes trashes your working tree if there are unmergeable files around. Cleaning this up with a forced manual rebase is not something we would recommend for a git beginner. === Working in an own branch This is actually the suggested way to prevent auto-merges. Create an own branch where you do your feature work. Either do all your work in one branch or create one branch per feature you are working on. [source,bash] ---------------------- $ git branch mybranch ---------------------- After you finished your feature, `git-add` and `git-commit` your work. Check with `git-status` that you don't have any dirty files and uncommitted changes around. You can use `git-stash` to 'backup' unfinished work. Then switch back to the master branch and pull changes done by other committers in the meantime. ---------------------- $ git checkout master $ git pull --rebase ---------------------- You should now get all the changes done by other committers and the will get applied to your local master branch. Now go back to your private branch and rebase your locally performed work to the HEAD of master. ------------------------ $ git checkout mybranch $ git rebase master ------------------------ If you got conflicts, you will get lines with ">>>>" added to those files. Resolve those conflicts manually, add them and finish the rebase. Check with `git-status` and `gitk` if the merge went well and the history now contains your changes. If all is well, go back to the master branch and merge your changes in. ------------------------------------------------------------------------ $ git pull --rebase // (just for safety, you should see no changes) $ git checkout master $ git merge mybranch ------------------------------------------------------------------------ Finally you can push your changes to the ASF git repo ----------- $ git push ----------- == Contribution workflow Please understand that our contribution workflow is designed for outside contributions. They should represent your changes and your changes alone. Any other contributors should raise their own pull request or submit their own patch. Committers should continue to follow the discussion flow for complex changes, and merge their changes when ready. === Raising Pull Requests You should use the following workflow if you plan to contribute features or bug fixes to Apache DeltaSpike via GitHub First, fork our repository https://github.com/apache/deltaspike[on github] Second, clone it locally and add our upstream as a remote ---------------------- $ git clone https://github.com//deltaspike $ git remote add asf https://git-wip-us.apache.org/repos/asf/deltaspike.git ---------------------- Third, find a JIRA ticket to work on. When you do, use that as your branch name --------------------------------- $ git checkout -b DELTASPIKE-XXX --------------------------------- Now you can start to work on your patch. When you are finished, commit your changes. But don't forget to **add the name of the JIRA issue to the commit message**. ------------------------------------------------- $ git commit -am "DELTASPIKE-XXX: Fixed some issue" ------------------------------------------------- Once you're done with your changes, make sure you're up to date and rebase from master ------------------------------------------------- $ git pull asf master --rebase ------------------------------------------------- Next, push your branch to GitHub ------------------------------------------------- $ git push origin DELTASPIKE-XXX ------------------------------------------------- Finally, raise your PR. If you go to your GitHub fork of DeltaSpike, you should see an option to create a PR === Merging Pull Requests Whenever a PR gets created for DeltaSpike, an email is sent to the dev@deltaspike. It will include the subject ------------------------------------------------- [GitHub] deltaspike pull request #00: DELTASPIKE-XXX some changes ------------------------------------------------- Which will contain the instructions ------------------------------------------------- You can merge this pull request into a Git repository by running: $ git pull https://github.com//deltaspike DELTASPIKE-XXX ------------------------------------------------- As long as you don't rebase, pushing the result of this pull will merge the change into our git repository and close the PR. If there are any issues with the patch, you can monitor the build status from the PR, where we run some smoke tests against the commit to ensure its working. Please make the requestor aware of any issues identified (e.g. code quality, formatting, missing tests, etc). === Creating patches You should use the following workflow, if you plan to contribute patches or new features to DeltaSpike. First update you local copy of the repository: ---------------------- $ git checkout master $ git pull --rebase ---------------------- Then create a new local branch for your work. It's good practice to name it after the corresponding JIRA issue. --------------------------------- $ git checkout -b DELTASPIKE-XXX --------------------------------- Now you can start to work on your patch. When you are finished, commit your changes. But don't forget to **add the name of the JIRA issue to the commit message**. ------------------------------------------------- $ git commit -am "DELTASPIKE-XXX: Fixed some issue" ------------------------------------------------- For small patches we recommend to do a single commit containing your changes. For larger contributions you should try to group your work into separate sub-tasks that you can commit one by one. Before you create your patch you should make sure that your local repository is up to date with the master repository. This is very important especially if you work on your branch for a long time. Use the following commands to pull the latest changes from the upstream repository and rebase your branch against the current master. [source,bash] ------------------------------ $ git checkout master $ git pull --rebase $ git checkout DELTASPIKE-XXX $ git rebase master ------------------------------ Now you are ready to create your patch: [source,bash] -------------------------------------------------------------- $ git checkout DELTASPIKE-XXX $ git format-patch --stdout master > ../DELTASPIKE-XXX.patch -------------------------------------------------------------- Please attach the resulting patch file to the correspoding JIRA issue. ===Applying patches If you are a committer and want to apply a patch you should do so in a separate branch. --------------------------------- $ git checkout -b DELTASPIKE-XXX --------------------------------- Then apply the patch using `git-am` and rebase it against the master branch. ------------------------------------ $ git am < ../DELTASPIKE-XXX.patch $ git rebase master ------------------------------------ After reviewing the changes and testing the code, the changes are ready to be merged into the master branch: ------------------------------- $ git checkout master $ git merge DELTASPIKE-XXX $ git branch -d DELTASPIKE-XXX ------------------------------- == Discussion workflow (optional) All discussions which lead to a decision take place on the mailing list. Sometimes it's required to show-case an idea especially if the solution is more than a few lines. As shown above it makes sense to use local branches for developing new parts. Git allows to push such local branches to a public repository. So it's easier to share it with the community for discussing it. The following listings show an example in combination with GitHub - for sure it works with any hosting platform like BitBucket, Google-Code,... The only important part here is that such branches _NEVER_ get pushed to the main Apache repository to keep the commit history as clean as possible. *Initial setup* [source,bash] ---------------------------------------------------------------------------------- $ git clone https://git-wip-us.apache.org/repos/asf/deltaspike.git ./ $ git remote add discuss https://[username]@github.com/[username]/[repo-name].git $ git push -u discuss master ---------------------------------------------------------------------------------- *Branches for discussions* [source,bash] -------------------------------------------------- $ git checkout -b DELTASPIKE-XXX //1-n commits $ git push discuss DELTASPIKE-XXX //share the link to the branch for the discussions -------------------------------------------------- _If the community agrees on the suggested change, the implementation will be applied to the origin master. A committer has to follow the steps described above for the basic workflow to keep the commit history simple, clean and straight. A contributor has to follow the steps described above for creating a patch._ *Delete the branch again* ---------------------------------- $ git push discuss :DELTASPIKE-XXX $ git branch -d DELTASPIKE-XXX ---------------------------------- ================================================ FILE: template/document.html.erb ================================================ <%#encoding:UTF-8%> <%= document.name %> <% def is_toc? not (attributes.has_key?('notoc')) end %> <% if is_toc? then %> <% end %>
<% $moduleDeps = 'moduledeps' unless defined? $moduleDeps $moduleConf = 'moduleconf' unless defined? $moduleConf $moduleBase = 'modulebase' unless defined? $moduleBase $conf_link = "https://github.com/apache/deltaspike/blob/master/deltaspike/%{base}/%{proj}/src/main/java/%{fqn}.java" unless defined? $conf_link # module dependencies def dep_name(short_name) short_name.tr('-', ' ').capitalize end def has_deps? if attributes.has_key?($moduleDeps) && !(attributes[$moduleDeps].empty?) attributes[$moduleDeps].split(%r{\s*,\s*}).size > 0 else false end end def deps_list() attributes[$moduleDeps].split(%r{\s*,\s*}) end # module configuration def module_base() if attributes.has_key?($moduleBase) && !(attributes[$moduleBase].empty?) attributes[$moduleBase] else 'modules/' + attributes['docname'] end end def conf_name(fqn) fqn[fqn.rindex(".")+1..-1] end def conf_link(in_fqn) $conf_link % { base: module_base(), proj: in_fqn.split(':')[0], fqn: in_fqn.split(':')[1].tr('.', '/') } end def has_conf? if attributes.has_key?($moduleConf) && !(attributes[$moduleConf].empty?) attributes[$moduleConf].split(%r{\s*,\s*}).size > 0 else false end end def conf_list() attributes[$moduleConf].split(%r{\s*,\s*}) end %>

<%= document.name %>

<%= document.content %>
<% if is_toc? or has_deps? or has_conf? then %>
<% if is_toc? then %>
<%= converter.convert @document, 'outline', :toclevels => 4 %>
<% end %>
<% end %>

Copyright © 2011-2025 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.

Apache and the Apache feather logo are trademarks of The Apache Software Foundation.