public static List < Resource > parsePath ( final SecurityContext securityContext , final HttpServletRequest request , final Map < Pattern , Class < ? extends Resource > > resourceMap , final Value < String > propertyView ) throws FrameworkException { final String path = request . getPathInfo ( ) ; // intercept empty path and send 204 No Content if ( StringUtils . isBlank ( path ) ) { throw new NoResultsException ( "No content" ) ; } // 1.: split request path into URI parts final String [ ] pathParts = path . split ( "[/]+" ) ; // 2.: create container for resource constraints final Set < String > propertyViews = Services . getInstance ( ) . getConfigurationProvider ( ) . getPropertyViews ( ) ; final List < Resource > resourceChain = new ArrayList <> ( pathParts . length ) ; // 3.: try to assign resource constraints for each URI part for ( int i = 0 ; i < pathParts . length ; i ++ ) { // eliminate empty strings final String part = pathParts [ i ] . trim ( ) ; if ( part . length ( ) > 0 ) { boolean found = false ; // check views first if ( propertyViews . contains ( part ) ) { Resource resource = new ViewFilterResource ( ) ; resource . checkAndConfigure ( part , securityContext , request ) ; resource . configurePropertyView ( propertyView ) ; resourceChain . add ( resource ) ; // mark this part as successfully parsed found = true ; } else { // look for matching pattern for ( Map . Entry < Pattern , Class < ? extends Resource > > entry : resourceMap . entrySet ( ) ) { Pattern pattern = entry . getKey ( ) ; Matcher matcher = pattern . matcher ( pathParts [ i ] ) ; if ( matcher . matches ( ) ) { Class < ? extends Resource > type = entry . getValue ( ) ; Resource resource = null ; try { // instantiate resource constraint resource = type . newInstance ( ) ; } catch ( Throwable t ) { logger . warn ( "Error instantiating resource class" , t ) ; } if ( resource != null ) { // set security context resource . setSecurityContext ( securityContext ) ; if ( resource . checkAndConfigure ( part , securityContext , request ) ) { logger . debug ( "{} matched, adding resource of type {} for part {}" , new Object [ ] { matcher . pattern ( ) , type . getName ( ) , part } ) ; // allow constraint to modify context resource . configurePropertyView ( propertyView ) ; // add constraint and go on resourceChain . add ( resource ) ; found = true ; // first match wins, so choose priority wisely ;) break ; } } } } } if ( ! found ) { throw new NotFoundException ( "Cannot resolve URL path" ) ; } } } return resourceChain ; }
Parse the request path and match with possible resource patterns