Class AssetLookup

java.lang.Object
ru.vyarus.guicey.gsp.app.asset.AssetLookup
All Implemented Interfaces:
Serializable

public class AssetLookup extends Object implements Serializable
GSP application assets resolution (for exact application with all its extensions).

Assets stored in classpath. Multiple classpath locations could be mapped for assets (overriding default location). Some assets could be mapped into exact urls (with ability to override too).

Also, assets may be resolved through special class loaders. Possible example is attaching additional folders as resource folder using custom class loader.

WARNING: custom class loader will be automatically supported for static resources, but template engine may not be able to resolve template. For example, freemarker use class loader of resource class serving view, so if resource class and view template are in the same class loader then it will work. For sure direct template rendering (without custom resource class) will not work. Freemarker may be configured to support all cases by using custom template loader, activated with global bundle shortcut ServerPagesBundle.ViewsBuilder.enableFreemarkerCustomClassLoadersSupport(). Mustache is impossible to configure properly (with current mustache views renderer). The problem with view implementations is that they accept only path to template for rendering and will lookup it by default only in application classloader.

Overall, lookup performs two operations: lookup classpath path by url (probably using extra mapping) and resource loading itself. First phase obviously performs lookup too (duplicates second phase), but separate phases are still required to be able to lookup templates directly (using proper class loader).

Since:
26.11.2019
See Also:
  • Constructor Details

    • AssetLookup

      public AssetLookup(String primaryLocation, com.google.common.collect.Multimap<String,String> locations, com.google.common.collect.Multimap<String,ClassLoader> loaders)
  • Method Details

    • getPrimaryLocation

      public String getPrimaryLocation()
      Returns:
      main application assets classpath path
    • getLocations

      public com.google.common.collect.Multimap<String,String> getLocations()
      Returns:
      assets mapping paths
    • getLoaders

      public com.google.common.collect.Multimap<String,ClassLoader> getLoaders()
      Returned map contains not only custom class loaders but also default class loader (this is important to grant proper resource override sequence). Default class loader is AssetSources.DEFAULT_LOADER.
      Returns:
      classpath paths mapping to class loaders
    • getRelativePath

      public String getRelativePath(String path)
      Checks if provided path is an absolute path into primary location and returns relative url instead. It cuts off application url prefix in order to resolve proper path under all registered locations. For example, if application registered for "/app/*" then incoming resource request may be "/app/css/style.css", but actual resource path is "css/style.css" which we will look under classpath (classpath locations also registered by root locations so if app declared its resources under "com.foo.app" package then resource will be searched as "com.foo.app.css/style.css" (the same for all extended locations).
      Parameters:
      path - possibly absolute path
      Returns:
      relative path (without primary location part if detected)
    • lookupUrl

      public URL lookupUrl(String url)
      Lookup asset in classpath by path (relative to application root). Assets, registered to exact path processed in priority. For example, if assets registered for '/foo/bar/' path then path '/foo/bar/sample.css' will be checked first in path-specific assets. Multiple asset packages copuld be configured on each path: assets checked in registration-reverse order to grant regitstration order priority (resources from package, registered later are prioritized).

      Url may contain application mapping url (so be url relative to server root): getRelativePath(String) will be used to cut off mapping prefix.

      Parameters:
      url - path to find asset for
      Returns:
      matched asset or null if not found
    • lookupPath

      public String lookupPath(String url)
      Same as lookupUrl(String) but returns resolved absolute location in classpath (may be in custom class loader). This has to be used for templates resolution (views) which does not support direct file specification. It is assumed that later such path will be loaded with load(String) which will find proper class loader (again).

      Url may contain application mapping url (so be url relative to server root): getRelativePath(String) will be used to cut off mapping prefix.

      Parameters:
      url - path to find asset for
      Returns:
      matched absolute classpath path or null if not found
    • load

      public URL load(String assetPath)
      Loads asset from classpath. Will select proper class loader if custom class loaders used. It is assumed to mainly load paths after lookupPath(String), but may be used as general loading mechanism.

      Will check first if provided path is already an absolute classpath location (assumed to be resolved with lookupPath(String)) and if nothing found perform full relative matching with lookupUrl(String) (kind of fallback mechanism).

      Parameters:
      assetPath - exact classpath path
      Returns:
      found resource or null
    • lookup

      public AssetLookup.AssetLocation lookup(String path)
      General lookup mechanism (used by lookupUrl(String) and lookupPath(String) shortcuts.

      Lookup asset in classpath by path (relative to application root). Assets, registered to exact path processed in priority. For example, if assets registered for '/foo/bar/' path then path '/foo/bar/sample.css' will be checked first in path-specific assets. Multiple asset packages could be configured on each path: assets checked in registration-reverse order to grant regitstration order priority (resources from package, registered later are prioritized).

      Parameters:
      path - path to find asset for
      Returns:
      matched location or null if not found
    • getMatchingLocations

      public List<String> getMatchingLocations(String url)
      Supposed to be used for error reporting. Return locations in package notion.
      Parameters:
      url - url relative to application root
      Returns:
      matching classpath locations (where resource may be found)
    • getMatchingLoaders

      public Set<ClassLoader> getMatchingLoaders(String assetPath)
      NOTE: method will return not only custom class loaders but also default application loader (AssetSources.DEFAULT_LOADER) because otherwise it will be impossible to preserve intended loading order.

      It may return empty set ONLY if requested absolute path is outside of any registered asset locations (incorrect usage).

      Parameters:
      assetPath - classpath path (absolute!)
      Returns:
      set (to avoid default classloader duplicates) of custom class loaders