1# Copyright 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import posixpath 6 7from docs_server_utils import StringIdentity 8from file_system import FileSystem 9from future import Future 10 11 12class ChrootFileSystem(FileSystem): 13 '''ChrootFileSystem(fs, path) exposes a FileSystem whose root is |path| inside 14 |fs|, so ChrootFileSystem(fs, 'hello').Read(['world']) is equivalent to 15 fs.Read(['hello/world']) with the 'hello' prefix stripped from the result. 16 ''' 17 18 def __init__(self, file_system, root): 19 '''Parameters: 20 |file_system| The FileSystem instance to transpose paths of. 21 |root| The path to transpose all Read/Stat calls by. 22 ''' 23 self._file_system = file_system 24 self._root = root.strip('/') 25 26 def Read(self, paths, skip_not_found=False): 27 # Maintain reverse mapping so the result can be mapped to the original 28 # paths given (the result from |file_system| will include |root| in the 29 # result, which would be wrong). 30 prefixed_paths = {} 31 def prefix(path): 32 prefixed = posixpath.join(self._root, path) 33 prefixed_paths[prefixed] = path 34 return prefixed 35 future_result = self._file_system.Read( 36 tuple(prefix(path) for path in paths), 37 skip_not_found=skip_not_found) 38 def resolve(): 39 return dict((prefixed_paths[path], content) 40 for path, content in future_result.Get().iteritems()) 41 return Future(callback=resolve) 42 43 def Refresh(self): 44 return self._file_system.Refresh() 45 46 def Stat(self, path): 47 return self._file_system.Stat(posixpath.join(self._root, path)) 48 49 def GetIdentity(self): 50 return StringIdentity( 51 '%s/%s' % (self._file_system.GetIdentity(), self._root)) 52 53 def __repr__(self): 54 return 'ChrootFileSystem(%s, %s)' % ( 55 self._root, repr(self._file_system)) 56