@Override
 public <T extends EventListener> void addListener(final T t) {
   ensureNotInitialized();
   ensureNotProgramaticListener();
   if (ApplicationListeners.listenerState() != NO_LISTENER
       && ServletContextListener.class.isAssignableFrom(t.getClass())) {
     throw UndertowServletMessages.MESSAGES.cannotAddServletContextListener();
   }
   ListenerInfo listener =
       new ListenerInfo(t.getClass(), new ImmediateInstanceFactory<EventListener>(t));
   deploymentInfo.addListener(listener);
   deployment.getApplicationListeners().addListener(new ManagedListener(listener, true));
 }
 @Override
 public <T extends EventListener> T createListener(final Class<T> clazz) throws ServletException {
   ensureNotProgramaticListener();
   if (!ApplicationListeners.isListenerClass(clazz)) {
     throw UndertowServletMessages.MESSAGES.listenerMustImplementListenerClass(clazz);
   }
   try {
     return deploymentInfo
         .getClassIntrospecter()
         .createInstanceFactory(clazz)
         .createInstance()
         .getInstance();
   } catch (Exception e) {
     throw UndertowServletMessages.MESSAGES.couldNotInstantiateComponent(clazz.getName(), e);
   }
 }
 @Override
 public void addListener(final Class<? extends EventListener> listenerClass) {
   ensureNotInitialized();
   ensureNotProgramaticListener();
   if (ApplicationListeners.listenerState() != NO_LISTENER
       && ServletContextListener.class.isAssignableFrom(listenerClass)) {
     throw UndertowServletMessages.MESSAGES.cannotAddServletContextListener();
   }
   InstanceFactory<? extends EventListener> factory = null;
   try {
     factory = deploymentInfo.getClassIntrospecter().createInstanceFactory(listenerClass);
   } catch (Exception e) {
     throw new IllegalArgumentException(e);
   }
   final ListenerInfo listener = new ListenerInfo(listenerClass, factory);
   deploymentInfo.addListener(listener);
   deployment.getApplicationListeners().addListener(new ManagedListener(listener, true));
 }
  @Override
  public void deploy() {
    DeploymentInfo deploymentInfo = originalDeployment.clone();

    if (deploymentInfo.getServletStackTraces() == ServletStackTraces.ALL) {
      UndertowServletLogger.REQUEST_LOGGER.servletStackTracesAll(
          deploymentInfo.getDeploymentName());
    }

    deploymentInfo.validate();
    final ConvergedDeploymentImpl deployment =
        new ConvergedDeploymentImpl(this, deploymentInfo, servletContainer);

    // set deployment to parent using reflection
    try {
      Field deploymentField = DeploymentManagerImpl.class.getDeclaredField("deployment");
      deploymentField.setAccessible(true);
      deploymentField.set(this, deployment);
      deploymentField.setAccessible(false);
    } catch (NoSuchFieldException | IllegalAccessException e) {
      throw new RuntimeException(e);
    }

    final ServletContextImpl servletContexImpl =
        new ServletContextImpl(servletContainer, deployment);
    final ServletContext servletContext = new ConvergedServletContextImpl(servletContexImpl);

    // deployment.setServletContext(((ConvergedServletContextImpl)servletContext).getDelegatedContext());
    this.invokeDeploymentMethod(
        deployment,
        "setServletContext",
        new Class[] {ServletContextImpl.class},
        new Object[] {((ConvergedServletContextImpl) servletContext).getDelegatedContext()});
    deployment.setConvergedServletContext((ConvergedServletContextImpl) servletContext);

    handleExtensions(deploymentInfo, servletContext);

    deployment.setDefaultCharset(Charset.forName(deploymentInfo.getDefaultEncoding()));

    handleDeploymentSessionConfig(
        deploymentInfo, ((ConvergedServletContextImpl) servletContext).getDelegatedContext());

    // deployment.setSessionManager(deploymentInfo.getSessionManagerFactory().createSessionManager(deployment));
    this.invokeDeploymentMethod(
        deployment,
        "setSessionManager",
        new Class[] {SessionManager.class},
        new Object[] {deploymentInfo.getSessionManagerFactory().createSessionManager(deployment)});

    deployment
        .getSessionManager()
        .setDefaultSessionTimeout(deploymentInfo.getDefaultSessionTimeout());
    for (SessionListener listener : deploymentInfo.getSessionListeners()) {
      deployment.getSessionManager().registerSessionListener(listener);
    }

    final List<ThreadSetupAction> setup = new ArrayList<>();
    setup.add(ServletRequestContextThreadSetupAction.INSTANCE);
    setup.add(new ContextClassLoaderSetupAction(deploymentInfo.getClassLoader()));
    setup.addAll(deploymentInfo.getThreadSetupActions());
    final CompositeThreadSetupAction threadSetupAction = new CompositeThreadSetupAction(setup);
    deployment.setThreadSetupAction(threadSetupAction);

    ThreadSetupAction.Handle handle = threadSetupAction.setup(null);
    try {

      final ApplicationListeners listeners = createListeners();
      listeners.start();

      // deployment.setApplicationListeners(listeners);
      this.invokeDeploymentMethod(
          deployment,
          "setApplicationListeners",
          new Class[] {ApplicationListeners.class},
          new Object[] {listeners});

      // now create the servlets and filters that we know about. We can still get more later
      createServletsAndFilters(deployment, deploymentInfo);

      // first run the SCI's
      for (final ServletContainerInitializerInfo sci :
          deploymentInfo.getServletContainerInitializers()) {
        final InstanceHandle<? extends ServletContainerInitializer> instance =
            sci.getInstanceFactory().createInstance();
        try {
          instance.getInstance().onStartup(sci.getHandlesTypes(), servletContext);
        } finally {
          instance.release();
        }
      }

      deployment
          .getSessionManager()
          .registerSessionListener(
              new ConvergedSessionListenerBridge(
                  threadSetupAction, listeners, servletContext, deployment.getSessionManager()));

      initializeErrorPages(deployment, deploymentInfo);
      initializeMimeMappings(deployment, deploymentInfo);
      initializeTempDir(servletContext, deploymentInfo);
      listeners.contextInitialized();
      // run

      HttpHandler wrappedHandlers = ServletDispatchingHandler.INSTANCE;
      wrappedHandlers =
          wrapHandlers(wrappedHandlers, deploymentInfo.getInnerHandlerChainWrappers());
      HttpHandler securityHandler = setupSecurityHandlers(wrappedHandlers);
      wrappedHandlers =
          new PredicateHandler(DispatcherTypePredicate.REQUEST, securityHandler, wrappedHandlers);

      HttpHandler outerHandlers =
          wrapHandlers(wrappedHandlers, deploymentInfo.getOuterHandlerChainWrappers());
      wrappedHandlers =
          new PredicateHandler(DispatcherTypePredicate.REQUEST, outerHandlers, wrappedHandlers);
      wrappedHandlers =
          handleDevelopmentModePersistentSessions(
              wrappedHandlers, deploymentInfo, deployment.getSessionManager(), servletContext);

      MetricsCollector metrics = deploymentInfo.getMetricsCollector();
      if (metrics != null) {
        wrappedHandlers = new MetricsChainHandler(wrappedHandlers, metrics, deployment);
      }

      final ServletInitialHandler servletInitialHandler =
          SecurityActions.createServletInitialHandler(
              deployment.getServletPaths(),
              wrappedHandlers,
              deployment.getThreadSetupAction(),
              servletContext);

      HttpHandler initialHandler =
          wrapHandlers(
              servletInitialHandler,
              deployment.getDeploymentInfo().getInitialHandlerChainWrappers());
      initialHandler = new HttpContinueReadHandler(initialHandler);
      if (deploymentInfo.getUrlEncoding() != null) {
        initialHandler =
            Handlers.urlDecodingHandler(deploymentInfo.getUrlEncoding(), initialHandler);
      }
      deployment.setInitialHandler(initialHandler);

      // deployment.setServletHandler(servletInitialHandler);
      this.invokeDeploymentMethod(
          deployment,
          "setServletHandler",
          new Class[] {ServletInitialHandler.class},
          new Object[] {servletInitialHandler});

      deployment.getServletPaths().invalidate(); // make sure we have a fresh set of servlet paths
      ((ConvergedServletContextImpl) servletContext).initDone();
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      handle.tearDown();
    }

    // set state using reflection:
    try {
      Field stateField = DeploymentManagerImpl.class.getDeclaredField("state");
      stateField.setAccessible(true);
      stateField.set(this, State.DEPLOYED);
      stateField.setAccessible(false);
    } catch (NoSuchFieldException | IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }
 private void ensureNotProgramaticListener() {
   if (ApplicationListeners.listenerState() == PROGRAMATIC_LISTENER) {
     throw UndertowServletMessages.MESSAGES.cannotCallFromProgramaticListener();
   }
 }