All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.matrixweb.smaller.servlet.ResourceScanner Maven / Gradle / Ivy

package de.matrixweb.smaller.servlet;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import javax.servlet.ServletContext;

/**
 * @author marwol
 */
public class ResourceScanner {

  private final ServletContext servletContext;

  private final String[] includes;

  private final String[] excludes;

  /**
   * @param servletContext
   * @param includes
   * @param excludes
   */
  public ResourceScanner(final ServletContext servletContext,
      final String[] includes, final String[] excludes) {
    this.servletContext = servletContext;
    this.includes = includes;
    this.excludes = excludes;
  }

  /**
   * @return Returns a set of all resources matching the given includes and
   *         excludes definition
   */
  public Set getResources() {
    final Set resources = new HashSet();

    for (final String include : this.includes) {
      resources.addAll(findCandidates("/", include));
    }
    for (final String exclude : this.excludes) {
      for (final String match : filterRecursive(resources, "/", exclude,
          !exclude.startsWith("**"))) {
        resources.remove(match);
      }
    }
    resources.remove(null);

    return resources;
  }

  private Set findCandidates(final String base, final String include) {
    final Set candidates = new HashSet();

    final int starstar = include.indexOf("**");
    if (starstar > -1) {
      candidates.addAll(filterRecursive(base, include, starstar, starstar > 0));
    } else {
      final int star = include.indexOf('*');
      if (star > -1) {
        candidates.addAll(filterRecursive(base, include, star, true));
      } else {
        candidates.add(findDirect(base, include));
      }
    }

    return candidates;
  }

  @SuppressWarnings("unchecked")
  private Set findRecursive(final String base) {
    final Set matches = new HashSet();

    for (final String match : (Set) this.servletContext
        .getResourcePaths(base)) {
      if (match.endsWith("/")) {
        matches.addAll(findRecursive(match));
      } else {
        matches.add(match);
      }
    }

    return matches;
  }

  private Set filterRecursive(final String base, final String include,
      final int index, final boolean prefixPatternWithBase) {
    return filterRecursive(findRecursive(base + include.substring(0, index)),
        base, include, prefixPatternWithBase);
  }

  private Set filterRecursive(final Set matches,
      final String base, final String include,
      final boolean prefixPatternWithBase) {
    final Set result = new HashSet();

    String pattern = include.replace(".", "\\.").replace("**", "#starstar#")
        .replace("*", "[^/]+").replace("#starstar#", ".*");
    if (prefixPatternWithBase) {
      pattern = base + pattern;
    }
    final Pattern expr = Pattern.compile(pattern);
    for (final String match : matches) {
      if (match != null && expr.matcher(match).matches()) {
        result.add(match);
      }
    }

    return result;
  }

  @SuppressWarnings("unchecked")
  private String findDirect(final String base, final String include) {
    final String parent = include.substring(0, include.lastIndexOf('/'));
    for (final String match : (Set) this.servletContext
        .getResourcePaths(base + parent)) {
      if (match.equals(base + include)) {
        return match;
      }
    }
    return null;
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy