ServerBootstrapPreinitialization.java
/*
* Copyright (c) 2021 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.inject.weld.internal.managed;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.servlet.Filter;
import javax.servlet.FilterConfig;
import javax.servlet.FilterRegistration;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import javax.servlet.descriptor.JspConfigDescriptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.GenericType;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.server.Response;
import org.glassfish.jersey.inject.weld.spi.BootstrapPreinitialization;
import org.glassfish.jersey.internal.ServiceFinderBinder;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.inject.Binding;
import org.glassfish.jersey.internal.inject.ClassBinding;
import org.glassfish.jersey.internal.inject.ReferencingFactory;
import org.glassfish.jersey.internal.spi.AutoDiscoverable;
import org.glassfish.jersey.internal.util.collection.Ref;
import org.glassfish.jersey.model.internal.CommonConfig;
import org.glassfish.jersey.model.internal.ComponentBag;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.wadl.WadlFeature;
import org.glassfish.jersey.server.wadl.processor.OptionsMethodProcessor;
import org.glassfish.jersey.server.wadl.processor.WadlModelProcessor;
import org.glassfish.jersey.servlet.WebConfig;
import org.glassfish.jersey.servlet.spi.AsyncContextDelegateProvider;
import org.glassfish.jersey.servlet.spi.FilterUrlMappingsProvider;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.Map;
import java.util.Set;
/**
* Jersey server side pre-initialization implementation.
*/
// TODO : put to a proper module
public class ServerBootstrapPreinitialization implements BootstrapPreinitialization {
/**
* Referencing factory for Grizzly request.
*/
private static class GrizzlyRequestReferencingFactory extends ReferencingFactory<Request> {
@Inject
public GrizzlyRequestReferencingFactory(final Provider<Ref<Request>> referenceFactory) {
super(referenceFactory);
}
}
/**
* Referencing factory for Grizzly response.
*/
private static class GrizzlyResponseReferencingFactory extends ReferencingFactory<Response> {
@Inject
public GrizzlyResponseReferencingFactory(final Provider<Ref<Response>> referenceFactory) {
super(referenceFactory);
}
}
@SuppressWarnings("JavaDoc")
private static class HttpServletRequestReferencingFactory extends ReferencingFactory<HttpServletRequest> {
@Inject
public HttpServletRequestReferencingFactory(final Provider<Ref<HttpServletRequest>> referenceFactory) {
super(referenceFactory);
}
}
@SuppressWarnings("JavaDoc")
private static class HttpServletResponseReferencingFactory extends ReferencingFactory<HttpServletResponse> {
@Inject
public HttpServletResponseReferencingFactory(final Provider<Ref<HttpServletResponse>> referenceFactory) {
super(referenceFactory);
}
}
private static class WebConfigInitializer implements WebConfig {
@Override
public ConfigType getConfigType() {
return ConfigType.ServletConfig;
}
@Override
public ServletConfig getServletConfig() {
return new ServletConfig() {
@Override
public String getServletName() {
return "Preinit";
}
@Override
public ServletContext getServletContext() {
return WebConfigInitializer.this.getServletContext();
}
@Override
public String getInitParameter(String name) {
return null;
}
@Override
public Enumeration<String> getInitParameterNames() {
return null;
}
};
}
@Override
public FilterConfig getFilterConfig() {
return null;
}
@Override
public String getName() {
return "Preinit";
}
@Override
public String getInitParameter(String name) {
return getName();
}
@Override
public Enumeration getInitParameterNames() {
return null;
}
@Override
public ServletContext getServletContext() {
return new ServletContext() {
@Override
public String getContextPath() {
return null;
}
@Override
public ServletContext getContext(String uripath) {
return WebConfigInitializer.this.getServletContext();
}
@Override
public int getMajorVersion() {
return 0;
}
@Override
public int getMinorVersion() {
return 0;
}
@Override
public int getEffectiveMajorVersion() {
return 0;
}
@Override
public int getEffectiveMinorVersion() {
return 0;
}
@Override
public String getMimeType(String file) {
return null;
}
@Override
public Set<String> getResourcePaths(String path) {
return null;
}
@Override
public URL getResource(String path) throws MalformedURLException {
return null;
}
@Override
public InputStream getResourceAsStream(String path) {
return null;
}
@Override
public RequestDispatcher getRequestDispatcher(String path) {
return null;
}
@Override
public RequestDispatcher getNamedDispatcher(String name) {
return null;
}
@Override
public Servlet getServlet(String name) throws ServletException {
return null;
}
@Override
public Enumeration<Servlet> getServlets() {
return null;
}
@Override
public Enumeration<String> getServletNames() {
return null;
}
@Override
public void log(String msg) {
}
@Override
public void log(Exception exception, String msg) {
}
@Override
public void log(String message, Throwable throwable) {
}
@Override
public String getRealPath(String path) {
return null;
}
@Override
public String getServerInfo() {
return null;
}
@Override
public String getInitParameter(String name) {
return null;
}
@Override
public Enumeration<String> getInitParameterNames() {
return null;
}
@Override
public boolean setInitParameter(String name, String value) {
return false;
}
@Override
public Object getAttribute(String name) {
return null;
}
@Override
public Enumeration<String> getAttributeNames() {
return null;
}
@Override
public void setAttribute(String name, Object object) {
}
@Override
public void removeAttribute(String name) {
}
@Override
public String getServletContextName() {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
return null;
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {
return null;
}
@Override
public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) {
return null;
}
@Override
public <T extends Servlet> T createServlet(Class<T> clazz) throws ServletException {
return null;
}
@Override
public ServletRegistration getServletRegistration(String servletName) {
return null;
}
@Override
public Map<String, ? extends ServletRegistration> getServletRegistrations() {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, String className) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
return null;
}
@Override
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
return null;
}
@Override
public <T extends Filter> T createFilter(Class<T> clazz) throws ServletException {
return null;
}
@Override
public FilterRegistration getFilterRegistration(String filterName) {
return null;
}
@Override
public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
return null;
}
@Override
public SessionCookieConfig getSessionCookieConfig() {
return null;
}
@Override
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) {
}
@Override
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
return null;
}
@Override
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
return null;
}
@Override
public void addListener(String className) {
}
@Override
public <T extends EventListener> void addListener(T t) {
}
@Override
public void addListener(Class<? extends EventListener> listenerClass) {
}
@Override
public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException {
return null;
}
@Override
public JspConfigDescriptor getJspConfigDescriptor() {
return null;
}
@Override
public ClassLoader getClassLoader() {
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) {
}
};
}
}
private static class PreinitializationFeatureContext implements FeatureContext {
private final AbstractBinder binder;
private PreinitializationFeatureContext(AbstractBinder binder) {
this.binder = binder;
}
@Override
public Configuration getConfiguration() {
return new CommonConfig(RuntimeType.SERVER, ComponentBag.INCLUDE_ALL);
}
@Override
public FeatureContext property(String name, Object value) {
return this;
}
@Override
public FeatureContext register(Class<?> componentClass) {
binder.bindAsContract(componentClass);
return this;
}
@Override
public FeatureContext register(Class<?> componentClass, int priority) {
binder.bindAsContract(componentClass).ranked(priority);
return this;
}
@Override
public FeatureContext register(Class<?> componentClass, Class<?>... contracts) {
final ClassBinding binding = binder.bind(componentClass);
if (contracts != null) {
for (Class<?> contract : contracts) {
binding.to(contract);
}
}
return this;
}
@Override
public FeatureContext register(Class<?> componentClass, Map<Class<?>, Integer> contracts) {
for (Map.Entry<Class<?>, Integer> contract : contracts.entrySet()) {
final AbstractBinder abstractBinder = new AbstractBinder() {
@Override
protected void configure() {
}
};
final ClassBinding binding = abstractBinder.bind(componentClass);
binding.to(contract.getKey()).ranked(contract.getValue());
binder.install(abstractBinder);
}
return this;
}
@Override
public FeatureContext register(Object component) {
if (AbstractBinder.class.isInstance(component)) {
binder.install((AbstractBinder) component);
} else {
binder.bind(component).to(component.getClass());
}
return this;
}
@Override
public FeatureContext register(Object component, int priority) {
binder.bind(component).to(component.getClass()).ranked(priority);
return this;
}
@Override
public FeatureContext register(Object component, Class<?>... contracts) {
Binding binding = binder.bind(component);
if (contracts != null) {
for (Class<?> contract : contracts) {
binding.to(contract);
}
}
return this;
}
@Override
public FeatureContext register(Object component, Map<Class<?>, Integer> contracts) {
for (Map.Entry<Class<?>, Integer> contract : contracts.entrySet()) {
final AbstractBinder abstractBinder = new AbstractBinder() {
@Override
protected void configure() {
}
};
final Binding binding = abstractBinder.bind(component);
binding.to(contract.getKey()).ranked(contract.getValue());
binder.install(abstractBinder);
}
return this;
}
}
@Override
public void register(RuntimeType runtimeType, AbstractBinder binder) {
// binder.install(new MessagingBinders.MessageBodyProviders(null, RuntimeType.SERVER),
// new MessagingBinders.HeaderDelegateProviders());
//
// // Server Binder
// binder.install(new MappableExceptionWrapperInterceptor.Binder(),
// new MonitoringContainerListener.Binder());
// binder.bind(ChunkedResponseWriter.class).to(MessageBodyWriter.class).in(Singleton.class);
// binder.bind(JsonWithPaddingInterceptor.class).to(WriterInterceptor.class).in(Singleton.class);
if (runtimeType == RuntimeType.SERVER) {
// new ApplicationHandler(new ResourceConfig());
//grizzly
binder.bindFactory(GrizzlyRequestReferencingFactory.class).to(Request.class)
.proxy(false).in(RequestScoped.class);
binder.bindFactory(ReferencingFactory.<Request>referenceFactory()).to(new GenericType<Ref<Request>>() {})
.in(RequestScoped.class);
binder.bindFactory(GrizzlyResponseReferencingFactory.class).to(Response.class)
.proxy(true).proxyForSameScope(false).in(RequestScoped.class);
binder.bindFactory(ReferencingFactory.<Response>referenceFactory()).to(new GenericType<Ref<Response>>() {})
.in(RequestScoped.class);
// servlet
binder.bindFactory(HttpServletRequestReferencingFactory.class).to(HttpServletRequest.class)
.proxy(true).proxyForSameScope(false).in(RequestScoped.class);
binder.bindFactory(ReferencingFactory.referenceFactory())
.to(new GenericType<Ref<HttpServletRequest>>() {}).in(RequestScoped.class);
binder.bindFactory(HttpServletResponseReferencingFactory.class).to(HttpServletResponse.class)
.proxy(true).proxyForSameScope(false).in(RequestScoped.class);
binder.bindFactory(ReferencingFactory.referenceFactory())
.to(new GenericType<Ref<HttpServletResponse>>() {}).in(RequestScoped.class);
final WebConfig webConfig = new WebConfigInitializer();
final Map<String, Object> applicationProperties = Collections.EMPTY_MAP;
binder.bindFactory(() -> webConfig.getServletContext()).to(ServletContext.class).in(Singleton.class);
binder.bindFactory(() -> webConfig).to(WebConfig.class).in(Singleton.class);
binder.install(
new ServiceFinderBinder<>(AsyncContextDelegateProvider.class, applicationProperties, RuntimeType.SERVER));
binder.install(
new ServiceFinderBinder<>(FilterUrlMappingsProvider.class, applicationProperties, RuntimeType.SERVER));
final ServletConfig servletConfig = webConfig.getServletConfig();
binder.bindFactory(() -> servletConfig).to(ServletConfig.class).in(Singleton.class);
// WADL TODO put to a proper module
try {
new WadlFeature().configure(new PreinitializationFeatureContext(binder) {
@Override
public FeatureContext register(Class<?> componentClass) {
if (WadlModelProcessor.class.isAssignableFrom(componentClass)) {
super.register(WadlModelProcessor.OptionsHandler.class);
}
super.register(componentClass);
return this;
}
});
} catch (Exception e) {
}
try {
Class[] classes = OptionsMethodProcessor.class.getDeclaredClasses();
for (Class clz : classes) {
binder.bindAsContract(clz);
}
} catch (Exception e) {
}
}
//
// //ApplicationConfigurator
// binder.bind(new InitializableInstanceBinding((Application) null).to(Application.class));
}
}