/* (non-Javadoc)
   * @see com.googlecode.psiprobe.beans.ResourceResolver#lookupDataSource(org.apache.catalina.Context, java.lang.String, com.googlecode.psiprobe.beans.ContainerWrapperBean)
   */
  public synchronized DataSource lookupDataSource(
      final Context context, String resourceName, ContainerWrapperBean containerWrapper)
      throws NamingException {

    if (context != null) {
      ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context);
    }
    try {
      javax.naming.Context ctx =
          (context != null) ? new InitialContext() : getGlobalNamingContext();
      String jndiName = resolveJndiName(resourceName, (context == null));
      Object obj = ctx.lookup(jndiName);

      if (obj instanceof DataSource) {
        return (DataSource) obj;
      } else {
        return null;
      }
    } finally {
      if (context != null) {
        ((AbstractTomcatContainer) containerWrapper.getTomcatContainer())
            .unbindFromContext(context);
      }
    }
  }
  /* (non-Javadoc)
   * @see com.googlecode.psiprobe.beans.ResourceResolver#resetResource(org.apache.catalina.Context, java.lang.String, com.googlecode.psiprobe.beans.ContainerWrapperBean)
   */
  public synchronized boolean resetResource(
      final Context context, String resourceName, ContainerWrapperBean containerWrapper)
      throws NamingException {

    if (context != null) {
      ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context);
    }
    try {
      javax.naming.Context ctx =
          (context != null) ? new InitialContext() : getGlobalNamingContext();
      String jndiName = resolveJndiName(resourceName, (context == null));
      Object obj = ctx.lookup(jndiName);
      try {
        for (DatasourceAccessor accessor : datasourceMappers) {
          if (accessor.reset(obj)) {
            return true;
          }
        }
        return false;
      } catch (Throwable e) {
        //
        // make sure we always re-throw ThreadDeath
        //
        if (e instanceof ThreadDeath) {
          throw (ThreadDeath) e;
        }
        return false;
      }
    } finally {
      if (context != null) {
        ((AbstractTomcatContainer) containerWrapper.getTomcatContainer())
            .unbindFromContext(context);
      }
    }
  }
  /* (non-Javadoc)
   * @see com.googlecode.psiprobe.beans.ResourceResolver#getApplicationResources(org.apache.catalina.Context, com.googlecode.psiprobe.beans.ContainerWrapperBean)
   */
  public synchronized List<ApplicationResource> getApplicationResources(
      Context context, ContainerWrapperBean containerWrapper) throws NamingException {

    List<ApplicationResource> resourceList = new ArrayList<ApplicationResource>();

    boolean contextAvailable = containerWrapper.getTomcatContainer().getAvailable(context);
    if (contextAvailable) {

      logger.info("Reading CONTEXT " + context.getName());

      boolean contextBound = false;

      try {
        ((AbstractTomcatContainer) containerWrapper.getTomcatContainer()).bindToContext(context);
        contextBound = true;
      } catch (NamingException e) {
        logger.error("Cannot bind to context. useNaming=false ?");
        logger.debug("  Stack trace:", e);
      }

      try {
        containerWrapper
            .getTomcatContainer()
            .addContextResource(context, resourceList, contextBound);

        containerWrapper
            .getTomcatContainer()
            .addContextResourceLink(context, resourceList, contextBound);

        for (ApplicationResource resourceList1 : resourceList) {
          lookupResource(resourceList1, contextBound, false);
        }

      } finally {
        if (contextBound) {
          ((AbstractTomcatContainer) containerWrapper.getTomcatContainer())
              .unbindFromContext(context);
        }
      }
    }

    return resourceList;
  }
  /**
   * Creates Application instance from Tomcat Context object. If ResourceResolver is passed the
   * method will also collect additional information about the application such as session count,
   * session attribute count, application attribute count, servlet count, servlet stats summary and
   * datasource usage summary. Collecting additional information can be CPU intensive and time
   * consuming so this should be avoided unless absolutely required. Some datasource implementations
   * (c3p0) are known to be prone to internal deadlocks, so this method can also hang is datasource
   * usage stats is to be collected.
   *
   * @param context the context from which to create the Application
   * @param resourceResolver the resolver to use for resources associated with the given context
   * @param calcSize flag which controls whether to calculate session size
   * @param containerWrapper the wrapper for the context's root containing server
   * @return Application object
   */
  public static Application getApplication(
      Context context,
      ResourceResolver resourceResolver,
      boolean calcSize,
      ContainerWrapperBean containerWrapper) {

    // ContainerWrapperBean containerWrapper
    logger.debug("Querying webapp: " + context.getName());

    Application app = new Application();
    app.setName(context.getName().length() > 0 ? context.getName() : "/");
    app.setDocBase(context.getDocBase());
    app.setDisplayName(context.getDisplayName());

    app.setAvailable(containerWrapper.getTomcatContainer().getAvailable(context));
    app.setDistributable(context.getDistributable());
    app.setSessionTimeout(context.getSessionTimeout());
    app.setServletVersion(
        context.getServletContext().getMajorVersion()
            + "."
            + context.getServletContext().getMinorVersion());

    if (resourceResolver != null) {
      logger.debug("counting servlet attributes");

      int ctxAttrCount = 0;
      for (Enumeration e = context.getServletContext().getAttributeNames();
          e.hasMoreElements();
          e.nextElement()) {
        ctxAttrCount++;
      }
      app.setContextAttributeCount(ctxAttrCount);

      if (app.isAvailable()) {
        logger.debug("collecting session information");

        app.setSessionCount(context.getManager().findSessions().length);

        boolean serializable = true;
        int sessionAttributeCount = 0;
        long size = 0;

        for (Session session : context.getManager().findSessions()) {
          ApplicationSession appSession = getApplicationSession(session, calcSize, false);
          if (appSession != null) {
            sessionAttributeCount += appSession.getObjectCount();
            serializable = serializable && appSession.isSerializable();
            size += appSession.getSize();
          }
        }
        app.setSerializable(serializable);
        app.setSessionAttributeCount(sessionAttributeCount);
        app.setSize(size);
      }

      logger.debug("aggregating servlet stats");

      collectApplicationServletStats(context, app);

      if (resourceResolver.supportsPrivateResources() && app.isAvailable()) {
        int[] scores =
            getApplicationDataSourceUsageScores(context, resourceResolver, containerWrapper);
        app.setDataSourceBusyScore(scores[0]);
        app.setDataSourceEstablishedScore(scores[1]);
      }
    }

    return app;
  }
 public static List getApplicationFilters(Context context, ContainerWrapperBean containerWrapper) {
   return containerWrapper.getTomcatContainer().getApplicationFilters(context);
 }