/**
   * Retrieves the static resource path for the given Grails resource artifact (controller/taglib
   * etc.)
   *
   * @param resource The Resource
   * @param contextPath The additonal context path to prefix
   * @return The resource path
   */
  public static String getStaticResourcePathForResource(Resource resource, String contextPath) {

    if (contextPath == null) contextPath = "";
    if (resource == null) return contextPath;

    String url;
    try {
      url = resource.getURL().toString();
    } catch (IOException e) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Error reading URL whilst resolving static resource path from ["
                + resource
                + "]: "
                + e.getMessage(),
            e);
      }
      return contextPath;
    }

    Matcher m = PLUGIN_RESOURCE_PATTERN.matcher(url);
    if (m.find()) {
      return (contextPath.length() > 0 ? contextPath + "/" : "") + m.group(1);
    }

    return contextPath;
  }
  /**
   * Takes a Grails resource (one located inside the grails-app dir) and gets its relative path
   * inside the WEB-INF directory when deployed.
   *
   * @param resource The Grails resource, which is a file inside the grails-app dir
   * @return The relative URL of the file inside the WEB-INF dir at deployment time or null if it
   *     cannot be established
   */
  public static String getRelativeInsideWebInf(Resource resource) {
    if (resource == null) return null;

    try {
      String url = resource.getURL().toString();
      int i = url.indexOf(WEB_INF);
      if (i > -1) {
        return url.substring(i);
      }

      Matcher m = PLUGIN_PATTERN.matcher(url);
      if (m.find()) {
        return WEB_INF + m.group(1);
      }

      i = url.lastIndexOf(GRAILS_APP_DIR);
      if (i > -1) {
        return WEB_INF + "/" + url.substring(i);
      }
    } catch (IOException e) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Error reading URL whilst resolving relative path within WEB-INF from ["
                + resource
                + "]: "
                + e.getMessage(),
            e);
      }
      return null;
    }
    return null;
  }
 public static boolean isGrailsResource(Resource r) {
   try {
     return isGrailsPath(r.getURL().getFile());
   } catch (IOException e) {
     return false;
   }
 }
  public static Resource getViewsDir(Resource resource) {
    if (resource == null) return null;

    try {
      Resource appDir = getAppDir(resource);
      return new UrlResource(appDir.getURL().toString() + "/views");
    } catch (IOException e) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Error reading URL whilst resolving views dir from ["
                + resource
                + "]: "
                + e.getMessage(),
            e);
      }
      return null;
    }
  }
  public static Resource getAppDir(Resource resource) {
    if (resource == null) return null;

    try {
      String url = resource.getURL().toString();

      int i = url.lastIndexOf(GRAILS_APP_DIR);
      if (i > -1) {
        url = url.substring(0, i + 10);
        return new UrlResource(url);
      }

      return null;
    } catch (MalformedURLException e) {
      return null;
    } catch (IOException e) {
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Error reading URL whilst resolving app dir from [" + resource + "]: " + e.getMessage(),
            e);
      }
      return null;
    }
  }