static String canonicalizePath ( String path ) { String [ ] parts = path . split ( MODULE_SLASH ) ; String [ ] buffer = new String [ parts . length ] ; int position = 0 ; int available = 0 ; boolean absolutePath = ( parts . length > 1 && parts [ 0 ] . isEmpty ( ) ) ; if ( absolutePath ) { // If the path starts with "/" (so the left side, index zero, is empty), then the path will // always remain absolute. Make the first segment unavailable to touch. -- available ; } for ( String part : parts ) { if ( part . equals ( "." ) ) { continue ; } if ( part . equals ( ".." ) ) { if ( available > 0 ) { // Consume the previous segment. -- position ; -- available ; buffer [ position ] = null ; } else if ( ! absolutePath ) { // If this is a relative path, retain "..", as it can't be consumed on the left. buffer [ position ] = part ; ++ position ; } continue ; } buffer [ position ] = part ; ++ position ; ++ available ; } if ( absolutePath && position == 1 ) { return MODULE_SLASH ; // special-case single absolute segment as joining [""] doesn't work } return MODULE_JOINER . join ( Arrays . copyOf ( buffer , position ) ) ; }
Canonicalize a given path removing segments containing . and consuming segments for .. .