Better @Inject support. For servlet classes, a qualifier is used. Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/ext/cdi/jersey-cdi-rs-inject/pom.xml b/ext/cdi/jersey-cdi-rs-inject/pom.xml index 68505d2..537fb2a 100644 --- a/ext/cdi/jersey-cdi-rs-inject/pom.xml +++ b/ext/cdi/jersey-cdi-rs-inject/pom.xml
@@ -45,6 +45,13 @@ <artifactId>cdi-api</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>jakarta.servlet</groupId> + <artifactId>jakarta.servlet-api</artifactId> + <version>${servlet4.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> </dependencies> <build> @@ -65,6 +72,7 @@ <instructions> <Import-Package> ${cdi.osgi.version}, + javax.servlet.*;version="[2.4,5.0)";resolution:=optional, * </Import-Package> </instructions>
diff --git a/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/InjectExtension.java b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/InjectExtension.java index a6d2e09..3466852 100644 --- a/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/InjectExtension.java +++ b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/InjectExtension.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -22,12 +22,23 @@ import org.glassfish.jersey.internal.util.collection.Value; import org.glassfish.jersey.internal.util.collection.Values; +import javax.enterprise.context.RequestScoped; +import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.event.Observes; import javax.enterprise.inject.Alternative; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.AnnotatedType; +import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.BeforeBeanDiscovery; import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.InjectionTarget; +import javax.enterprise.inject.spi.InjectionTargetFactory; +import javax.enterprise.inject.spi.PassivationCapable; import javax.enterprise.inject.spi.ProcessAnnotatedType; +import javax.inject.Singleton; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ResourceContext; import javax.ws.rs.container.ResourceInfo; @@ -40,9 +51,13 @@ import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Providers; import javax.ws.rs.sse.Sse; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; import java.security.AccessController; +import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.UUID; /** * <p> @@ -57,7 +72,12 @@ */ @SuppressWarnings("unused") class InjectExtension implements Extension { - private void processAnnotatedType(@Observes ProcessAnnotatedType<?> processAnnotatedType, BeanManager beanManager) { + private static final Class<?> WEB_CONFIG_CLASS = + AccessController.doPrivileged(ReflectionHelper.classForNamePA("org.glassfish.jersey.servlet.WebConfig")); + private AnnotatedType<ServletReferenceProducer> interceptorAnnotatedType; + + private void processAnnotatedType(@Observes ProcessAnnotatedType<?> processAnnotatedType, + BeanManager beanManager) { final Class<?> baseClass = (Class<?>) processAnnotatedType.getAnnotatedType().getBaseType(); if (Application.class.isAssignableFrom(baseClass) && Configuration.class.isAssignableFrom(baseClass)) { if (!baseClass.isAnnotationPresent(Alternative.class)) { @@ -67,8 +87,103 @@ } private void beforeDiscoveryObserver(@Observes final BeforeBeanDiscovery bbf, final BeanManager beanManager) { - final CdiComponentProvider cdiComponentProvider = beanManager.getExtension(CdiComponentProvider.class); - cdiComponentProvider.addHK2DepenendencyCheck(InjectExtension::isHK2Dependency); + if (WEB_CONFIG_CLASS != null) { + interceptorAnnotatedType = beanManager.createAnnotatedType(ServletReferenceProducer.class); + bbf.addAnnotatedType(interceptorAnnotatedType, ServletReferenceProducer.class.getName()); + } + CdiComponentProvider.addHK2DepenendencyCheck(InjectExtension::isHK2Dependency); + } + + private void afterDiscoveryObserver(@Observes final AfterBeanDiscovery abd, final BeanManager beanManager) { + if (WEB_CONFIG_CLASS != null) { + abd.addBean(new ServletReferenceProducerBean(beanManager)); + } + } + + @Singleton + private final class ServletReferenceProducerBean implements Bean<ServletReferenceProducer>, PassivationCapable { + private final Set<Annotation> qualifiers = new HashSet<>(); + private final Set<Type> types = new HashSet<>(2); + private final InjectionTarget<ServletReferenceProducer> interceptorTarget; + private final String id = UUID.randomUUID().toString(); + + private ServletReferenceProducerBean(BeanManager beanManager) { + qualifiers.add(new CdiJerseyContextAnnotation()); + qualifiers.add(new CdiAnyAnnotation()); + + types.add(ServletReferenceProducer.class); + types.add(Object.class); + + final AnnotatedType<ServletReferenceProducer> interceptorType = interceptorAnnotatedType; + final InjectionTargetFactory<ServletReferenceProducer> injectionTargetFactory = + beanManager.getInjectionTargetFactory(interceptorType); + + interceptorTarget = injectionTargetFactory.createInjectionTarget(null); + } + @Override + public Set<Type> getTypes() { + return types; + } + + @Override + public Set<Annotation> getQualifiers() { + return qualifiers; + } + + @Override + public Class<? extends Annotation> getScope() { + return RequestScoped.class; + } + + @Override + public String getName() { + return ServletReferenceProducer.class.getName(); + } + + @Override + public Set<Class<? extends Annotation>> getStereotypes() { + return Collections.emptySet(); + } + + @Override + public boolean isAlternative() { + return false; + } + + @Override + public ServletReferenceProducer create(CreationalContext<ServletReferenceProducer> creationalContext) { + final ServletReferenceProducer result = interceptorTarget.produce(creationalContext); + interceptorTarget.inject(result, creationalContext); + interceptorTarget.postConstruct(result); + return result; + } + + @Override + public void destroy(ServletReferenceProducer servletProducer, + CreationalContext<ServletReferenceProducer> creationalContext) { + interceptorTarget.preDestroy(servletProducer); + interceptorTarget.dispose(servletProducer); + creationalContext.release(); + } + + @Override + public Class<?> getBeanClass() { + return ServletReferenceProducer.class; + } + + @Override + public Set<InjectionPoint> getInjectionPoints() { + return interceptorTarget.getInjectionPoints(); + } + + public boolean isNullable() { + return false; + } + + @Override + public String getId() { + return id; + } } private static final boolean isHK2Dependency(Class<?> clazz) { @@ -95,20 +210,17 @@ injectables.add(Sse.class); injectables.add(UriInfo.class); - //Servlet if available - addOptionally("javax.servlet.http.HttpServletRequest", injectables); - addOptionally("javax.servlet.http.HttpServletResponse", injectables); - addOptionally("javax.servlet.ServletConfig", injectables); - addOptionally("javax.servlet.ServletContext", injectables); - addOptionally("javax.servlet.FilterConfig", injectables); - return injectables; } - private static void addOptionally(String className, Set<Class<?>> set) { - final Class<?> optionalClass = AccessController.doPrivileged(ReflectionHelper.classForNamePA(className)); - if (optionalClass != null) { - set.add(optionalClass); - } + private static class CdiJerseyContextAnnotation + extends javax.enterprise.util.AnnotationLiteral<JerseyContext> implements JerseyContext { + private static final long serialVersionUID = 1L; } + + private static class CdiAnyAnnotation + extends javax.enterprise.util.AnnotationLiteral<Any> implements Any { + private static final long serialVersionUID = 1L; + } + }
diff --git a/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/JerseyContext.java b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/JerseyContext.java new file mode 100644 index 0000000..f238f53 --- /dev/null +++ b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/JerseyContext.java
@@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.ext.cdi1x.inject.internal; + +import javax.inject.Qualifier; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * <p> + * Qualifier used for injecting the CDI beans using {@code @Inject}. Used only for beans that originate in Specification other + * than Jakarta RESTful Web Services (such as Servlet). Such beans must not be produced with {@code @Default} qualifier so that + * there is no ambiguity for the CDI injection. + * </p> + * <p> + * Jakarta REST Spec. Section 11 demands {@code HttpServletRequest}, {@code HttpServletResponse}, {@code ServletContext}, + * {@code ServletConfig}, and {@code FilterConfig} to be available by injections using {@code @Context}. For CDI, these + * servlet classes are available with {@link JerseyContext} qualifier. + * </p> + * <p> + * Note that {@code @Context} injection is not aware of the qualifier and using {@code @Context} in conjuction with + * {@code @JerseyContext} will not work. + * </p> + * <p> + * Can be used as e.g. + * + * <pre> + * @Inject + * @JerseyContext //internal + * HttpServletRequest httpServletRequest; + * </pre> + * or as iterable of all {@code HttpServletRequest} beans + * <pre> + * @Inject + * @Any + * Instance<HttpServletRequest> httpServletRequests; + * </pre> + * </p> + * @since 2.38 + */ +@Qualifier +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) +public @interface JerseyContext { +}
diff --git a/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/ServletReferenceProducer.java b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/ServletReferenceProducer.java new file mode 100644 index 0000000..56f4e9f --- /dev/null +++ b/ext/cdi/jersey-cdi-rs-inject/src/main/java/org/glassfish/jersey/ext/cdi1x/inject/internal/ServletReferenceProducer.java
@@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.ext.cdi1x.inject.internal; + +import org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider; +import org.glassfish.jersey.internal.inject.InjectionManager; + +import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.BeanManager; +import javax.inject.Inject; +import javax.servlet.FilterConfig; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * A CDI producer producing servlet beans in a {@code RequestScope}. + */ +class ServletReferenceProducer { + @Inject + InjectionManager injectionManager; + + @Inject + BeanManager beanManager; + + @Produces + @JerseyContext + @RequestScoped + public HttpServletRequest produceHttpServletRequest() { + return injectionManager().getInstance(HttpServletRequest.class); + } + + @Produces + @JerseyContext + @RequestScoped + public HttpServletResponse produceHttpServletResponse() { + return injectionManager().getInstance(HttpServletResponse.class); + } + + @Produces + @JerseyContext + @RequestScoped + public ServletContext produceServletContext() { + return injectionManager().getInstance(ServletContext.class); + } + + @Produces + @JerseyContext + @RequestScoped + public ServletConfig produceServletConfig() { + return injectionManager().getInstance(ServletConfig.class); + } + + @Produces + @JerseyContext + @RequestScoped + public FilterConfig produceFilterConfig() { + return injectionManager().getInstance(FilterConfig.class); + } + + private InjectionManager injectionManager() { + InjectionManager injectionManager = beanManager.getExtension(CdiComponentProvider.class).getEffectiveInjectionManager(); + if (injectionManager != null && !injectionManager.isShutdown()) { + return injectionManager; + } + return this.injectionManager; + } +}
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java index ff63759..5595b8a 100644 --- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java +++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
@@ -68,7 +68,6 @@ import javax.enterprise.inject.spi.ProcessAnnotatedType; import javax.enterprise.inject.spi.ProcessInjectionTarget; import javax.enterprise.util.AnnotationLiteral; -import javax.inject.Qualifier; import org.glassfish.jersey.ext.cdi1x.internal.spi.InjectionManagerInjectedTarget; import org.glassfish.jersey.ext.cdi1x.internal.spi.InjectionManagerStore; @@ -118,7 +117,7 @@ private final Set<Type> jaxrsInjectableTypes = new HashSet<>(); private final Set<Type> hk2ProvidedTypes = Collections.synchronizedSet(new HashSet<Type>()); private final Set<Type> jerseyVetoedTypes = Collections.synchronizedSet(new HashSet<Type>()); - private final Set<DependencyPredicate> jerseyOrDependencyTypes = Collections.synchronizedSet(new LinkedHashSet<>()); + private static final Set<DependencyPredicate> jerseyOrDependencyTypes = Collections.synchronizedSet(new LinkedHashSet<>()); private final ThreadLocal<InjectionManager> threadInjectionManagers = new ThreadLocal<>(); /** @@ -554,7 +553,7 @@ * * @return HK2 injection manager. */ - /* package */ InjectionManager getEffectiveInjectionManager() { + public InjectionManager getEffectiveInjectionManager() { return injectionManagerStore.getEffectiveInjectionManager(); } @@ -870,11 +869,11 @@ * Add a predicate to test HK2 dependency to create a CDI bridge bean to HK2 for it. * @param predicate to test whether given class is a HK2 dependency. */ - public void addHK2DepenendencyCheck(Predicate<Class<?>> predicate) { + public static void addHK2DepenendencyCheck(Predicate<Class<?>> predicate) { jerseyOrDependencyTypes.add(new DependencyPredicate(predicate)); } - private final class DependencyPredicate implements Predicate<Class<?>> { + private static final class DependencyPredicate implements Predicate<Class<?>> { private final Predicate<Class<?>> predicate; public DependencyPredicate(Predicate<Class<?>> predicate) { @@ -891,7 +890,7 @@ if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DependencyPredicate that = (DependencyPredicate) o; - return predicate.getClass().equals(that.predicate); + return predicate.getClass().equals(that.predicate.getClass()); } @Override
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ApplicationInjectParent.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ApplicationInjectParent.java index 5b4de38..4f44123 100644 --- a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ApplicationInjectParent.java +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ApplicationInjectParent.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -37,7 +37,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriInfo; -import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Providers; import java.lang.reflect.Field; import java.util.Iterator; @@ -96,9 +95,6 @@ @Context protected HttpServletRequest contextHttpServletRequest; - @Inject - protected HttpServletRequest injectHttpServletRequest; - @Context protected WebConfig contextWebConfig; @@ -108,21 +104,12 @@ @Context protected HttpServletResponse contextHttpServletResponse; - @Inject - protected HttpServletResponse injectHttpServletResponse; - @Context protected ServletConfig contextServletConfig; - @Inject - protected ServletConfig injectServletConfig; - @Context protected ServletContext contextServletContext; - @Inject - protected ServletContext injectServletContext; - static class InjectHolder extends ParentInject { @Override
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java index 6a546fb..e4daf19 100644 --- a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ParentInject.java
@@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2022 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -33,7 +33,6 @@ import javax.ws.rs.core.Request; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriInfo; -import javax.ws.rs.ext.ParamConverterProvider; import javax.ws.rs.ext.Providers; public class ParentInject implements ParentChecker { @@ -106,9 +105,6 @@ @Context protected HttpServletRequest contextHttpServletRequest; - @Inject - protected HttpServletRequest injectHttpServletRequest; - @Context protected WebConfig contextWebConfig; @@ -118,21 +114,12 @@ @Context protected HttpServletResponse contextHttpServletResponse; - @Inject - protected HttpServletResponse injectHttpServletResponse; - @Context protected ServletConfig contextServletConfig; - @Inject - protected ServletConfig injectServletConfig; - @Context protected ServletContext contextServletContext; - @Inject - protected ServletContext injectServletContext; - @Override public boolean checkInjected(StringBuilder stringBuilder) { boolean injected = true; @@ -148,11 +135,7 @@ injected &= InjectionChecker.checkSecurityContext(injectSecurityContext, stringBuilder); injected &= InjectionChecker.checkUriInfo(injectUriInfo, stringBuilder); - injected &= InjectionChecker.checkHttpServletRequest(injectHttpServletRequest, stringBuilder); - injected &= InjectionChecker.checkHttpServletResponse(injectHttpServletResponse, stringBuilder); injected &= InjectionChecker.checkWebConfig(injectWebConfig, stringBuilder); - injected &= InjectionChecker.checkServletConfig(injectServletConfig, stringBuilder); - injected &= InjectionChecker.checkServletContext(injectServletContext, stringBuilder); return injected; } @@ -182,7 +165,7 @@ } protected boolean checkApplication(Application application, StringBuilder stringBuilder) { - return InjectionChecker.checkApplication(contextApplication, stringBuilder); + return InjectionChecker.checkApplication(application, stringBuilder); } protected boolean checkConfiguration(Configuration configuration, StringBuilder stringBuilder) {
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletApplication.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletApplication.java new file mode 100644 index 0000000..ec50128 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletApplication.java
@@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import org.glassfish.jersey.server.ResourceConfig; + +import javax.enterprise.context.ApplicationScoped; + +@ApplicationScoped +public class ServletApplication extends ResourceConfig { + ServletApplication() { + super(ServletExceptionMapper.class, + ServletResponseFilter.class, + ServletRequestFilter.class, + ServletResource.class); + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletExceptionMapper.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletExceptionMapper.java new file mode 100644 index 0000000..9643019 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletExceptionMapper.java
@@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ExceptionMapper; + +@ApplicationScoped +public class ServletExceptionMapper extends ServletInject implements ExceptionMapper<IllegalArgumentException> { + @Override + public Response toResponse(IllegalArgumentException exception) { + return super.check(); + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletInject.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletInject.java new file mode 100644 index 0000000..57fa75a --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletInject.java
@@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import javax.enterprise.inject.Any; +import javax.inject.Inject; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Response; + +public class ServletInject { + @Inject + @Any + protected HttpServletRequest injectHttpServletRequest; + + @Inject + @Any + protected HttpServletResponse injectHttpServletResponse; + + @Inject + @Any + protected ServletConfig injectServletConfig; + + @Inject + @Any + protected ServletContext injectServletContext; + + public boolean check(StringBuilder sb) { + boolean injected = true; + injected &= InjectionChecker.checkHttpServletRequest(injectHttpServletRequest, sb); + injected &= InjectionChecker.checkHttpServletResponse(injectHttpServletResponse, sb); + injected &= InjectionChecker.checkServletConfig(injectServletConfig, sb); + injected &= InjectionChecker.checkServletContext(injectServletContext, sb); + return injected; + } + + public Response check() { + StringBuilder sb = new StringBuilder(); + if (check(sb)) { + return Response.ok().entity("All injected").build(); + } else { + return Response.status(Response.Status.EXPECTATION_FAILED).entity(sb.toString()).build(); + } + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletRequestFilter.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletRequestFilter.java new file mode 100644 index 0000000..21996cc --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletRequestFilter.java
@@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import javax.enterprise.context.RequestScoped; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Response; +import java.io.IOException; + +@RequestScoped +public class ServletRequestFilter extends ServletInject implements ContainerRequestFilter { + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + Response response = super.check(); + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + requestContext.abortWith(response); + } + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResource.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResource.java new file mode 100644 index 0000000..acddb88 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResource.java
@@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import javax.enterprise.context.RequestScoped; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +@RequestScoped +@Path("/servlet") +public class ServletResource extends ServletInject { + + @GET + public Response checkApp() { + return super.check(); + } + + @GET + @Path("exception") + public Response throwE() { + throw new IllegalArgumentException(); + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResponseFilter.java b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResponseFilter.java new file mode 100644 index 0000000..90cb656 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/main/java/org/glassfish/jersey/tests/cdi/inject/ServletResponseFilter.java
@@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import javax.enterprise.context.RequestScoped; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.Response; +import java.io.IOException; + +@RequestScoped +public class ServletResponseFilter extends ServletInject implements ContainerResponseFilter { + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { + if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) { + Response response = super.check(); + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + responseContext.setStatus(response.getStatus()); + responseContext.setEntity(response.getEntity()); + } + } + } +}
diff --git a/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/ServletTest.java b/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/ServletTest.java new file mode 100644 index 0000000..c3a77c7 --- /dev/null +++ b/tests/integration/cdi-integration/context-inject-on-server/src/test/java/org/glassfish/jersey/tests/cdi/inject/ServletTest.java
@@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ + +package org.glassfish.jersey.tests.cdi.inject; + +import org.glassfish.jersey.inject.hk2.Hk2InjectionManagerFactory; +import org.glassfish.jersey.servlet.ServletProperties; +import org.glassfish.jersey.test.DeploymentContext; +import org.glassfish.jersey.test.JerseyTest; +import org.glassfish.jersey.test.ServletDeploymentContext; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; +import org.glassfish.jersey.test.spi.TestContainerException; +import org.glassfish.jersey.test.spi.TestContainerFactory; +import org.jboss.weld.environment.se.Weld; +import org.junit.Assert; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response; + +public class ServletTest extends JerseyTest { + private Weld weld; + + @Before + public void setup() { + Assume.assumeTrue(Hk2InjectionManagerFactory.isImmediateStrategy()); + } + + @Override + public void setUp() throws Exception { + if (Hk2InjectionManagerFactory.isImmediateStrategy()) { + weld = new Weld(); + weld.initialize(); + super.setUp(); + } + } + + @Override + public void tearDown() throws Exception { + if (Hk2InjectionManagerFactory.isImmediateStrategy()) { + weld.shutdown(); + super.tearDown(); + } + } + + @Override + protected Application configure() { + return new ServletApplication(); + } + + @Override + protected TestContainerFactory getTestContainerFactory() throws TestContainerException { + return new GrizzlyWebTestContainerFactory(); + } + + @Override + protected DeploymentContext configureDeployment() { + return ServletDeploymentContext.builder(configure()) + .initParam(ServletProperties.JAXRS_APPLICATION_CLASS, ServletApplication.class.getName()) + .build(); + } + + @Test + public void testServlet() { + try (Response response = target("servlet").request().header(InjectionChecker.HEADER, InjectionChecker.HEADER).get()) { + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + System.out.println(response.readEntity(String.class)); + } + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + } + + @Test + public void testServletExceptionMapper() { + try (Response response = target("servlet/exception").request() + .header(InjectionChecker.HEADER, InjectionChecker.HEADER).get()) { + if (response.getStatus() != Response.Status.OK.getStatusCode()) { + System.out.println(response.readEntity(String.class)); + } + Assert.assertEquals(response.getStatus(), Response.Status.OK.getStatusCode()); + } + } + +}