private void _setSpriteImages(ServletContext servletContext, Theme theme, String resourcePath)
      throws Exception {

    if (!resourcePath.startsWith(StringPool.SLASH)) {
      resourcePath = StringPool.SLASH.concat(resourcePath);
    }

    Set<String> resourcePaths = servletContext.getResourcePaths(resourcePath);

    if (resourcePaths == null) {
      return;
    }

    List<URL> imageURLs = new ArrayList<URL>(resourcePaths.size());

    for (String curResourcePath : resourcePaths) {
      if (curResourcePath.endsWith(StringPool.SLASH)) {
        _setSpriteImages(servletContext, theme, curResourcePath);
      } else if (curResourcePath.endsWith(".png")) {
        URL imageURL = servletContext.getResource(curResourcePath);

        if (imageURL != null) {
          imageURLs.add(imageURL);
        } else {
          if (ServerDetector.isTomcat()) {
            if (_log.isInfoEnabled()) {
              _log.info(ServletContextUtil.LOG_INFO_SPRITES);
            }
          } else {
            _log.error("Real path for " + curResourcePath + " is null");
          }
        }
      }
    }

    String spriteFileName = resourcePath.concat(PropsValues.SPRITE_FILE_NAME);
    String spritePropertiesFileName = resourcePath.concat(PropsValues.SPRITE_PROPERTIES_FILE_NAME);
    URL spritePropertiesRootURL = servletContext.getResource(StringPool.SLASH);

    Properties spriteProperties =
        SpriteProcessorUtil.generate(
            servletContext,
            imageURLs,
            spriteFileName,
            spritePropertiesFileName,
            spritePropertiesRootURL,
            16,
            16,
            10240);

    if (spriteProperties == null) {
      return;
    }

    String contextPath = ContextPathUtil.getContextPath(servletContext);

    spriteFileName = contextPath.concat(SpriteProcessor.PATH).concat(spriteFileName);

    theme.setSpriteImages(spriteFileName, spriteProperties);
  }
  private List<URL> listResourcesFromWebDir(String base, String namespace, String suffix) {
    Preconditions.checkNotNull(base, "No base defined");

    // Make sure we end in a slash
    StringBuilder path = new StringBuilder(base);
    if (!base.endsWith("/")) {
      path.append('/');
    }
    path.append(namespace.replace(".", "/")).append('/');

    Set<String> files = (Set<String>) servletContext.getResourcePaths(path.toString());

    List<URL> resourceList = new ArrayList<URL>();
    if (files != null) {
      for (String file : files) {
        if (file.endsWith(suffix)) {
          try {
            resourceList.add(servletContext.getResource(file));
          } catch (MalformedURLException e) {
            throw new RuntimeException("Unable to resolve resource at: " + file, e);
          }
        }
      }
    }
    return resourceList;
  }
  /*
   * Scans the web application's sub-directory identified by startPath,
   * along with its sub-directories, for TLDs and adds an implicit map entry
   * to the taglib map for any TLD that has a <uri> element.
   *
   * Initially, rootPath equals /WEB-INF/. The /WEB-INF/classes and
   * /WEB-INF/lib sub-directories are excluded from the search, as per the
   * JSP 2.0 spec.
   *
   * Keep code in sync with o.a.c.startup.TldConfig
   */
  private void tldScanResourcePaths(String startPath) throws Exception {

    Set<String> dirList = ctxt.getResourcePaths(startPath);
    if (dirList != null) {
      Iterator<String> it = dirList.iterator();
      while (it.hasNext()) {
        String path = it.next();
        if (!path.endsWith(TLD_EXT)
            && (path.startsWith(WEB_INF_LIB) || path.startsWith("/WEB-INF/classes/"))) {
          continue;
        }
        if (path.endsWith(TLD_EXT)) {
          if (path.startsWith("/WEB-INF/tags/") && !path.endsWith("implicit.tld")) {
            continue;
          }
          InputStream stream = ctxt.getResourceAsStream(path);
          try {
            tldScanStream(path, null, stream);
          } finally {
            if (stream != null) {
              try {
                stream.close();
              } catch (Throwable t) {
                ExceptionUtils.handleThrowable(t);
              }
            }
          }
        } else {
          tldScanResourcePaths(path);
        }
      }
    }
  }
  /** Initiate all plugins available */
  @Override
  public void init() {
    Set<String> libJars = servletContext.getResourcePaths("/WEB-INF/lib");
    Set<URL> pluginJars =
        libJars
            .stream()
            .filter(
                jar -> jar.toLowerCase().contains("plugin") || jar.toLowerCase().contains("common"))
            .map(
                jar -> {
                  try {
                    return servletContext.getResource(jar);
                  } catch (MalformedURLException e) {
                    log.error("error getting resource", e);
                    return null;
                  }
                })
            .filter(url -> url != null)
            .collect(Collectors.toSet());

    AnnotationDB db = new AnnotationDB();
    try {
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      URL[] urls = pluginJars.toArray(new URL[] {});
      db.scanArchives(urls);

      sourceRepoPluginMap = buildPluginMap(db, cl, RepoPlugin.class);
      transServerPluginMap = buildPluginMap(db, cl, TranslationServerPlugin.class);
    } catch (IOException | ClassNotFoundException e) {
      throw Throwables.propagate(e);
    }
  }
Exemple #5
0
  @SuppressWarnings("unchecked")
  public List<String> getResourcePaths(String path) {
    List<String> result = CollectionFactory.newList();
    Stack<String> queue = CollectionFactory.newStack();

    queue.push(path);

    while (!queue.isEmpty()) {
      String current = queue.pop();

      Set<String> matches = servletContext.getResourcePaths(current);

      // Tomcat 5.5.20 inside JBoss 4.0.2 has been observed to do this!
      // Perhaps other servers do as well.

      if (matches == null) continue;

      for (String match : matches) {
        // Folders are queued up for further expansion.

        if (match.endsWith("/")) queue.push(match);
        else result.add(match);
      }
    }

    Collections.sort(result);

    return result;
  }
  private void _setSpriteImages(ServletContext servletContext, Theme theme, String resourcePath)
      throws Exception {

    if (!resourcePath.startsWith(StringPool.SLASH)) {
      resourcePath = StringPool.SLASH.concat(resourcePath);
    }

    Set<String> resourcePaths = servletContext.getResourcePaths(resourcePath);

    if ((resourcePaths == null) || resourcePaths.isEmpty()) {
      return;
    }

    List<URL> imageURLs = new ArrayList<URL>(resourcePaths.size());

    for (String curResourcePath : resourcePaths) {
      if (curResourcePath.endsWith(StringPool.SLASH)) {
        _setSpriteImages(servletContext, theme, curResourcePath);
      } else if (curResourcePath.endsWith(".png")) {
        URL imageURL = servletContext.getResource(curResourcePath);

        if (imageURL != null) {
          imageURLs.add(imageURL);
        } else {
          _log.error("Resource URL for " + curResourcePath + " is null");
        }
      }
    }

    String spriteRootDirName = PropsValues.SPRITE_ROOT_DIR;
    String spriteFileName = resourcePath.concat(PropsValues.SPRITE_FILE_NAME);
    String spritePropertiesFileName = resourcePath.concat(PropsValues.SPRITE_PROPERTIES_FILE_NAME);
    String rootPath = ServletContextUtil.getRootPath(servletContext);

    Properties spriteProperties =
        SpriteProcessorUtil.generate(
            servletContext,
            imageURLs,
            spriteRootDirName,
            spriteFileName,
            spritePropertiesFileName,
            rootPath,
            16,
            16,
            10240);

    if (spriteProperties == null) {
      return;
    }

    String contextPath = ContextPathUtil.getContextPath(servletContext);

    spriteFileName = contextPath.concat(SpriteProcessor.PATH).concat(spriteFileName);

    theme.setSpriteImages(spriteFileName, spriteProperties);
  }
  private void _setSpriteImages(ServletContext servletContext, Theme theme, String resourcePath)
      throws Exception {

    Set<String> resourcePaths = servletContext.getResourcePaths(resourcePath);

    if (resourcePaths == null) {
      return;
    }

    List<File> images = new ArrayList<File>(resourcePaths.size());

    for (String curResourcePath : resourcePaths) {
      if (curResourcePath.endsWith(StringPool.SLASH)) {
        _setSpriteImages(servletContext, theme, curResourcePath);
      } else if (curResourcePath.endsWith(".png")) {
        String realPath = ServletContextUtil.getRealPath(servletContext, curResourcePath);

        if (realPath != null) {
          images.add(new File(realPath));
        } else {
          if (ServerDetector.isTomcat()) {
            if (_log.isInfoEnabled()) {
              _log.info(ServletContextUtil.LOG_INFO_SPRITES);
            }
          } else {
            _log.error("Real path for " + curResourcePath + " is null");
          }
        }
      }
    }

    String spriteFileName = ".sprite.png";
    String spritePropertiesFileName = ".sprite.properties";
    String spritePropertiesRootPath =
        ServletContextUtil.getRealPath(servletContext, theme.getImagesPath());

    Properties spriteProperties =
        SpriteProcessorUtil.generate(
            images,
            spriteFileName,
            spritePropertiesFileName,
            spritePropertiesRootPath,
            16,
            16,
            10240);

    if (spriteProperties == null) {
      return;
    }

    spriteFileName =
        resourcePath.substring(theme.getImagesPath().length(), resourcePath.length())
            + spriteFileName;

    theme.setSpriteImages(spriteFileName, spriteProperties);
  }
  @Override
  public Set<String> getResourcePaths(String s) {
    final String pluginPath = "/plugins/" + pluginManager.getName(plugin) + "/";
    final Set<String> proxyResults = proxy.getResourcePaths(pluginPath + s);
    final Set<String> results = new HashSet<>();
    for (final String proxyResult : proxyResults) {
      results.add(proxyResult.replaceFirst(pluginPath, ""));
    }

    return results;
  }
 /* (non-Javadoc)
  * @see net.jawr.web.resource.handler.ResourceInfoProvider#getResourceNames(java.lang.String)
  */
 @SuppressWarnings("unchecked")
 public Set<String> getResourceNames(String path) {
   Set<String> paths = context.getResourcePaths(path);
   Set<String> names = new HashSet<String>();
   int length = path.length();
   if (null != paths) {
     for (Iterator<String> it = paths.iterator(); it.hasNext(); ) {
       String resourcePath = (String) it.next();
       names.add(resourcePath.substring(length, resourcePath.length()));
     }
   }
   return names;
 }
  public Repository[] getRepositories() throws IOException {
    Set paths = context.getResourcePaths(path);
    List<Repository> list = new ArrayList<Repository>();

    if (paths != null) {
      for (Object obj : paths) {
        String path = (String) obj;
        if (path.endsWith("/")) {
          int n = path.lastIndexOf('/', path.length() - 2);
          String name = path.substring(n + 1, path.length() - 1);
          list.add(lookupRepository(name));
        }
      }
    }
    return list.toArray(new Repository[list.size()]);
  }
 public static void readOntologyFilesInPathSet(String path, ServletContext ctx, Model model) {
   log.debug("Reading ontology files from '" + path + "'");
   Set<String> paths = ctx.getResourcePaths(path);
   if (paths != null) {
     for (String p : paths) {
       String format = getRdfFormat(p);
       log.info("Loading ontology file at " + p + " as format " + format);
       InputStream ontologyInputStream = ctx.getResourceAsStream(p);
       try {
         model.read(ontologyInputStream, null, format);
         log.debug("...successful");
       } catch (Throwable t) {
         log.error("Failed to load ontology file at '" + p + "' as format " + format, t);
       }
     }
   }
 }
  protected void getResources(List<Resource> list, boolean recursive) throws IOException {
    Set paths = context.getResourcePaths(path);

    if (paths != null) {
      for (Object obj : paths) {
        String path = (String) obj;
        if (!path.endsWith("/")) {
          int n = path.lastIndexOf('/', path.length() - 1);
          String name = path.substring(n + 1);
          list.add(lookupResource(name));
        } else if (recursive) {
          int n = path.lastIndexOf('/', path.length() - 2);
          String name = path.substring(n + 1, path.length() - 1);
          AbstractRepository repo = lookupRepository(name);
          repo.getResources(list, true);
        }
      }
    }
  }
Exemple #13
0
 private void processWebInfGroovy(ServletContext sc, Set<String> paths, Set<String> classList) {
   if (paths != null && !paths.isEmpty()) {
     for (String pathElement : paths) {
       if (pathElement.endsWith("/")) {
         processWebInfGroovy(sc, sc.getResourcePaths(pathElement), classList);
       } else {
         if (pathElement.endsWith(SUFFIX)) {
           String cname = convertToClassName(SCRIPT_PATH, pathElement);
           if (containsAnnotation(sc, pathElement)) {
             if (LOGGER.isLoggable(Level.FINE)) {
               LOGGER.log(Level.FINE, "[WEB-INF/groovy] Found annotated Class: {0}", cname);
             }
             classList.add(cname);
           }
         }
       }
     }
   }
 }
  /*
   * Searches the filesystem under /WEB-INF for any TLD files, and adds
   * an implicit map entry to the taglib map for any TLD that has a <uri>
   * element.
   */
  protected void processTldsInFileSystem(String startPath, Map tmpMappings) // SYNC
      throws Exception {

    Set dirList = ctx.getResourcePaths(startPath);
    if (dirList != null) {
      Iterator it = dirList.iterator();
      while (it.hasNext()) {
        String path = (String) it.next();
        if (path.endsWith("/")) {
          processTldsInFileSystem(path, tmpMappings); // SYNC
        }
        if (path.endsWith(".jar")) {
          URL resURL = ctx.getResource(path);
          URLConnection conn = resURL.openConnection();
          conn.setUseCaches(false);
          this.scanJar(conn, resURL.toString(), false, tmpMappings); // SYNC
        } else if (path.endsWith(".tld") == true) {
          InputStream stream = ctx.getResourceAsStream(path);
          String uri = null;
          try {
            uri = getUriFromTld(path, stream);
          } finally {
            if (stream != null) {
              try {
                stream.close();
              } catch (Throwable t) {
                // do nothing
              }
            }
          }
          // Add implicit map entry only if its uri is not already
          // present in the map
          if (uri != null && tmpMappings.get(uri) == null) // SYNC
          {
            tmpMappings.put(uri, new String[] {path, null}); // SYNC
          }
        }
      }
    }
  }
Exemple #15
0
  public FolderOAICatalog(Properties properties, ServletContext context) throws IOException {
    this.context = context;
    String temp;

    dateFormatter.applyPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
    temp = properties.getProperty("NewFileSystemOAICatalog.maxListSize");
    if (temp == null)
      throw new IllegalArgumentException(
          "NewFileSystemOAICatalog." + "maxListSize is missing from the properties file");
    maxListSize = Integer.parseInt(temp);
    if (debug) System.out.println("in NewFileSystemOAICatalog(): maxListSize=" + maxListSize);

    homeDir = properties.getProperty("NewFileSystemOAICatalog.homeDir");
    if (homeDir != null) {
      if (debug) System.out.println("in NewFileSystemOAICatalog(): homeDir=" + homeDir);

      File homeFile = new File(homeDir);
      int homeDirLen = homeFile.getPath().length() + 1;
      loadFileMap(homeDirLen, homeFile);
    } else {
      /* Try looking in a known location */
      Set resourcePaths = context.getResourcePaths("/WEB-INF/DATA/");
      if (resourcePaths == null || resourcePaths.size() == 0) {
        throw new IllegalArgumentException(
            "NewFileSystemOAICatalog." + "homeDir is missing from the properties file");
      }
      String earliestDatestamp = loadFileMap(context, resourcePaths);
      properties.setProperty("Identify.earliestDatestamp", earliestDatestamp);
    }
    //      Iterator iterator = datestampMap.entrySet().iterator();
    //      while (iterator.hasNext()) {
    //      Map.Entry entry = (Map.Entry)iterator.next();
    //      System.out.println(entry.getKey() + ":" + entry.getValue());
    //      }
    sets = getSets(properties);
  }
  /**
   * Creates any result types from the resources available in the web application. This scans the
   * web application resources using the servlet context.
   *
   * @param actionClass The action class the results are being built for.
   * @param results The results map to put the result configs created into.
   * @param resultPath The calculated path to the resources.
   * @param resultPrefix The prefix for the result. This is usually <code>/resultPath/actionName
   *     </code>.
   * @param actionName The action name which is used only for logging in this implementation.
   * @param packageConfig The package configuration which is passed along in order to determine
   * @param resultsByExtension The map of extensions to result type configuration instances.
   */
  protected void createFromResources(
      Class<?> actionClass,
      Map<String, ResultConfig> results,
      final String resultPath,
      final String resultPrefix,
      final String actionName,
      PackageConfig packageConfig,
      Map<String, ResultTypeConfig> resultsByExtension) {
    if (LOG.isTraceEnabled()) {
      LOG.trace(
          "Searching for results in the Servlet container at [#0]" + " with result prefix of [#1]",
          resultPath,
          resultPrefix);
    }

    // Build from web application using the ServletContext
    @SuppressWarnings("unchecked")
    Set<String> paths =
        servletContext.getResourcePaths(flatResultLayout ? resultPath : resultPrefix);
    if (paths != null) {
      for (String path : paths) {
        if (LOG.isTraceEnabled()) {
          LOG.trace("Processing resource path [#0]", path);
        }

        String fileName = StringUtils.substringAfterLast(path, "/");
        if (StringUtils.isBlank(fileName) || StringUtils.startsWith(fileName, ".")) {
          if (LOG.isTraceEnabled()) LOG.trace("Ignoring file without name [#0]", path);
          continue;
        } else if (fileName.lastIndexOf(".") > 0) {
          String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);

          if (conventionsService.getResultTypesByExtension(packageConfig).get(suffix) == null) {
            if (LOG.isDebugEnabled())
              LOG.debug(
                  "No result type defined for file suffix : [#0]. Ignoring file #1",
                  suffix,
                  fileName);
            continue;
          }
        }

        makeResults(actionClass, path, resultPrefix, results, packageConfig, resultsByExtension);
      }
    }

    // Building from the classpath
    String classPathLocation =
        resultPath.startsWith("/") ? resultPath.substring(1, resultPath.length()) : resultPath;
    if (LOG.isTraceEnabled()) {
      LOG.trace(
          "Searching for results in the class path at [#0]"
              + " with a result prefix of [#1] and action name [#2]",
          classPathLocation,
          resultPrefix,
          actionName);
    }

    ResourceFinder finder = new ResourceFinder(classPathLocation, getClassLoaderInterface());
    try {
      Map<String, URL> matches = finder.getResourcesMap("");
      if (matches != null) {
        Test<URL> resourceTest = getResourceTest(resultPath, actionName);
        for (Map.Entry<String, URL> entry : matches.entrySet()) {
          if (resourceTest.test(entry.getValue())) {
            if (LOG.isTraceEnabled()) {
              LOG.trace("Processing URL [#0]", entry.getKey());
            }

            String urlStr = entry.getValue().toString();
            int index = urlStr.lastIndexOf(resultPrefix);
            String path = urlStr.substring(index);
            makeResults(
                actionClass, path, resultPrefix, results, packageConfig, resultsByExtension);
          }
        }
      }
    } catch (IOException ex) {
      if (LOG.isErrorEnabled())
        LOG.error("Unable to scan directory [#0] for results", ex, classPathLocation);
    }
  }
 /* (non-Javadoc)
  * @see net.jawr.web.resource.handler.ResourceInfoProvider#isDirectory(java.lang.String)
  */
 @SuppressWarnings("unchecked")
 public boolean isDirectory(String path) {
   Set<String> paths = context.getResourcePaths(path);
   return (null != paths && paths.size() > 0);
 }
 public Set getResourcePaths(String name) {
   return delegate.getResourcePaths(name);
 }
Exemple #19
0
 /** @see javax.faces.context.ExternalContext#getResourcePaths(String) */
 public Set<String> getResourcePaths(String path) {
   return TypedCollections.dynamicallyCastSet(servletContext.getResourcePaths(path), String.class);
 }
  /**
   * Scan the provided ServletContext and classloader for JAR files. Each JAR file found will be
   * passed to the callback handler to be processed.
   *
   * @param context The ServletContext - used to locate and access WEB-INF/lib
   * @param classloader The classloader - used to access JARs not in WEB-INF/lib
   * @param callback The handler to process any JARs found
   * @param jarsToSkip List of JARs to ignore. If this list is null, a default list will be read
   *     from the system property defined by {@link Constants#SKIP_JARS_PROPERTY}
   */
  @Override
  public void scan(
      ServletContext context,
      ClassLoader classloader,
      JarScannerCallback callback,
      Set<String> jarsToSkip) {

    if (log.isTraceEnabled()) {
      log.trace(sm.getString("jarScan.webinflibStart"));
    }

    Set<String> ignoredJars;
    if (jarsToSkip == null) {
      ignoredJars = defaultJarsToSkip;
    } else {
      ignoredJars = jarsToSkip;
    }
    Set<String[]> ignoredJarsTokens = new HashSet<String[]>();
    for (String pattern : ignoredJars) {
      ignoredJarsTokens.add(Matcher.tokenizePathAsArray(pattern));
    }

    // Scan WEB-INF/lib
    Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
    if (dirList != null) {
      Iterator<String> it = dirList.iterator();
      while (it.hasNext()) {
        String path = it.next();
        if (path.endsWith(Constants.JAR_EXT)
            && !Matcher.matchPath(ignoredJarsTokens, path.substring(path.lastIndexOf('/') + 1))) {
          // Need to scan this JAR
          if (log.isDebugEnabled()) {
            log.debug(sm.getString("jarScan.webinflibJarScan", path));
          }
          URL url = null;
          try {
            url = context.getResource(path);
            process(callback, url);
          } catch (IOException e) {
            log.warn(sm.getString("jarScan.webinflibFail", url), e);
          }
        } else {
          if (log.isTraceEnabled()) {
            log.trace(sm.getString("jarScan.webinflibJarNoScan", path));
          }
        }
      }
    }

    // Scan the classpath
    if (scanClassPath) {
      if (log.isTraceEnabled()) {
        log.trace(sm.getString("jarScan.classloaderStart"));
      }

      ClassLoader loader = Thread.currentThread().getContextClassLoader();

      while (loader != null) {
        if (loader instanceof URLClassLoader) {
          URL[] urls = ((URLClassLoader) loader).getURLs();
          for (int i = 0; i < urls.length; i++) {
            // Extract the jarName if there is one to be found
            String jarName = getJarName(urls[i]);

            // Skip JARs known not to be interesting and JARs
            // in WEB-INF/lib we have already scanned
            if (jarName != null
                && !(Matcher.matchPath(ignoredJarsTokens, jarName)
                    || urls[i].toString().contains(Constants.WEB_INF_LIB + jarName))) {
              if (log.isDebugEnabled()) {
                log.debug(sm.getString("jarScan.classloaderJarScan", urls[i]));
              }
              try {
                process(callback, urls[i]);
              } catch (IOException ioe) {
                log.warn(sm.getString("jarScan.classloaderFail", urls[i]), ioe);
              }
            } else {
              if (log.isTraceEnabled()) {
                log.trace(sm.getString("jarScan.classloaderJarNoScan", urls[i]));
              }
            }
          }
        }
        loader = loader.getParent();
      }
    }
  }
Exemple #21
0
  public Set<String> getScripts() {
    Set<String> scripts = new HashSet<>();
    processWebInfGroovy(servletContext, servletContext.getResourcePaths(SCRIPT_PATH), scripts);

    return scripts;
  }
 public Set<String> getResourcePaths(String path) {
   return context.getResourcePaths(canonicalURI(path));
 }
 @Override
 public Set<String> getResourcePaths(String path) {
   return sc.getResourcePaths(path);
 }
  /**
   * Scan the provided ServletContext and classloader for JAR files. Each JAR file found will be
   * passed to the callback handler to be processed.
   *
   * @param context The ServletContext - used to locate and access WEB-INF/lib
   * @param classloader The classloader - used to access JARs not in WEB-INF/lib
   * @param callback The handler to process any JARs found
   * @param jarsToSkip List of JARs to ignore. If this list is null, a default list will be read
   *     from the system property defined by {@link Constants#SKIP_JARS_PROPERTY}
   */
  @Override
  public void scan(
      ServletContext context,
      ClassLoader classloader,
      JarScannerCallback callback,
      Set<String> jarsToSkip) {

    if (log.isTraceEnabled()) {
      log.trace(sm.getString("jarScan.webinflibStart"));
    }

    final Set<String> ignoredJars;
    if (jarsToSkip == null) {
      ignoredJars = defaultJarsToSkip;
    } else {
      ignoredJars = jarsToSkip;
    }

    // Scan WEB-INF/lib
    Set<String> dirList = context.getResourcePaths(Constants.WEB_INF_LIB);
    if (dirList != null) {
      Iterator<String> it = dirList.iterator();
      while (it.hasNext()) {
        String path = it.next();
        if (path.endsWith(Constants.JAR_EXT)
            && !Matcher.matchName(ignoredJars, path.substring(path.lastIndexOf('/') + 1))) {
          // Need to scan this JAR
          if (log.isDebugEnabled()) {
            log.debug(sm.getString("jarScan.webinflibJarScan", path));
          }
          URL url = null;
          try {
            // File URLs are always faster to work with so use them
            // if available.
            String realPath = context.getRealPath(path);
            if (realPath == null) {
              url = context.getResource(path);
            } else {
              url = (new File(realPath)).toURI().toURL();
            }
            process(callback, url);
          } catch (IOException e) {
            log.warn(sm.getString("jarScan.webinflibFail", url), e);
          }
        } else {
          if (log.isTraceEnabled()) {
            log.trace(sm.getString("jarScan.webinflibJarNoScan", path));
          }
        }
      }
    }

    // Scan the classpath
    if (scanClassPath && classloader != null) {
      if (log.isTraceEnabled()) {
        log.trace(sm.getString("jarScan.classloaderStart"));
      }

      ClassLoader loader = classloader;

      ClassLoader stopLoader = null;
      if (!scanBootstrapClassPath) {
        // Stop when we reach the bootstrap class loader
        stopLoader = ClassLoader.getSystemClassLoader().getParent();
      }

      while (loader != null && loader != stopLoader) {
        if (loader instanceof URLClassLoader) {
          URL[] urls = ((URLClassLoader) loader).getURLs();
          for (int i = 0; i < urls.length; i++) {
            // Extract the jarName if there is one to be found
            String jarName = getJarName(urls[i]);

            // Skip JARs known not to be interesting and JARs
            // in WEB-INF/lib we have already scanned
            if (jarName != null
                && !(Matcher.matchName(ignoredJars, jarName)
                    || urls[i].toString().contains(Constants.WEB_INF_LIB + jarName))) {
              if (log.isDebugEnabled()) {
                log.debug(sm.getString("jarScan.classloaderJarScan", urls[i]));
              }
              try {
                process(callback, urls[i]);
              } catch (IOException ioe) {
                log.warn(sm.getString("jarScan.classloaderFail", urls[i]), ioe);
              }
            } else {
              if (log.isTraceEnabled()) {
                log.trace(sm.getString("jarScan.classloaderJarNoScan", urls[i]));
              }
            }
          }
        }
        loader = loader.getParent();
      }
    }
  }
  private void processPaths(String... paths) {
    for (final String path : paths) {

      final Set<String> resourcePaths = sc.getResourcePaths(path);
      if (resourcePaths == null) {
        break;
      }

      resourceFinderStack.push(
          new ResourceFinder() {

            private Deque<String> resourcePathsStack =
                new LinkedList<String>() {

                  private static final long serialVersionUID = 3109256773218160485L;

                  {
                    for (String resourcePath : resourcePaths) {
                      push(resourcePath);
                    }
                  }
                };
            private String current;
            private String next;

            @Override
            public boolean hasNext() {
              while (next == null && !resourcePathsStack.isEmpty()) {
                next = resourcePathsStack.pop();

                if (next.endsWith("/")) {
                  processPaths(next);
                  next = null;
                } else if (next.endsWith(".jar")) {
                  try {
                    resourceFinderStack.push(
                        new JarFileScanner(sc.getResourceAsStream(next), "", true));
                  } catch (IOException ioe) {
                    throw new ResourceFinderException(ioe);
                  }
                  next = null;
                }
              }

              return next != null;
            }

            @Override
            public String next() {
              if (next != null || hasNext()) {
                current = next;
                next = null;
                return current;
              }

              throw new NoSuchElementException();
            }

            @Override
            public void remove() {
              throw new UnsupportedOperationException();
            }

            @Override
            public InputStream open() {
              return sc.getResourceAsStream(current);
            }

            @Override
            public void reset() {
              throw new UnsupportedOperationException();
            }
          });
    }
  }