Class AssetLookup

  • All Implemented Interfaces:
    java.io.Serializable

    public class AssetLookup
    extends java.lang.Object
    implements java.io.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:
    Serialized Form
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  AssetLookup.AssetLocation
      Represent resolved asset location: actual classpath path (absolute) and target class loader (where resource found).
    • Constructor Summary

      Constructors 
      Constructor Description
      AssetLookup​(java.lang.String primaryLocation, com.google.common.collect.Multimap<java.lang.String,​java.lang.String> locations, com.google.common.collect.Multimap<java.lang.String,​java.lang.ClassLoader> loaders)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      com.google.common.collect.Multimap<java.lang.String,​java.lang.ClassLoader> getLoaders()
      Returned map contains not only custom class loaders but also default class loader (this is important to grant proper resource override sequence).
      com.google.common.collect.Multimap<java.lang.String,​java.lang.String> getLocations()  
      java.util.Set<java.lang.ClassLoader> getMatchingLoaders​(java.lang.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.
      java.util.List<java.lang.String> getMatchingLocations​(java.lang.String url)
      Supposed to be used for error reporting.
      java.lang.String getPrimaryLocation()  
      java.lang.String getRelativePath​(java.lang.String path)
      Checks if provided path is an absolute path into primary location and returns relative url instead.
      java.net.URL load​(java.lang.String assetPath)
      Loads asset from classpath.
      AssetLookup.AssetLocation lookup​(java.lang.String path)
      General lookup mechanism (used by lookupUrl(String) and lookupPath(String) shortcuts.
      java.lang.String lookupPath​(java.lang.String url)
      Same as lookupUrl(String) but returns resolved absolute location in classpath (may be in custom class loader).
      java.net.URL lookupUrl​(java.lang.String url)
      Lookup asset in classpath by path (relative to application root).
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • AssetLookup

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

      • getPrimaryLocation

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

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

        public com.google.common.collect.Multimap<java.lang.String,​java.lang.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 java.lang.String getRelativePath​(java.lang.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 java.net.URL lookupUrl​(java.lang.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 java.lang.String lookupPath​(java.lang.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 java.net.URL load​(java.lang.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​(java.lang.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 java.util.List<java.lang.String> getMatchingLocations​(java.lang.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 java.util.Set<java.lang.ClassLoader> getMatchingLoaders​(java.lang.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