public void start(BundleContext context) throws Exception {

    // simplistic way of achieving the WebContainer as service
    ServiceReference<WebContainer> serviceReference =
        context.getServiceReference(WebContainer.class);

    while (serviceReference == null) {
      serviceReference = context.getServiceReference(WebContainer.class);
    }

    WebContainer service = (WebContainer) context.getService(serviceReference);

    Collection<ServiceReference<HttpContext>> serviceReferences =
        context.getServiceReferences(HttpContext.class, "(httpContext.id=shared)");

    if (serviceReferences.size() > 1) {
      throw new RuntimeException("should only be one http shared context");
    }

    HttpContext httpContext = context.getService(serviceReferences.iterator().next());

    Dictionary<String, String> props;

    props = new Hashtable<String, String>();
    props.put("pattern", ".*");
    props.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, "shared");

    service.registerFilter(new ServletFilter(), new String[] {"/*"}, null, props, httpContext);
  }
 protected void removingWebContainerCallback(ServiceReference serviceReference) {
   WebContainer service = (WebContainer) bundleContext.getService(serviceReference);
   if (service != null) {
     service.unregisterLoginConfig(httpContext);
     service.unregisterConstraintMapping(httpContext);
   }
 }
  protected WebContainer addingWebContainerCallback(ServiceReference webContainerServiceReference) {
    WebContainer service = (WebContainer) bundleContext.getService(webContainerServiceReference);
    httpContext = service.createDefaultHttpContext();

    addJettyWebXml(service);

    if (constraintMappings == null) {
      throw new IllegalStateException("constraintMappings was null!");
    }
    for (ConstraintMapping constraintMapping : constraintMappings) {
      addConstraintMapping(service, constraintMapping);
    }

    service.registerLoginConfig("BASIC", "does-not-matter", null, null, httpContext);

    return service;
  }
  @Override
  public void start(BundleContext context) throws Exception {

    ServiceReference<WebContainer> serviceReference =
        context.getServiceReference(WebContainer.class);

    while (serviceReference == null) {
      serviceReference = context.getServiceReference(WebContainer.class);
    }

    WebContainer service = (WebContainer) context.getService(serviceReference);

    HttpContext httpContext = service.getDefaultSharedHttpContext();

    Dictionary<String, String> props;

    // register a custom http context that forbids access
    props = new Hashtable<String, String>();
    props.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, "shared");
    httpContextReg = context.registerService(HttpContext.class, httpContext, props);
    // and an servlet that cannot be accessed due to the above context
    props = new Hashtable<String, String>();
    props.put(ExtenderConstants.PROPERTY_ALIAS, Bundle1Servlet.ALIAS);
    props.put("servlet-name", "Bundle1Servlet");
    props.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, "shared");
    bundle1ServletReg = context.registerService(Servlet.class, new Bundle1Servlet(), props);

    // register a filter
    props = new Hashtable<String, String>();
    props.put(ExtenderConstants.PROPERTY_URL_PATTERNS, Bundle1Servlet.ALIAS + "/*");
    props.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, "shared");
    filterReg = context.registerService(Filter.class, new Bundle1Filter(), props);

    Dictionary<String, String> filterInit = new Hashtable<String, String>();
    filterInit.put("pattern", ".*");
    filterInit.put(ExtenderConstants.PROPERTY_HTTP_CONTEXT_ID, "shared");

    service.registerFilter(
        new Bundle1SharedFilter(),
        new String[] {"/*"},
        null,
        filterInit,
        (HttpContext) context.getService(httpContextReg.getReference()));
  }
  @Test
  @Ignore("PAXWEB-483: Filtering without a Servlet doesn't work with Http-Service but within a war")
  public void testFilterOnly() throws Exception {
    ServiceTracker<WebContainer, WebContainer> tracker =
        new ServiceTracker<WebContainer, WebContainer>(bundleContext, WebContainer.class, null);
    tracker.open();
    WebContainer service = tracker.waitForService(TimeUnit.SECONDS.toMillis(20));
    Filter filter = new SimpleOnlyFilter();
    service.registerFilter(
        filter,
        new String[] {
          "/testFilter/*",
        },
        null,
        null,
        null);

    testClient.testWebPath("http://127.0.0.1:8181/testFilter/filterMe", "Hello Whiteboard Filter");

    service.unregisterFilter(filter);
  }
  protected void addJettyWebXml(WebContainer service) {
    String jettyWebXmlLoc;
    if (this.jettyWebXmlLocation == null) {
      jettyWebXmlLoc = "/WEB-INF/jetty-web.xml";
    } else {
      jettyWebXmlLoc = this.jettyWebXmlLocation;
    }

    URL jettyWebXml = bundleContext.getBundle().getResource(jettyWebXmlLoc);
    if (jettyWebXml != null) {
      log.debug("Found jetty-web XML configuration on bundle classpath on " + jettyWebXmlLoc);
      service.registerJettyWebXml(jettyWebXml, httpContext);
    } else {
      log.debug("Not found jetty-web XML configuration on bundle classpath on " + jettyWebXmlLoc);
    }
  }
  protected void addConstraintMapping(WebContainer service, ConstraintMapping constraintMapping) {
    Constraint constraint = constraintMapping.getConstraint();
    String[] roles = constraint.getRoles();
    // name property is unavailable on constraint object :/
    String name = "Constraint-" + new Random().nextInt();

    int dataConstraint = constraint.getDataConstraint();
    String dataConstraintStr;
    switch (dataConstraint) {
      case Constraint.DC_UNSET:
        dataConstraintStr = null;
        break;
      case Constraint.DC_NONE:
        dataConstraintStr = "NONE";
        break;
      case Constraint.DC_CONFIDENTIAL:
        dataConstraintStr = "CONFIDENTIAL";
        break;
      case Constraint.DC_INTEGRAL:
        dataConstraintStr = "INTEGRAL";
        break;
      default:
        log.warnv("Unknown data constraint: " + dataConstraint);
        dataConstraintStr = "CONFIDENTIAL";
    }
    List<String> rolesList = Arrays.asList(roles);

    log.debug(
        "Adding security constraint name="
            + name
            + ", url="
            + constraintMapping.getPathSpec()
            + ", dataConstraint="
            + dataConstraintStr
            + ", canAuthenticate="
            + constraint.getAuthenticate()
            + ", roles="
            + rolesList);
    service.registerConstraintMapping(
        name,
        constraintMapping.getPathSpec(),
        null,
        dataConstraintStr,
        constraint.getAuthenticate(),
        rolesList,
        httpContext);
  }
  @Test
  @Ignore("Test fails due to a filter doesn't work right now for the root '/'")
  public void testRootFilterRegistration() throws Exception {
    ServiceTracker<WebContainer, WebContainer> tracker =
        new ServiceTracker<WebContainer, WebContainer>(bundleContext, WebContainer.class, null);
    tracker.open();
    WebContainer service = tracker.waitForService(TimeUnit.SECONDS.toMillis(20));
    final String fullContent = "This content is Filtered by a javax.servlet.Filter";
    Filter filter =
        new Filter() {

          @Override
          public void init(FilterConfig filterConfig) throws ServletException {}

          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
              throws IOException, ServletException {
            PrintWriter writer = response.getWriter();
            writer.write(fullContent);
            writer.flush();
          }

          @Override
          public void destroy() {}
        };
    final StringWriter writer = new StringWriter();
    // CHECKSTYLE:OFF
    filter.doFilter(
        null,
        (ServletResponse)
            Proxy.newProxyInstance(
                getClass().getClassLoader(),
                new Class[] {ServletResponse.class},
                new InvocationHandler() {

                  @Override
                  public Object invoke(Object proxy, Method method, Object[] args)
                      throws Throwable {
                    if (method.getName().equals("getWriter")) {
                      return new PrintWriter(writer);
                    }
                    return null;
                  }
                }),
        null);
    // CHECKSTYLE:OFF
    // Check if our example filter do write the string to the writer...
    Assert.assertEquals(fullContent, writer.toString());
    // Now register the Filter under some alias...
    service.registerFilter(
        filter, new String[] {"*", "/*", "/", "/some/random/path"}, null, null, null);
    // If it works, always the filter should take over and return the same string regardeless of the
    // URL
    String expectedContent = "content is Filtered by";
    testClient.testWebPath("http://127.0.0.1:8181/test-context/some/random/path", expectedContent);
    testClient.testWebPath(
        "http://127.0.0.1:8181/test-context/some/notregistered/random/path", expectedContent);
    testClient.testWebPath("http://127.0.0.1:8181/test-context/", expectedContent);
    // Even for existing path!
    testClient.testWebPath("http://127.0.0.1:8181/helloworld/hs", expectedContent);
    // And even for images
    testClient.testWebPath("http://127.0.0.1:8181/images/logo.png", expectedContent);
    // of course we should be able to deregister :-)
    service.unregisterFilter(filter);
    tracker.close();
  }