/**
   * Configures web resources for the supplied web application context.
   *
   * <p>Implementation details:
   *
   * <ul>
   *   <li>The resource base path is retrieved from the supplied {@code
   *       WebMergedContextConfiguration}.
   *   <li>A {@link ResourceLoader} is instantiated for the {@link MockServletContext}: if the
   *       resource base path is prefixed with "{@code classpath:}", a {@link DefaultResourceLoader}
   *       will be used; otherwise, a {@link FileSystemResourceLoader} will be used.
   *   <li>A {@code MockServletContext} will be created using the resource base path and resource
   *       loader.
   *   <li>The supplied {@link GenericWebApplicationContext} is then stored in the {@code
   *       MockServletContext} under the {@link
   *       WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE} key.
   *   <li>Finally, the {@code MockServletContext} is set in the {@code WebApplicationContext}.
   *
   * @param context the web application context for which to configure the web resources
   * @param webMergedConfig the merged context configuration to use to load the web application
   *     context
   */
  protected void configureWebResources(
      GenericWebApplicationContext context, WebMergedContextConfiguration webMergedConfig) {

    String resourceBasePath = webMergedConfig.getResourceBasePath();
    ResourceLoader resourceLoader =
        resourceBasePath.startsWith(ResourceLoader.CLASSPATH_URL_PREFIX)
            ? new DefaultResourceLoader()
            : new FileSystemResourceLoader();

    ServletContext servletContext = new MockServletContext(resourceBasePath, resourceLoader);
    servletContext.setAttribute(
        WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
    context.setServletContext(servletContext);
  }
  /** {@inheritDoc} */
  public void configureWebApp() throws Exception {
    log.debug("Configuring Jetty webapp");

    // Get context
    WebAppContext context = getWebAppContext();

    // If app is already started...
    if (context.isStarted()) {
      log.debug("Cannot configure webapp after it is started");
      return;
    }

    // Get WEB_INF directory
    Resource webInf = context.getWebInf();
    if (webInf != null && webInf.isDirectory()) {
      // Get properties file with virtualHosts and context path
      Resource config = webInf.addPath("red5-web.properties");
      if (config.exists()) {
        log.debug("Configuring red5-web.properties");
        // Load configuration properties
        Properties props = new Properties();
        props.load(config.getInputStream());

        // Get context path and virtual hosts
        String contextPath = props.getProperty("webapp.contextPath");
        String virtualHosts = props.getProperty("webapp.virtualHosts");

        // Get hostnames
        String[] hostnames = virtualHosts.split(",");
        for (int i = 0; i < hostnames.length; i++) {
          hostnames[i] = hostnames[i].trim();
          if (hostnames[i].equals("*")) {
            // A virtual host "null" must be used so requests for
            // any host will be served.
            hostnames = null;
            break;
          }
        }

        // Set virtual hosts and context path to context
        context.setVirtualHosts(hostnames);
        context.setContextPath(contextPath);
        LoaderBase.setRed5ApplicationContext(contextPath, new JettyApplicationContext(context));
      }
    } else if (webInf == null) {
      // No WEB-INF directory found, register as default application
      log.info(
          "No WEB-INF directory found for "
              + context.getContextPath()
              + ", creating default application.");
      BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance("red5.xml");
      BeanFactoryReference bfr = bfl.useBeanFactory("red5.common");

      // Create WebScope dynamically
      WebScope scope = new WebScope();
      IServer server = (IServer) bfr.getFactory().getBean(IServer.ID);
      scope.setServer(server);
      scope.setGlobalScope(server.getGlobal("default"));

      // Get default Red5 context from context loader that is JettyLoader in this case
      ApplicationContext appCtx = JettyLoader.getApplicationContext();
      ContextLoader loader = (ContextLoader) appCtx.getBean("context.loader");
      appCtx = loader.getContext("default.context");

      // Create context for the WebScope and initialize
      Context scopeContext = new Context();
      scopeContext.setContextPath("/");
      scopeContext.setClientRegistry((IClientRegistry) appCtx.getBean("global.clientRegistry"));
      scopeContext.setMappingStrategy((IMappingStrategy) appCtx.getBean("global.mappingStrategy"));
      scopeContext.setServiceInvoker((IServiceInvoker) appCtx.getBean("global.serviceInvoker"));
      scopeContext.setScopeResolver((IScopeResolver) appCtx.getBean("red5.scopeResolver"));

      // The context needs an ApplicationContext so resources can be
      // resolved
      GenericWebApplicationContext webCtx = new GenericWebApplicationContext();
      webCtx.setDisplayName("Automatic generated WebAppContext");
      webCtx.setParent(appCtx);
      webCtx.setServletContext(ContextHandler.getCurrentContext());
      scopeContext.setApplicationContext(webCtx);

      // Store context in scope
      scope.setContext(scopeContext);

      // Use default ApplicationAdapter as handler
      scope.setHandler(new ApplicationAdapter());

      // Make available as "/<directoryName>" and allow access from all
      // hosts
      scope.setContextPath(context.getContextPath());
      scope.setVirtualHosts("*");

      LoaderBase.setRed5ApplicationContext(
          context.getContextPath(), new JettyApplicationContext(context));

      // Register WebScope in server
      scope.register();
    }
  }
 private void prepareContext(GenericWebApplicationContext context) {
   MockServletContext servletContext = new MockServletContext();
   context.setServletContext(servletContext);
   servletContext.setAttribute(
       WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
 }
 @Override
 public void setServletContext(ServletContext servletContext) {
   super.setServletContext(servletContext);
   prepareWebApplicationContext(servletContext);
 }