[!!!][TASK] Driver API has too many crosscutting concerns 20/26520/12
authorSteffen Ritter <info@rs-websystems.de>
Sat, 14 Dec 2013 10:33:35 +0000 (11:33 +0100)
committerBenjamin Mack <benni@typo3.org>
Wed, 15 Jan 2014 13:57:53 +0000 (14:57 +0100)
The Driver within the FileAbstractionLayer is the actual
abstraction of a concrete file-system meant to unify
access to several kind of storage-systems the file data
might reside in. For each way of storing files there
has to be a driver.

Therefore a driver is solely a unique API to interact with
an underlying storage system based upon its own identifier
system.

Opposite to that, the AbstractDriver (defining our Interface)
knows about its storage, file- and folder-objects as well
as indexes. The methods within the current driver need to
implement more FAL-internal logic than one would expect from
what the driver is purposed to. As a result only a few drivers
are existing by now. In addition it's nearly impossible to
change FAL interals without touching every driver out there.

This change deals with these problems. In several steps the
current driver API has been refactored to have less dependencies
and only fullfills it's original purpose: the abstraction of a
file storage system.

The following things are considered:
   1. Change every return value which has been an object to the
      identifier and adapt the ResourceStorage accordingly.
   2. Change every method parameter being FileInterface, File,
      AbstractFile or Folder objects to a string: the identifier.
   3. Get rid of the storage as a member variable, only the uid
      of the storage is needed at two places.
   4. Remove all abstract methods from the AbstractDriver and
      put them in a newly created DriverInterface.
   5. Exchange all references to AbstractDriver to the interface.
   6. Remove unused methods, which came to light doing so.
   7. Merge addFile/removeFile and *Raw since the do the same if
      no objects are in place.
   8. Unify the creation of folder objects and how information
      is retrieved (analogue to files now).
   9. Unify and simplify the methods for retrieving folder
      contents (files / folders).
  10. Adapt the UnitTests of both classes to the changes.
      This also leads to the removal of some tests which are
      superfluous with that change.
  11. Make the DriverRegistry check the implementation of the
      newly created interface.
  12. Unify the parameter names in the methods.

Releases: 6.2
Resolves: #54230
Resolves: #54231
Change-Id: I4a51572c6a10859e6fd5f12f6cb539950444992e
Reviewed-on: https://review.typo3.org/26520
Reviewed-by: Frans Saris
Tested-by: Frans Saris
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
17 files changed:
typo3/sysext/core/Classes/Resource/Driver/AbstractDriver.php
typo3/sysext/core/Classes/Resource/Driver/AbstractHierarchicalFilesystemDriver.php
typo3/sysext/core/Classes/Resource/Driver/DriverInterface.php [new file with mode: 0644]
typo3/sysext/core/Classes/Resource/Driver/DriverRegistry.php
typo3/sysext/core/Classes/Resource/Driver/LocalDriver.php
typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php
typo3/sysext/core/Classes/Resource/Filter/FileNameFilter.php
typo3/sysext/core/Classes/Resource/Folder.php
typo3/sysext/core/Classes/Resource/ResourceFactory.php
typo3/sysext/core/Classes/Resource/ResourceStorage.php
typo3/sysext/core/Classes/Resource/Service/FileProcessingService.php
typo3/sysext/core/Tests/Unit/Resource/Driver/AbstractDriverTest.php
typo3/sysext/core/Tests/Unit/Resource/Driver/DriverRegistryTest.php
typo3/sysext/core/Tests/Unit/Resource/Driver/LocalDriverTest.php
typo3/sysext/core/Tests/Unit/Resource/ResourceStorageTest.php
typo3/sysext/core/Tests/Unit/Resource/Utility/FileExtensionFilterTest.php
typo3/sysext/filelist/Classes/FileList.php

index 0bbd9f3..173cec4 100644 (file)
@@ -34,40 +34,36 @@ use TYPO3\CMS\Core\Utility\PathUtility;
 /**
  * An abstract implementation of a storage driver.
  *
- * @author Ingmar Schlecht <ingmar.schlecht@typo3.org>
- * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
  */
-abstract class AbstractDriver {
+abstract class AbstractDriver implements DriverInterface {
 
+       /*******************
+        * CAPABILITIES
+        *******************/
        /**
-        * The mount object this driver instance belongs to
+        * The capabilities of this driver. See Storage::CAPABILITY_* constants for possible values. This value should be set
+        * in the constructor of derived classes.
         *
-        * @var \TYPO3\CMS\Core\Resource\ResourceStorage
+        * @var integer
         */
-       protected $storage;
+       protected $capabilities = 0;
 
-       /**
-        * A list of all supported hash algorithms, written all lower case and
-        * without any dashes etc. (e.g. sha1 instead of SHA-1)
-        * Be sure to set this in inherited classes!
-        *
-        * @var array
-        */
-       protected $supportedHashAlgorithms = array();
 
        /**
-        * The storage folder that forms the root of this FS tree
+        * The storage uid the driver was instantiated for
         *
-        * @var Folder
+        * @var integer
         */
-       protected $rootLevelFolder;
+       protected $storageUid;
 
        /**
-        * The default folder new files should be put into.
+        * A list of all supported hash algorithms, written all lower case and
+        * without any dashes etc. (e.g. sha1 instead of SHA-1)
+        * Be sure to set this in inherited classes!
         *
-        * @var Folder
+        * @var array
         */
-       protected $defaultLevelFolder;
+       protected $supportedHashAlgorithms = array();
 
        /**
         * The configuration of this driver
@@ -77,20 +73,6 @@ abstract class AbstractDriver {
        protected $configuration = array();
 
        /**
-        * The callback method to handle the files when listing folder contents
-        *
-        * @var string
-        */
-       protected $fileListCallbackMethod = 'getFileList_itemCallback';
-
-       /**
-        * The callback method to handle the folders when listing folder contents
-        *
-        * @var string
-        */
-       protected $folderListCallbackMethod = 'getFolderList_itemCallback';
-
-       /**
         * Creates this object.
         *
         * @param array $configuration
@@ -100,21 +82,13 @@ abstract class AbstractDriver {
        }
 
        /**
-        * Initializes this object. This is called by the storage after the driver
-        * has been attached.
-        *
-        * @return void
-        */
-       abstract public function initialize();
-
-       /**
-        * Checks a fileName for validity. This could be overriden in concrete
+        * Checks a fileName for validity. This could be overidden in concrete
         * drivers if they have different file naming rules.
         *
         * @param string $fileName
         * @return boolean TRUE if file name is valid
         */
-       public function isValidFilename($fileName) {
+       protected function isValidFilename($fileName) {
                if (strpos($fileName, '/') !== FALSE) {
                        return FALSE;
                }
@@ -125,71 +99,15 @@ abstract class AbstractDriver {
        }
 
        /**
-        * Sets the storage object that works with this driver
+        * Sets the storage uid the driver belongs to
         *
-        * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storage
-        * @return \TYPO3\CMS\Core\Resource\Driver\AbstractDriver
-        */
-       public function setStorage(\TYPO3\CMS\Core\Resource\ResourceStorage $storage) {
-               $this->storage = $storage;
-               return $this;
-       }
-
-       /**
-        * Checks if a configuration is valid for this driver.
-        * Throws an exception if a configuration will not work.
-        *
-        * @abstract
-        * @param array $configuration
+        * @param integer $storageUid
         * @return void
         */
-       static abstract public function verifyConfiguration(array $configuration);
-
-       /**
-        * processes the configuration, should be overridden by subclasses
-        *
-        * @return void
-        */
-       abstract public function processConfiguration();
-
-       /**
-        * Returns the name of a file/folder based on its identifier.
-        *
-        * @param string $identifier
-        * @return string
-        */
-       protected function getNameFromIdentifier($identifier) {
-               return PathUtility::basename($identifier);
-       }
-
-       /**
-        * Generic handler method for directory listings - gluing together the
-        * listing items is done
-        *
-        * @param string $basePath
-        * @param integer $start
-        * @param integer $numberOfItems
-        * @param array $filterMethods The filter methods used to filter the directory items
-        * @param string $itemHandlerMethod
-        * @param array $itemRows
-        * @param boolean $recursive
-        * @return array
-        */
-       protected function getDirectoryItemList($basePath, $start, $numberOfItems, array $filterMethods, $itemHandlerMethod, $itemRows = array(), $recursive = FALSE) {
-
+       public function setStorageUid($storageUid) {
+               $this->storageUid = $storageUid;
        }
 
-       /*******************
-        * CAPABILITIES
-        *******************/
-       /**
-        * The capabilities of this driver. See Storage::CAPABILITY_* constants for possible values. This value should be set
-        * in the constructor of derived classes.
-        *
-        * @var integer
-        */
-       protected $capabilities = 0;
-
        /**
         * Returns the capabilities of this driver.
         *
@@ -213,44 +131,16 @@ abstract class AbstractDriver {
        /*******************
         * FILE FUNCTIONS
         *******************/
-       /**
-        * Returns a temporary path for a given file, including the file extension.
-        *
-        * @param FileInterface $file
-        * @return string
-        */
-       protected function getTemporaryPathForFile(FileInterface $file) {
-               return \TYPO3\CMS\Core\Utility\GeneralUtility::tempnam('fal-tempfile-') . '.' . $file->getExtension();
-       }
-
-       /**
-        * Returns the public URL to a file.
-        *
-        * @abstract
-        * @param \TYPO3\CMS\Core\Resource\ResourceInterface $resource
-        * @param bool  $relativeToCurrentScript    Determines whether the URL returned should be relative to the current script, in case it is relative at all (only for the LocalDriver)
-        * @return string
-        */
-       abstract public function getPublicUrl(\TYPO3\CMS\Core\Resource\ResourceInterface $resource, $relativeToCurrentScript = FALSE);
 
        /**
-        * Returns a list of all hashing algorithms this Storage supports.
-        *
-        * @return array
-        */
-       public function getSupportedHashAlgorithms() {
-               return $this->supportedHashAlgorithms;
-       }
-
-       /**
-        * Creates a (cryptographic) hash for a file.
+        * Returns a temporary path for a given file, including the file extension.
         *
-        * @abstract
         * @param string $fileIdentifier
-        * @param string $hashAlgorithm The hash algorithm to use
         * @return string
         */
-       abstract public function hash($fileIdentifier, $hashAlgorithm);
+       protected function getTemporaryPathForFile($fileIdentifier) {
+               return \TYPO3\CMS\Core\Utility\GeneralUtility::tempnam('fal-tempfile-') . '.' . PathUtility::basename($fileIdentifier);
+       }
 
        /**
         * Hashes a file identifier, taking the case sensitivity of the file system
@@ -266,137 +156,6 @@ abstract class AbstractDriver {
        }
 
        /**
-        * Creates a new file and returns the matching file object for it.
-        *
-        * @abstract
-        * @param string $fileName
-        * @param Folder $parentFolder
-        * @return \TYPO3\CMS\Core\Resource\File
-        */
-       abstract public function createFile($fileName, Folder $parentFolder);
-
-       /**
-        * Returns the contents of a file. Beware that this requires to load the
-        * complete file into memory and also may require fetching the file from an
-        * external location. So this might be an expensive operation (both in terms
-        * of processing resources and money) for large files.
-        *
-        * @param FileInterface $file
-        * @return string The file contents
-        */
-       abstract public function getFileContents(FileInterface $file);
-
-       /**
-        * Sets the contents of a file to the specified value.
-        *
-        * @param FileInterface $file
-        * @param string $contents
-        * @return integer The number of bytes written to the file
-        * @throws \RuntimeException if the operation failed
-        */
-       abstract public function setFileContents(FileInterface $file, $contents);
-
-       /**
-        * Adds a file from the local server hard disk to a given path in TYPO3s virtual file system.
-        *
-        * This assumes that the local file exists, so no further check is done here!
-        *
-        * @param string $localFilePath
-        * @param Folder $targetFolder
-        * @param string $fileName The name to add the file under
-        * @param \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject Optional file object to update (instead of creating a new object). With this parameter, this function can be used to "populate" a dummy file object with a real file underneath.
-        * @return FileInterface
-        */
-       abstract public function addFile($localFilePath, Folder $targetFolder, $fileName, \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject = NULL);
-
-       /**
-        * Checks if a resource exists - does not care for the type (file or folder).
-        *
-        * @param $identifier
-        * @return boolean
-        */
-       abstract public function resourceExists($identifier);
-
-       /**
-        * Checks if a file exists.
-        *
-        * @abstract
-        * @param string $identifier
-        * @return boolean
-        */
-       abstract public function fileExists($identifier);
-
-       /**
-        * Checks if a file inside a storage folder exists.
-        *
-        * @abstract
-        * @param string $fileName
-        * @param Folder $folder
-        * @return boolean
-        */
-       abstract public function fileExistsInFolder($fileName, Folder $folder);
-
-       /**
-        * Returns a (local copy of) a file for processing it. When changing the
-        * file, you have to take care of replacing the current version yourself!
-        *
-        * @abstract
-        * @param FileInterface $file
-        * @param bool $writable Set this to FALSE if you only need the file for read operations. This might speed up things, e.g. by using a cached local version. Never modify the file if you have set this flag!
-        * @return string The path to the file on the local disk
-        */
-       // TODO decide if this should return a file handle object
-       abstract public function getFileForLocalProcessing(FileInterface $file, $writable = TRUE);
-
-       /**
-        * Returns the permissions of a file as an array (keys r, w) of boolean flags
-        *
-        * @abstract
-        * @param FileInterface $file
-        * @return array
-        */
-       abstract public function getFilePermissions(FileInterface $file);
-
-       /**
-        * Returns the permissions of a folder as an array (keys r, w) of boolean flags
-        *
-        * @abstract
-        * @param Folder $folder
-        * @return array
-        */
-       abstract public function getFolderPermissions(Folder $folder);
-
-       /**
-        * Renames a file
-        *
-        * @abstract
-        * @param FileInterface $file
-        * @param string $newName
-        * @return string The new identifier of the file if the operation succeeds
-        * @throws \RuntimeException if renaming the file failed
-        */
-       abstract public function renameFile(FileInterface $file, $newName);
-
-       /**
-        * Replaces the contents (and file-specific metadata) of a file object with a local file.
-        *
-        * @abstract
-        * @param \TYPO3\CMS\Core\Resource\AbstractFile $file
-        * @param string $localFilePath
-        * @return boolean
-        */
-       abstract public function replaceFile(\TYPO3\CMS\Core\Resource\AbstractFile $file, $localFilePath);
-
-       /**
-        * Returns information about a file for a given file identifier.
-        *
-        * @param string $identifier The (relative) path to the file.
-        * @param array $propertiesToExtract Array of properties which should be extracted, if empty all will be extracted
-        * @return array
-        */
-       abstract public function getFileInfoByIdentifier($identifier, array $propertiesToExtract = array());
-
-       /**
         * Basic implementation of the method that does directly return the
         * file name as is.
         *
@@ -409,341 +168,6 @@ abstract class AbstractDriver {
        }
 
        /**
-        * Returns information about a file for a given file object.
-        *
-        * @param FileInterface $file
-        * @param array $propertiesToExtract Array of properties which should be extracted, if empty all will be extracted
-        * @return array
-        */
-       public function getFileInfo(FileInterface $file, array $propertiesToExtract = array()) {
-               return $this->getFileInfoByIdentifier($file->getIdentifier(), $propertiesToExtract);
-       }
-
-       /**
-        * Returns a file object by its identifier.
-        *
-        * @param string $identifier
-        * @throws \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
-        * @return FileInterface
-        */
-       public function getFile($identifier) {
-               $fileObject = NULL;
-               if (!$this->fileExists($identifier)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException();
-               }
-               $fileInfo = $this->getFileInfoByIdentifier($identifier);
-               $fileObject = $this->getFileObject($fileInfo);
-               return $fileObject;
-       }
-
-       /**
-        * Creates a file object from a given file data array
-        *
-        * @param array $fileData
-        * @return \TYPO3\CMS\Core\Resource\File
-        */
-       protected function getFileObject(array $fileData) {
-               $fileObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->createFileObject($fileData, $this->storage);
-               return $fileObject;
-       }
-
-       /**
-        * Returns a folder by its identifier.
-        *
-        * @param string $identifier
-        * @return Folder
-        */
-       public function getFolder($identifier) {
-               $name = $this->getNameFromIdentifier($identifier);
-               return \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->createFolderObject($this->storage, $identifier, $name);
-       }
-
-       /**
-        * Returns a folder within the given folder. Use this method instead of doing your own string manipulation magic
-        * on the identifiers because non-hierarchical storages might fail otherwise.
-        *
-        * @param $name
-        * @param Folder $parentFolder
-        * @return Folder
-        */
-       abstract public function getFolderInFolder($name, Folder $parentFolder);
-
-       /**
-        * Applies a set of filter methods to a file name to find out if it should be used or not. This is e.g. used by
-        * directory listings.
-        *
-        * @param array $filterMethods The filter methods to use
-        * @param string $itemName
-        * @param string $itemIdentifier
-        * @param string $parentIdentifier
-        * @param array $additionalInformation Additional information about the inspected item
-        * @throws \RuntimeException
-        * @return boolean
-        */
-       protected function applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation = array()) {
-               foreach ($filterMethods as $filter) {
-                       if (is_array($filter)) {
-                               $result = call_user_func($filter, $itemName, $itemIdentifier, $parentIdentifier, $additionalInformation, $this);
-                               // We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
-                               // If calling the method succeeded and thus we can't use that as a return value.
-                               if ($result === -1) {
-                                       return FALSE;
-                               } elseif ($result === FALSE) {
-                                       throw new \RuntimeException('Could not apply file/folder name filter ' . $filter[0] . '::' . $filter[1]);
-                               }
-                       }
-               }
-               return TRUE;
-       }
-
-       /**
-        * Returns a list of files inside the specified path
-        *
-        * @param string $path
-        * @param integer $start The position to start the listing; if not set, start from the beginning
-        * @param integer $numberOfItems The number of items to list; if not set, return all items
-        * @param array $filenameFilterCallbacks The method callbacks to use for filtering the items
-        * @param array $fileData Two-dimensional, identifier-indexed array of file index records from the database
-        * @param boolean $recursive
-        * @deprecated since TYPO3 CMS 6.2 LTS, will be removed 2 versions Later
-        * @return array
-        */
-       public function getFileList($path, $start = 0, $numberOfItems = 0, array $filenameFilterCallbacks = array(), $fileData = array(), $recursive = FALSE) {
-               \TYPO3\CMS\Core\Utility\GeneralUtility::logDeprecatedFunction();
-               return $this->getDirectoryItemList($path, $start, $numberOfItems, $filenameFilterCallbacks, $this->fileListCallbackMethod, $fileData, $recursive);
-       }
-
-       /**
-        * Returns a list of files inside the specified path
-        *
-        * @param string $folderIdentifier
-        * @param boolean $recursive
-        * @param array $filenameFilterCallbacks The method callbacks to use for filtering the items
-        * @return array of FileIdentifiers
-        */
-       abstract public function getFileIdentifierListInFolder($folderIdentifier, $recursive = FALSE, array $filenameFilterCallbacks = array());
-
-
-       /**
-        * Copies a file to a temporary path and returns that path.
-        *
-        * @abstract
-        * @param FileInterface $file
-        * @return string The temporary path
-        */
-       abstract public function copyFileToTemporaryPath(FileInterface $file);
-
-       /**
-        * Moves a file *within* the current storage.
-        * Note that this is only about an intra-storage move action, where a file is just
-        * moved to another folder in the same storage.
-        *
-        * @param FileInterface $file
-        * @param Folder $targetFolder
-        * @param string $fileName
-        * @return string The new identifier of the file
-        */
-       abstract public function moveFileWithinStorage(FileInterface $file, Folder $targetFolder, $fileName);
-
-       /**
-        * Copies a file *within* the current storage.
-        * Note that this is only about an intra-storage copy action, where a file is just
-        * copied to another folder in the same storage.
-        *
-        * @param FileInterface $file
-        * @param Folder $targetFolder
-        * @param string $fileName
-        * @return FileInterface The new (copied) file object.
-        */
-       abstract public function copyFileWithinStorage(FileInterface $file, Folder $targetFolder, $fileName);
-
-       /**
-        * Folder equivalent to moveFileWithinStorage().
-        *
-        * @param Folder $folderToMove
-        * @param Folder $targetFolder
-        * @param string $newFolderName
-        * @return array A map of old to new file identifiers
-        */
-       abstract public function moveFolderWithinStorage(Folder $folderToMove, Folder $targetFolder, $newFolderName);
-
-       /**
-        * Folder equivalent to copyFileWithinStorage().
-        *
-        * @param Folder $folderToCopy
-        * @param Folder $targetFolder
-        * @param string $newFileName
-        * @return boolean
-        */
-       abstract public function copyFolderWithinStorage(Folder $folderToCopy, Folder $targetFolder, $newFileName);
-
-       /**
-        * Move a folder from another storage.
-        *
-        * @param Folder $folderToMove
-        * @param Folder $targetParentFolder
-        * @param string $newFolderName
-        * @throws \BadMethodCallException
-        * @return boolean
-        */
-       public function moveFolderBetweenStorages(Folder $folderToMove, Folder $targetParentFolder, $newFolderName) {
-               // This is not implemented for now as moving files between storages might cause quite some headaches when
-               // something goes wrong. It is also not that common of a use case, so it does not hurt that much to leave it out
-               // for now.
-               throw new \BadMethodCallException('Moving folders between storages is not implemented.');
-       }
-
-       /**
-        * Copy a folder from another storage.
-        *
-        * @param Folder $folderToCopy
-        * @param Folder $targetParentFolder
-        * @param string $newFolderName
-        * @throws \BadMethodCallException
-        * @return boolean
-        */
-       public function copyFolderBetweenStorages(Folder $folderToCopy, Folder $targetParentFolder, $newFolderName) {
-               throw new \BadMethodCallException('Not yet implemented!', 1330262731);
-       }
-
-       /**
-        * Removes a file from this storage. This does not check if the file is
-        * still used or if it is a bad idea to delete it for some other reason
-        * this has to be taken care of in the upper layers (e.g. the Storage)!
-        *
-        * @abstract
-        * @param FileInterface $file
-        * @return boolean TRUE if deleting the file succeeded
-        */
-       abstract public function deleteFile(FileInterface $file);
-
-       /**
-        * Removes a folder from this storage.
-        *
-        * @param Folder $folder
-        * @param boolean $deleteRecursively
-        * @return boolean
-        */
-       abstract public function deleteFolder(Folder $folder, $deleteRecursively = FALSE);
-
-       /**
-        * Adds a file at the specified location. This should only be used internally.
-        *
-        * @abstract
-        * @param string $localFilePath
-        * @param Folder $targetFolder
-        * @param string $targetFileName
-        * @return string The new identifier of the file
-        */
-       // TODO check if this is still necessary if we move more logic to the storage
-       abstract public function addFileRaw($localFilePath, Folder $targetFolder, $targetFileName);
-
-       /**
-        * Deletes a file without access and usage checks.
-        * This should only be used internally.
-        *
-        * This accepts an identifier instead of an object because we might want to
-        * delete files that have no object associated with (or we don't want to
-        * create an object for) them - e.g. when moving a file to another storage.
-        *
-        * @abstract
-        * @param string $identifier
-        * @return boolean TRUE if removing the file succeeded
-        */
-       abstract public function deleteFileRaw($identifier);
-
-       /*******************
-        * FOLDER FUNCTIONS
-        *******************/
-       /**
-        * Returns the root level folder of the storage.
-        *
-        * @abstract
-        * @return Folder
-        */
-       abstract public function getRootLevelFolder();
-
-       /**
-        * Returns the default folder new files should be put into.
-        *
-        * @abstract
-        * @return Folder
-        */
-       abstract public function getDefaultFolder();
-
-       /**
-        * Creates a folder.
-        *
-        * @param string $newFolderName
-        * @param Folder $parentFolder
-        * @return Folder The new (created) folder object
-        */
-       abstract public function createFolder($newFolderName, Folder $parentFolder);
-
-       /**
-        * Returns a list of all folders in a given path
-        *
-        * @param string $path
-        * @param integer $start The position to start the listing; if not set, start from the beginning
-        * @param integer $numberOfItems The number of items to list; if not set, return all items
-        * @param array $foldernameFilterCallbacks The method callbacks to use for filtering the items
-        * @param boolean $recursive
-        * @return array
-        */
-       public function getFolderList($path, $start = 0, $numberOfItems = 0, array $foldernameFilterCallbacks = array(), $recursive = FALSE) {
-               return $this->getDirectoryItemList($path, $start, $numberOfItems, $foldernameFilterCallbacks, $this->folderListCallbackMethod, $recursive);
-       }
-
-       /**
-        * Checks if a folder exists
-        *
-        * @abstract
-        * @param string $identifier
-        * @return boolean
-        */
-       abstract public function folderExists($identifier);
-
-       /**
-        * Checks if a file inside a storage folder exists.
-        *
-        * @abstract
-        * @param string $folderName
-        * @param Folder $folder
-        * @return boolean
-        */
-       abstract public function folderExistsInFolder($folderName, Folder $folder);
-
-       /**
-        * Renames a folder in this storage.
-        *
-        * @param Folder $folder
-        * @param string $newName The target path (including the file name!)
-        * @return array A map of old to new file identifiers
-        * @throws \RuntimeException if renaming the folder failed
-        */
-       abstract public function renameFolder(Folder $folder, $newName);
-
-       /**
-        * Checks if a given object or identifier is within a container, e.g. if
-        * a file or folder is within another folder.
-        * This can e.g. be used to check for webmounts.
-        *
-        * @abstract
-        * @param Folder $container
-        * @param mixed $content An object or an identifier to check
-        * @return boolean TRUE if $content is within $container
-        */
-       abstract public function isWithin(Folder $container, $content);
-
-       /**
-        * Checks if a folder contains files and (if supported) other folders.
-        *
-        * @param Folder $folder
-        * @return boolean TRUE if there are no files and folders within $folder
-        */
-       abstract public function isFolderEmpty(Folder $folder);
-
-       /**
         * Returns TRUE if this driver uses case-sensitive identifiers. NOTE: This
         * is a configurable setting, but the setting does not change the way the
         * underlying file system treats the identifiers; the setting should
@@ -784,12 +208,4 @@ abstract class AbstractDriver {
         */
        abstract protected function canonicalizeAndCheckFolderIdentifier($folderIdentifier);
 
-       /**
-        * Returns the identifier of the folder the file resides in
-        *
-        * @param $fileIdentifier
-        *
-        * @return mixed
-        */
-       abstract public function getFolderIdentifierForFile($fileIdentifier);
 }
\ No newline at end of file
index a6e329b..0b65df1 100644 (file)
@@ -69,10 +69,12 @@ abstract class AbstractHierarchicalFilesystemDriver extends AbstractDriver {
         * @return string
         */
        protected function canonicalizeAndCheckFileIdentifier($fileIdentifier) {
-               $fileIdentifier = $this->canonicalizeAndCheckFilePath($fileIdentifier);
-               $fileIdentifier = '/' . ltrim($fileIdentifier, '/');
-               if (!$this->isCaseSensitiveFileSystem()) {
-                       $fileIdentifier = strtolower($fileIdentifier);
+               if ($fileIdentifier !== '') {
+                       $fileIdentifier = $this->canonicalizeAndCheckFilePath($fileIdentifier);
+                       $fileIdentifier = '/' . ltrim($fileIdentifier, '/');
+                       if (!$this->isCaseSensitiveFileSystem()) {
+                               $fileIdentifier = strtolower($fileIdentifier);
+                       }
                }
                return $fileIdentifier;
        }
@@ -93,7 +95,7 @@ abstract class AbstractHierarchicalFilesystemDriver extends AbstractDriver {
         * @param string $fileIdentifier
         * @return mixed
         */
-       public function getFolderIdentifierForFile($fileIdentifier) {
+       public function getParentFolderIdentifierOfIdentifier($fileIdentifier) {
                $fileIdentifier = $this->canonicalizeAndCheckFileIdentifier($fileIdentifier);
                return \TYPO3\CMS\Core\Utility\PathUtility::dirname($fileIdentifier) . '/';
        }
diff --git a/typo3/sysext/core/Classes/Resource/Driver/DriverInterface.php b/typo3/sysext/core/Classes/Resource/Driver/DriverInterface.php
new file mode 100644 (file)
index 0000000..fbebf65
--- /dev/null
@@ -0,0 +1,423 @@
+<?php
+namespace TYPO3\CMS\Core\Resource\Driver;
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Steffen Ritter <steffen.ritter@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ * A copy is found in the text file GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+
+/**
+ * An interface Drivers have to implement to fulfil the needs
+ * of the FAL API.
+ */
+interface DriverInterface {
+
+       /**
+        * Processes the configuration for this driver.
+        * @return void
+        */
+       public function processConfiguration();
+
+       /**
+        * Sets the storage uid the driver belongs to
+        *
+        * @param integer $storageUid
+        * @return void
+        */
+       public function setStorageUid($storageUid);
+
+       /**
+        * Initializes this object. This is called by the storage after the driver
+        * has been attached.
+        *
+        * @return void
+        */
+       public function initialize();
+
+       /**
+        * Returns the capabilities of this driver.
+        *
+        * @return integer
+        * @see Storage::CAPABILITY_* constants
+        */
+       public function getCapabilities();
+
+       /**
+        * Returns TRUE if this driver has the given capability.
+        *
+        * @param integer $capability A capability, as defined in a CAPABILITY_* constant
+        * @return boolean
+        */
+       public function hasCapability($capability);
+
+       /**
+        * Returns TRUE if this driver uses case-sensitive identifiers. NOTE: This
+        * is a configurable setting, but the setting does not change the way the
+        * underlying file system treats the identifiers; the setting should
+        * therefore always reflect the file system and not try to change its
+        * behaviour
+        *
+        * @return boolean
+        */
+       public function isCaseSensitiveFileSystem();
+
+       /**
+        * Cleans a fileName from not allowed characters
+        *
+        * @param string $fileName
+        * @param string $charset Charset of the a fileName
+        *                        (defaults to current charset; depending on context)
+        * @return string the cleaned filename
+        */
+       public function sanitizeFileName($fileName, $charset = '');
+
+       /**
+        * Hashes a file identifier, taking the case sensitivity of the file system
+        * into account. This helps mitigating problems with case-insensitive
+        * databases.
+        *
+        * @param string $identifier
+        * @return string
+        */
+       public function hashIdentifier($identifier);
+
+       /**
+        * Returns the identifier of the root level folder of the storage.
+        *
+        * @return string
+        */
+       public function getRootLevelFolder();
+
+       /**
+        * Returns the identifier of the default folder new files should be put into.
+        *
+        * @return string
+        */
+       public function getDefaultFolder();
+
+       /**
+        * Returns the identifier of the folder the file resides in
+        *
+        * @param string $fileIdentifier
+        *
+        * @return string
+        */
+       public function getParentFolderIdentifierOfIdentifier($fileIdentifier);
+
+       /**
+        * Returns the public URL to a file.
+        *
+        * @param string $identifier
+        * @param boolean $relativeToCurrentScript Determines whether the URL
+        *                                         returned should be relative
+        *                                         to the current script, in case
+        *                                         it is relative at all (only
+        *                                         for the LocalDriver)
+        * @return string
+        */
+       public function getPublicUrl($identifier, $relativeToCurrentScript = FALSE);
+
+       /**
+        * Creates a folder, within a parent folder.
+        * If no parent folder is given, a root level folder will be created
+        *
+        * @param string $newFolderName
+        * @param string $parentFolderIdentifier
+        * @param boolean $recursive
+        * @return string the Identifier of the new folder
+        */
+       public function createFolder($newFolderName, $parentFolderIdentifier = '', $recursive = FALSE);
+
+       /**
+        * Renames a folder in this storage.
+        *
+        * @param string $folderIdentifier
+        * @param string $newName
+        * @return array A map of old to new file identifiers of all affected resources
+        */
+       public function renameFolder($folderIdentifier, $newName);
+
+       /**
+        * Removes a folder in filesystem.
+        *
+        * @param string $folderIdentifier
+        * @param boolean $deleteRecursively
+        * @return boolean
+        */
+       public function deleteFolder($folderIdentifier, $deleteRecursively = FALSE);
+
+       /**
+        * Checks if a file exists.
+        *
+        * @param string $fileIdentifier
+        *
+        * @return boolean
+        */
+       public function fileExists($fileIdentifier);
+
+       /**
+        * Checks if a folder exists.
+        *
+        * @param string $folderIdentifier
+        *
+        * @return boolean
+        */
+       public function folderExists($folderIdentifier);
+
+       /**
+        * Checks if a folder contains files and (if supported) other folders.
+        *
+        * @param string $folderIdentifier
+        * @return boolean TRUE if there are no files and folders within $folder
+        */
+       public function isFolderEmpty($folderIdentifier);
+
+       /**
+        * Adds a file from the local server hard disk to a given path in TYPO3s
+        * virtual file system. This assumes that the local file exists, so no
+        * further check is done here! After a successful the original file must
+        * not exist anymore.
+        *
+        * @param string $localFilePath (within PATH_site)
+        * @param string $targetFolderIdentifier
+        * @param string $newFileName optional, if not given original name is used
+        * @param boolean $removeOriginal if set the original file will be removed
+        *                                after successful operation
+        * @return string the identifier of the new file
+        */
+       public function addFile($localFilePath, $targetFolderIdentifier, $newFileName = '', $removeOriginal = TRUE);
+
+       /**
+        * Creates a new (empty) file and returns the identifier.
+        *
+        * @param string $fileName
+        * @param string $parentFolderIdentifier
+        * @return string
+        */
+       public function createFile($fileName, $parentFolderIdentifier);
+
+       /**
+        * Copies a file *within* the current storage.
+        * Note that this is only about an inner storage copy action,
+        * where a file is just copied to another folder in the same storage.
+        *
+        * @param string $fileIdentifier
+        * @param string $targetFolderIdentifier
+        * @param string $fileName
+        * @return string the Identifier of the new file
+        */
+       public function copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName);
+
+       /**
+        * Renames a file in this storage.
+        *
+        * @param string $fileIdentifier
+        * @param string $newName The target path (including the file name!)
+        * @return string The identifier of the file after renaming
+        */
+       public function renameFile($fileIdentifier, $newName);
+
+       /**
+        * Replaces a file with file in local file system.
+        *
+        * @param string $fileIdentifier
+        * @param string $localFilePath
+        * @return boolean TRUE if the operation succeeded
+        */
+       public function replaceFile($fileIdentifier, $localFilePath);
+
+       /**
+        * Removes a file from the filesystem. This does not check if the file is
+        * still used or if it is a bad idea to delete it for some other reason
+        * this has to be taken care of in the upper layers (e.g. the Storage)!
+        *
+        * @param string $fileIdentifier
+        * @return boolean TRUE if deleting the file succeeded
+        */
+       public function deleteFile($fileIdentifier);
+
+       /**
+        * Creates a hash for a file.
+        *
+        * @param string $fileIdentifier
+        * @param string $hashAlgorithm The hash algorithm to use
+        * @return string
+        */
+       public function hash($fileIdentifier, $hashAlgorithm);
+
+
+       /**
+        * Moves a file *within* the current storage.
+        * Note that this is only about an inner-storage move action,
+        * where a file is just moved to another folder in the same storage.
+        *
+        * @param string $fileIdentifier
+        * @param string $targetFolderIdentifier
+        * @param string $newFileName
+        *
+        * @return string
+        */
+       public function moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName);
+
+
+       /**
+        * Folder equivalent to moveFileWithinStorage().
+        *
+        * @param string $sourceFolderIdentifier
+        * @param string $targetFolderIdentifier
+        * @param string $newFolderName
+        *
+        * @return array All files which are affected, map of old => new file identifiers
+        */
+       public function moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName);
+
+       /**
+        * Folder equivalent to copyFileWithinStorage().
+        *
+        * @param string $sourceFolderIdentifier
+        * @param string $targetFolderIdentifier
+        * @param string $newFolderName
+        *
+        * @return boolean
+        */
+       public function copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName);
+
+       /**
+        * Returns the contents of a file. Beware that this requires to load the
+        * complete file into memory and also may require fetching the file from an
+        * external location. So this might be an expensive operation (both in terms
+        * of processing resources and money) for large files.
+        *
+        * @param string $fileIdentifier
+        * @return string The file contents
+        */
+       public function getFileContents($fileIdentifier);
+
+       /**
+        * Sets the contents of a file to the specified value.
+        *
+        * @param string $fileIdentifier
+        * @param string $contents
+        * @return integer The number of bytes written to the file
+        */
+       public function setFileContents($fileIdentifier, $contents);
+
+       /**
+        * Checks if a file inside a folder exists
+        *
+        * @param string $fileName
+        * @param string $folderIdentifier
+        * @return boolean
+        */
+       public function fileExistsInFolder($fileName, $folderIdentifier);
+
+       /**
+        * Checks if a folder inside a folder exists.
+        *
+        * @param string $folderName
+        * @param string $folderIdentifier
+        * @return boolean
+        */
+       public function folderExistsInFolder($folderName, $folderIdentifier);
+
+       /**
+        * Returns a path to a local copy of a file for processing it. When changing the
+        * file, you have to take care of replacing the current version yourself!
+        *
+        * @param string $fileIdentifier
+        * @param bool $writable Set this to FALSE if you only need the file for read
+        *                       operations. This might speed up things, e.g. by using
+        *                       a cached local version. Never modify the file if you
+        *                       have set this flag!
+        * @return string The path to the file on the local disk
+        */
+       public function getFileForLocalProcessing($fileIdentifier, $writable = TRUE);
+
+       /**
+        * Returns the permissions of a file/folder as an array
+        * (keys r, w) of boolean flags
+        *
+        * @param string $identifier
+        * @return array
+        */
+       public function getPermissions($identifier);
+
+       /**
+        * Checks if a given identifier is within a container, e.g. if
+        * a file or folder is within another folder.
+        * This can e.g. be used to check for web-mounts.
+        *
+        * @param string $folderIdentifier
+        * @param string $identifier identifier to be checked against $folderIdentifier
+        *
+        * @return boolean TRUE if $content is within $folderIdentifier
+        */
+       public function isWithin($folderIdentifier, $identifier);
+
+       /**
+        * Returns information about a file.
+        *
+        * @param string $fileIdentifier
+        * @param array $propertiesToExtract Array of properties which are be extracted
+        *                                   If empty all will be extracted
+        * @return array
+        */
+       public function getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract = array());
+
+       /**
+        * Returns information about a file.
+        *
+        * @param string $folderIdentifier
+        * @return array
+        */
+       public function getFolderInfoByIdentifier($folderIdentifier);
+
+       /**
+        * Returns a list of files inside the specified path
+        *
+        * @param string $folderIdentifier
+        * @param integer $start
+        * @param integer $numberOfItems
+        * @param boolean $recursive
+        * @param array $filenameFilterCallbacks callbacks for filtering the items
+        *
+        * @return array of FileIdentifiers
+        */
+       public function getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $filenameFilterCallbacks = array());
+
+       /**
+        * Returns a list of folders inside the specified path
+        *
+        * @param string $folderIdentifier
+        * @param integer $start
+        * @param integer $numberOfItems
+        * @param boolean $recursive
+        * @param array $folderNameFilterCallbacks callbacks for filtering the items
+        *
+        * @return array of Folder Identifier
+        */
+       public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $folderNameFilterCallbacks = array());
+
+}
\ No newline at end of file
index e3b6c77..b029a71 100644 (file)
@@ -62,12 +62,17 @@ class DriverRegistry implements \TYPO3\CMS\Core\SingletonInterface {
         * @param string $label
         * @param string $flexFormDataStructurePathAndFilename
         * @return boolean TRUE if registering succeeded
+        * @throws \InvalidArgumentException
         */
        public function registerDriverClass($className, $shortName = NULL, $label = NULL, $flexFormDataStructurePathAndFilename = NULL) {
                // check if the class is available for TYPO3 before registering the driver
                if (!class_exists($className)) {
                        throw new \InvalidArgumentException('Class ' . $className . ' does not exist.', 1314979197);
                }
+
+               if (!in_array('TYPO3\CMS\Core\Resource\Driver\DriverInterface', class_implements($className), TRUE)) {
+                       throw new \InvalidArgumentException('Driver ' . $className . ' needs to implement the DriverInterface.', 1387619575);
+               }
                if ($shortName === '') {
                        $shortName = $className;
                }
@@ -113,6 +118,7 @@ class DriverRegistry implements \TYPO3\CMS\Core\SingletonInterface {
         *
         * @param string $shortName
         * @return string The class name
+        * @throws \InvalidArgumentException
         */
        public function getDriverClass($shortName) {
                if (in_array($shortName, $this->drivers) && class_exists($shortName)) {
index eff1ebc..f0bf41b 100644 (file)
@@ -6,6 +6,7 @@ namespace TYPO3\CMS\Core\Resource\Driver;
  *
  * (c) 2011-2013 Andreas Wolf <andreas.wolf@ikt-werk.de>
  * (c) 2013 Stefan Neufeind <info (at) speedpartner.de>
+ * (c) 2013 Steffen Ritter <steffen.ritter@typo3.org>
  * All rights reserved
  *
  * This script is part of the TYPO3 project. The TYPO3 project is
@@ -28,8 +29,6 @@ namespace TYPO3\CMS\Core\Resource\Driver;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-use TYPO3\CMS\Core\Resource\FileInterface;
-use TYPO3\CMS\Core\Resource\Folder;
 use TYPO3\CMS\Core\Resource\FolderInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\PathUtility;
@@ -37,7 +36,6 @@ use TYPO3\CMS\Core\Utility\PathUtility;
 /**
  * Driver for the local file system
  *
- * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
  */
 class LocalDriver extends AbstractHierarchicalFilesystemDriver {
 
@@ -76,17 +74,6 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        );
 
        /**
-        * Checks if a configuration is valid for this storage.
-        *
-        * @param array $configuration The configuration
-        * @return void
-        * @throws \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException
-        */
-       static public function verifyConfiguration(array $configuration) {
-               static::calculateBasePath($configuration);
-       }
-
-       /**
         * Processes the configuration for this driver.
         *
         * @return void
@@ -118,12 +105,9 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        protected function determineBaseUrl() {
                if (GeneralUtility::isFirstPartOfStr($this->absoluteBasePath, PATH_site)) {
                        // use site-relative URLs
-                       // TODO add unit test
                        $this->baseUri = \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($this->absoluteBasePath);
                } elseif (isset($this->configuration['baseUri']) && GeneralUtility::isValidUrl($this->configuration['baseUri'])) {
                        $this->baseUri = rtrim($this->configuration['baseUri'], '/') . '/';
-               } else {
-
                }
        }
 
@@ -136,7 +120,10 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         */
        protected function calculateBasePath(array $configuration) {
                if (!array_key_exists('basePath', $configuration) || empty($configuration['basePath'])) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException('Configuration must contain base path.', 1346510477);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(
+                               'Configuration must contain base path.',
+                               1346510477
+                       );
                }
 
                if ($configuration['pathType'] === 'relative') {
@@ -147,7 +134,10 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                }
                $absoluteBasePath = rtrim($absoluteBasePath, '/') . '/';
                if (!is_dir($absoluteBasePath)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException('Base path "' . $absoluteBasePath . '" does not exist or is no directory.', 1299233097);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(
+                               'Base path "' . $absoluteBasePath . '" does not exist or is no directory.',
+                               1299233097
+                       );
                }
                return $absoluteBasePath;
        }
@@ -156,66 +146,77 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * Returns the public URL to a file. For the local driver, this will always
         * return a path relative to PATH_site.
         *
-        * @param \TYPO3\CMS\Core\Resource\ResourceInterface $fileOrFolder
-        * @param boolean $relativeToCurrentScript Determines whether the URL returned should be relative to the current script, in case it is relative at all (only for the LocalDriver)
+        * @param string $identifier
+        * @param boolean $relativeToCurrentScript Determines whether the URL returned should be relative to the current script,
+        *                                         in case it is relative at all (only for the LocalDriver)
+        *
         * @return string
         * @throws \TYPO3\CMS\Core\Resource\Exception
         */
-       public function getPublicUrl(\TYPO3\CMS\Core\Resource\ResourceInterface $fileOrFolder, $relativeToCurrentScript = FALSE) {
+       public function getPublicUrl($identifier, $relativeToCurrentScript = FALSE) {
                if ($this->configuration['pathType'] === 'relative' && rtrim($this->configuration['basePath'], '/') !== '') {
-                       $publicUrl = rtrim($this->configuration['basePath'], '/') . '/' . ltrim($fileOrFolder->getIdentifier(), '/');
+                       $publicUrl = rtrim($this->configuration['basePath'], '/') . '/' . ltrim($identifier, '/');
                } elseif (isset($this->baseUri)) {
-                       $publicUrl = $this->baseUri . ltrim($fileOrFolder->getIdentifier(), '/');
+                       $publicUrl = $this->baseUri . ltrim($identifier, '/');
                } else {
                        throw new \TYPO3\CMS\Core\Resource\Exception('Public URL of file cannot be determined', 1329765518);
                }
                // If requested, make the path relative to the current script in order to make it possible
                // to use the relative file
                if ($relativeToCurrentScript) {
-                       $publicUrl = PathUtility::getRelativePathTo(PathUtility::dirname((PATH_site . $publicUrl))) . PathUtility::basename($publicUrl);
+                       $publicUrl = PathUtility::getRelativePathTo(PathUtility::dirname((PATH_site . $publicUrl))) .
+                               PathUtility::basename($publicUrl);
                }
                return $publicUrl;
        }
 
        /**
-        * Returns the root level folder of the storage.
+        * Returns the Identifier of the root level folder of the storage.
         *
-        * @return Folder
+        * @return string
         */
        public function getRootLevelFolder() {
-               if (!$this->rootLevelFolder) {
-                       $this->rootLevelFolder = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->createFolderObject($this->storage, '/', '');
-               }
-               return $this->rootLevelFolder;
+               return '/';
        }
 
        /**
-        * Returns the default folder new files should be put into.
+        * Returns identifier of the default folder new files should be put into.
         *
-        * @return Folder
+        * @return string
         */
        public function getDefaultFolder() {
-               if (!$this->defaultLevelFolder) {
-                       if (!file_exists(($this->absoluteBasePath . 'user_upload/'))) {
-                               mkdir($this->absoluteBasePath . 'user_upload/');
-                       }
-                       $this->defaultLevelFolder = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->createFolderObject($this->storage, '/user_upload/', '');
+               $identifier = '/user_upload/';
+               $createFolder = !$this->folderExists($identifier);
+               if ($createFolder === TRUE) {
+                       $identifier = $this->createFolder('user_upload');
                }
-               return $this->defaultLevelFolder;
+               return $identifier;
        }
 
        /**
-        * Creates a folder.
+        * Creates a folder, within a parent folder.
+        * If no parent folder is given, a rootlevel folder will be created
         *
         * @param string $newFolderName
-        * @param Folder $parentFolder
-        * @return Folder The new (created) folder object
+        * @param string $parentFolderIdentifier
+        * @param boolean $recursive
+        * @return string the Identifier of the new folder
         */
-       public function createFolder($newFolderName, Folder $parentFolder) {
-               $newFolderName = trim($this->sanitizeFileName($newFolderName), '/');
-               $newFolderPath = $this->canonicalizeAndCheckFolderIdentifier($parentFolder->getIdentifier() . '/' . $newFolderName);
-               GeneralUtility::mkdir($this->getAbsoluteBasePath() . $newFolderPath);
-               return \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->createFolderObject($this->storage, $newFolderPath, $newFolderName);
+       public function createFolder($newFolderName, $parentFolderIdentifier = '', $recursive = FALSE) {
+               $parentFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
+               $newFolderName = trim($newFolderName, '/');
+               if ($recursive == FALSE) {
+                       $newFolderName = $this->sanitizeFileName($newFolderName);
+                       $newIdentifier = $parentFolderIdentifier . $newFolderName . '/';
+                       GeneralUtility::mkdir($this->getAbsoluteBasePath() . $newIdentifier);
+               } else {
+                       $parts = GeneralUtility::trimExplode('/', $newFolderName);
+                       array_map(array($this, 'sanitizeFileName'), $parts);
+                       $newFolderName = implode('/', $parts);
+                       $newIdentifier = $parentFolderIdentifier . $newFolderName . '/';
+                       GeneralUtility::mkdir_deep($this->getAbsoluteBasePath() . $parentFolderIdentifier, $newFolderName);
+               }
+               return $newIdentifier;
        }
 
        /**
@@ -239,6 +240,28 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                return $this->extractFileInformation($absoluteFilePath, $dirPath, $propertiesToExtract);
        }
 
+       /**
+        * Returns information about a folder.
+        *
+        * @param string $folderIdentifier In the case of the LocalDriver, this is the (relative) path to the file.
+        * @return array
+        * @throws \TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException
+        */
+       public function getFolderInfoByIdentifier($folderIdentifier) {
+               $folderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($folderIdentifier);
+
+               if (!$this->folderExists($folderIdentifier)) {
+                       throw new \TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException(
+                               'File ' . $folderIdentifier . ' does not exist.',
+                               1314516809
+                       );
+               }
+               return array(
+                       'identifier' => $folderIdentifier,
+                       'name' => PathUtility::basename($folderIdentifier),
+                       'storage' => $this->storageUid
+               );
+       }
 
        /**
         * Returns a string where any character not matching [.a-zA-Z0-9_-] is
@@ -277,31 +300,36 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                // Strip trailing dots and return
                $cleanFileName = preg_replace('/\\.*$/', '', $cleanFileName);
                if (!$cleanFileName) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException('File name ' . $cleanFileName . ' is invalid.', 1320288991);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(
+                               'File name ' . $cleanFileName . ' is invalid.',
+                               1320288991
+                       );
                }
                return $cleanFileName;
        }
 
        /**
-        * Generic wrapper for extracting a list of items from a path. The
-        * extraction itself is done by the given handler method
+        * Generic wrapper for extracting a list of items from a path.
         *
-        * @param string $basePath
+        * @param string $folderIdentifier
         * @param integer $start The position to start the listing; if not set, start from the beginning
         * @param integer $numberOfItems The number of items to list; if set to zero, all items are returned
         * @param array $filterMethods The filter methods used to filter the directory items
-        * @param string $itemHandlerMethod The method (in this class) that handles the single iterator elements.
-        * @param array $itemRows
+        * @param boolean $includeFiles
+        * @param boolean $includeDirs
         * @param boolean $recursive
+        *
         * @return array
         * @throws \InvalidArgumentException
         */
-       protected function getDirectoryItemList($basePath, $start, $numberOfItems, array $filterMethods, $itemHandlerMethod, $itemRows = array(), $recursive = FALSE) {
-               // TODO add unit tests
-               $basePath = $this->canonicalizeAndCheckFolderIdentifier($basePath);
-               $realPath = rtrim($this->absoluteBasePath . trim($basePath, '/'), '/') . '/';
+       protected function getDirectoryItemList($folderIdentifier, $start = 0, $numberOfItems = 0, array $filterMethods, $includeFiles = TRUE, $includeDirs = TRUE, $recursive = FALSE) {
+               $folderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($folderIdentifier);
+               $realPath = $this->getAbsolutePath($folderIdentifier);
                if (!is_dir($realPath)) {
-                       throw new \InvalidArgumentException('Cannot list items in directory ' . $basePath . ' - does not exist or is no directory', 1314349666);
+                       throw new \InvalidArgumentException(
+                               'Cannot list items in directory ' . $folderIdentifier . ' - does not exist or is no directory',
+                               1314349666
+                       );
                }
 
                if ($start > 0) {
@@ -311,61 +339,40 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                // Fetch the files and folders and sort them by name; we have to do
                // this here because the directory iterator does return them in
                // an arbitrary order
-               $items = $this->getFileAndFoldernamesInPath($realPath, $recursive);
+               $items = $this->retrieveFileAndFoldersInPath($realPath, $recursive, $includeFiles, $includeDirs);
                uksort(
                        $items,
                        array('\\TYPO3\\CMS\\Core\\Utility\\ResourceUtility', 'recursiveFileListSortingHelper')
                );
 
                $iterator = new \ArrayIterator($items);
-               if ($iterator->count() == 0) {
+               if ($iterator->count() === 0) {
                        return array();
                }
                $iterator->seek($start);
 
-               if ($basePath !== '' && $basePath !== '/') {
-                       $basePath = '/' . trim($basePath, '/') . '/';
-               }
-
                // $c is the counter for how many items we still have to fetch (-1 is unlimited)
-               $c = $numberOfItems > 0 ? $numberOfItems : -1;
+               $c = $numberOfItems > 0 ? $numberOfItems : - 1;
                $items = array();
-               while ($iterator->valid() && ($numberOfItems == 0 || $c > 0)) {
+               while ($iterator->valid() && ($numberOfItems === 0 || $c > 0)) {
                        // $iteratorItem is the file or folder name
                        $iteratorItem = $iterator->current();
-
                        // go on to the next iterator item now as we might skip this one early
                        $iterator->next();
-                       $identifier = $basePath . $iteratorItem['path'];
 
                        if (
                                !$this->applyFilterMethodsToDirectoryItem(
                                        $filterMethods,
                                        $iteratorItem['name'],
-                                       $identifier,
-                                       dirname($identifier) . '/',
-                                       isset($itemRows[$identifier]) ? array('indexData' => $itemRows[$identifier]) : array()
+                                       $iteratorItem['identifier'],
+                                       $this->getParentFolderIdentifierOfIdentifier($iteratorItem['identifier'])
                                )
                        ) {
                                continue;
                        }
 
-                       // dirname returns "/" when called with "/" as the argument, so strip trailing slashes here to be sure
-                       $path = rtrim(GeneralUtility::fixWindowsFilePath(dirname($identifier)), '/') . '/';
-                       if (isset($itemRows[$identifier])) {
-                               list($key, $item) = $this->{$itemHandlerMethod}($iteratorItem['name'], $path, $itemRows[$identifier]);
-                       } else {
-                               list($key, $item) = $this->{$itemHandlerMethod}($iteratorItem['name'], $path);
-                       }
-
-                       if (empty($item)) {
-                               continue;
-                       }
-                       if ($recursive) {
-                               $key = $iteratorItem['path'];
-                       }
 
-                       $items[$key] = $item;
+                       $items[$iteratorItem['identifier']] = $iteratorItem['identifier'];
                        // Decrement item counter to make sure we only return $numberOfItems
                        // we cannot do this earlier in the method (unlike moving the iterator forward) because we only add the
                        // item here
@@ -375,98 +382,81 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        }
 
        /**
+        * Applies a set of filter methods to a file name to find out if it should be used or not. This is e.g. used by
+        * directory listings.
+        *
+        * @param array $filterMethods The filter methods to use
+        * @param string $itemName
+        * @param string $itemIdentifier
+        * @param string $parentIdentifier
+        * @throws \RuntimeException
+        * @return boolean
+        */
+       protected function applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier) {
+               foreach ($filterMethods as $filter) {
+                       if (is_array($filter)) {
+                               $result = call_user_func($filter, $itemName, $itemIdentifier, $parentIdentifier, array(), $this);
+                               // We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
+                               // If calling the method succeeded and thus we can't use that as a return value.
+                               if ($result === -1) {
+                                       return FALSE;
+                               } elseif ($result === FALSE) {
+                                       throw new \RuntimeException('Could not apply file/folder name filter ' . $filter[0] . '::' . $filter[1]);
+                               }
+                       }
+               }
+               return TRUE;
+       }
+
+       /**
         * Returns a list of files inside the specified path
         *
         * @param string $folderIdentifier
+        * @param integer $start
+        * @param integer $numberOfItems
         * @param boolean $recursive
         * @param array $filenameFilterCallbacks The method callbacks to use for filtering the items
         *
         * @return array of FileIdentifiers
         */
-       public function getFileIdentifierListInFolder($folderIdentifier, $recursive = FALSE, array $filenameFilterCallbacks = array()) {
-               return array_values($this->getDirectoryItemList($folderIdentifier, 0, 0, $filenameFilterCallbacks, 'getFileList_itemCallbackIdentifierOnly', array(), $recursive));
-       }
-
-
-       /**
-        * Handler for items in a file list.
-        *
-        * @param string $fileName
-        * @param string $path
-        * @return array
-        */
-       protected function getFileList_itemCallbackIdentifierOnly($fileName, $path) {
-               $file = $path . $fileName;
-               $filePath = $this->getAbsolutePath($file);
-               if (!is_file($filePath)) {
-                       return array('', array());
-               }
-               return array($file, $file);
+       public function getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $filenameFilterCallbacks = array()) {
+               return $this->getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $filenameFilterCallbacks, TRUE, FALSE, $recursive);
        }
 
-
-
        /**
-        * Handler for items in a file list.
+        * Returns a list of folders inside the specified path
         *
-        * @param string $fileName
-        * @param string $path
-        * @param array $fileRow The pre-loaded file row
-        * @return array
-        */
-       protected function getFileList_itemCallback($fileName, $path, array $fileRow = array()) {
-               $filePath = $this->getAbsolutePath($path . $fileName);
-               if (!is_file($filePath)) {
-                       return array('', array());
-               }
-
-               // TODO add unit test for existing file row case
-               if (!empty($fileRow) && filemtime($filePath) <= $fileRow['modification_date']) {
-                       return array($fileName, $fileRow);
-               } else {
-                       return array($fileName, $this->extractFileInformation($filePath, $path));
-               }
-       }
-
-       /**
-        * Handler for items in a directory listing.
+        * @param string $folderIdentifier
+        * @param integer $start
+        * @param integer $numberOfItems
+        * @param boolean $recursive
+        * @param array $folderNameFilterCallbacks The method callbacks to use for filtering the items
         *
-        * @param string $folderName The folder's name
-        * @param string $parentPath The path to the folder's parent folder
-        * @param array $folderRow [optional]
-        * @return array
+        * @return array of Folder Identifier
         */
-       protected function getFolderList_itemCallback($folderName, $parentPath, array $folderRow = array()) {
-               $folderPath = $this->getAbsolutePath($parentPath . $folderName);
-
-               if (!is_dir($folderPath)) {
-                       return array('', array());
-               }
-
-               // also don't show hidden files
-               if ($folderName === '..' || $folderName === '.' || $folderName === '') {
-                       return array('', array());
-               }
-
-               // remove the trailing slash from the folder name (the trailing slash comes from the DirectoryIterator)
-               $folderName = substr($folderName, 0, -1);
-
-               return array($folderName, $this->extractFolderInformation($folderPath, $parentPath));
+       public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = FALSE, array $folderNameFilterCallbacks = array()) {
+               return $this->getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $folderNameFilterCallbacks, FALSE, TRUE, $recursive);
        }
 
        /**
         * Returns a list with the names of all files and folders in a path, optionally recursive.
-        * Folder names have a trailing slash.
         *
         * @param string $path The absolute path
-        * @param bool $recursive If TRUE, recursively fetches files and folders
+        * @param boolean $recursive If TRUE, recursively fetches files and folders
+        * @param boolean $includeFiles
+        * @param boolean $includeDirs
         * @return array
         */
-       protected function getFileAndFoldernamesInPath($path, $recursive = FALSE) {
+       protected function retrieveFileAndFoldersInPath($path, $recursive = FALSE, $includeFiles = TRUE, $includeDirs = TRUE) {
+               $pathLength = strlen($this->getAbsoluteBasePath());
+               $iteratorMode = \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_FILEINFO;
                if ($recursive) {
-                       $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, \FilesystemIterator::CURRENT_AS_FILEINFO), \RecursiveIteratorIterator::SELF_FIRST);
+                       $iterator = new \RecursiveIteratorIterator(
+                               new \RecursiveDirectoryIterator($path, $iteratorMode),
+                               \RecursiveIteratorIterator::SELF_FIRST
+                       );
                } else {
-                       $iterator = new \RecursiveDirectoryIterator($path, \FilesystemIterator::CURRENT_AS_FILEINFO);
+                       $iterator = new \RecursiveDirectoryIterator($path, $iteratorMode);
                }
 
                $directoryEntries = array();
@@ -474,28 +464,22 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                        /** @var $entry \SplFileInfo */
                        $entry = $iterator->current();
                        // skip non-files/non-folders, and empty entries
-                       if (!$entry->isFile() && !$entry->isDir() || $entry->getFilename() == '') {
+                       if ((!$entry->isFile() && !$entry->isDir()) || $entry->getFilename() == '' ||
+                               ($entry->isFile() && !$includeFiles) || ($entry->isDir() && !$includeDirs)) {
                                $iterator->next();
                                continue;
                        }
-                       // skip the pseudo-directories "." and ".."
-                       if ($entry->getFilename() == '..' || $entry->getFilename() == '.') {
-                               $iterator->next();
-                               continue;
-                       }
-                       $entryPath = substr($entry->getPathname(), strlen($path));
-                       $entryPath = GeneralUtility::fixWindowsFilePath($entryPath);
-                       $entryName = PathUtility::basename(basename($entryPath));
+                       $entryIdentifier = '/' . substr($entry->getPathname(), $pathLength);
+                       $entryName = PathUtility::basename($entryIdentifier);
                        if ($entry->isDir()) {
-                               $entryPath .= '/';
-                               $entryName .= '/';
+                               $entryIdentifier .= '/';
                        }
-                       $entry = array(
-                               'path' => $entryPath,
+                       $entryArray = array(
+                               'identifier' => $entryIdentifier,
                                'name' => $entryName,
                                'type' => $entry->isDir() ? 'dir' : 'file'
                        );
-                       $directoryEntries[$entryPath] = $entry;
+                       $directoryEntries[$entryIdentifier] = $entryArray;
                        $iterator->next();
                }
                return $directoryEntries;
@@ -511,7 +495,10 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         */
        protected function extractFileInformation($filePath, $containerPath, array $propertiesToExtract = array()) {
                if (count($propertiesToExtract) === 0) {
-                       $propertiesToExtract = array('size', 'atime', 'atime', 'mtime', 'ctime', 'mimetype', 'name', 'identifier', 'identifier_hash', 'storage', 'folder_hash');
+                       $propertiesToExtract = array(
+                               'size', 'atime', 'atime', 'mtime', 'ctime', 'mimetype', 'name',
+                               'identifier', 'identifier_hash', 'storage', 'folder_hash'
+                       );
                }
                $fileInformation = array();
                foreach ($propertiesToExtract as $property) {
@@ -520,63 +507,45 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                return $fileInformation;
        }
 
+
        /**
         * Extracts a specific FileInformation from the FileSystems.
         *
-        * @param string $filePath
+        * @param string $fileIdentifier
         * @param string $containerPath
         * @param string $property
         *
         * @return bool|int|string
         * @throws \InvalidArgumentException
         */
-       public function getSpecificFileInformation($filePath, $containerPath, $property) {
-               $identifier = $this->canonicalizeAndCheckFileIdentifier($containerPath . PathUtility::basename($filePath));
+       public function getSpecificFileInformation($fileIdentifier, $containerPath, $property) {
+               $identifier = $this->canonicalizeAndCheckFileIdentifier($containerPath . PathUtility::basename($fileIdentifier));
 
                switch ($property) {
                        case 'size':
-                               return filesize($filePath);
+                               return filesize($fileIdentifier);
                        case 'atime':
-                               return fileatime($filePath);
+                               return fileatime($fileIdentifier);
                        case 'mtime':
-                               return filemtime($filePath);
+                               return filemtime($fileIdentifier);
                        case 'ctime':
-                               return filectime($filePath);
+                               return filectime($fileIdentifier);
                        case 'name':
-                               return PathUtility::basename($filePath);
+                               return PathUtility::basename($fileIdentifier);
                        case 'mimetype':
-                               return $this->getMimeTypeOfFile($filePath);
+                               return $this->getMimeTypeOfFile($fileIdentifier);
                        case 'identifier':
                                return $identifier;
                        case 'storage':
-                               return $this->storage->getUid();
+                               return $this->storageUid;
                        case 'identifier_hash':
                                return $this->hashIdentifier($identifier);
                        case 'folder_hash':
-                               return $this->hashIdentifier($this->getFolderIdentifierForFile($identifier));
+                               return $this->hashIdentifier($this->getParentFolderIdentifierOfIdentifier($identifier));
                        default:
                                throw new \InvalidArgumentException(sprintf('The information "%s" is not available.', $property));
                }
-       }
-
-       /**
-        * Extracts information about a folder from the filesystem.
-        *
-        * @param string $folderPath The absolute path to the folder
-        * @param string $containerPath The relative path to the folder's container inside the storage (must end with a trailing slash)
-        * @return array
-        */
-       protected function extractFolderInformation($folderPath, $containerPath) {
-               $folderName = PathUtility::basename($folderPath);
-               $identifier = $this->canonicalizeAndCheckFolderIdentifier($containerPath . $folderName);
-               $folderInformation = array(
-                       'ctime' => filectime($folderPath),
-                       'mtime' => filemtime($folderPath),
-                       'name' => $folderName,
-                       'identifier' => $identifier,
-                       'storage' => $this->storage->getUid()
-               );
-               return $folderInformation;
+               return NULL;
        }
 
        /**
@@ -584,28 +553,19 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         *
         * @return string
         */
-       public function getAbsoluteBasePath() {
+       protected function getAbsoluteBasePath() {
                return $this->absoluteBasePath;
        }
 
        /**
         * Returns the absolute path of a file or folder.
         *
-        * @param FileInterface|Folder|string $file
+        * @param string $fileIdentifier
         * @return string
-        * @throws \RuntimeException
         */
-       public function getAbsolutePath($file) {
-               if ($file instanceof FileInterface) {
-                       $path = $this->absoluteBasePath . ltrim($this->canonicalizeAndCheckFileIdentifier($file->getIdentifier()), '/');
-               } elseif ($file instanceof Folder) {
-                       // We can assume a trailing slash here because it is added by the folder object on construction.
-                       $path = $this->absoluteBasePath . ltrim($this->canonicalizeAndCheckFolderIdentifier($file->getIdentifier()), '/');
-               } elseif (is_string($file)) {
-                       $path = $this->absoluteBasePath . ltrim($file, '/');
-               } else {
-                       throw new \RuntimeException('Type "' . gettype($file) . '" is not supported.', 1325191178);
-               }
+       protected function getAbsolutePath($fileIdentifier) {
+               $relativeFilePath = ltrim($this->canonicalizeAndCheckFileIdentifier($fileIdentifier), '/');
+               $path = $this->absoluteBasePath . $relativeFilePath;
                return $path;
        }
 
@@ -635,7 +595,7 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * @throws \InvalidArgumentException
         */
        public function hash($fileIdentifier, $hashAlgorithm) {
-               if (!in_array($hashAlgorithm, $this->getSupportedHashAlgorithms())) {
+               if (!in_array($hashAlgorithm, $this->supportedHashAlgorithms)) {
                        throw new \InvalidArgumentException('Hash algorithm "' . $hashAlgorithm . '" is not supported.', 1304964032);
                }
                switch ($hashAlgorithm) {
@@ -653,209 +613,162 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
 
        /**
         * Adds a file from the local server hard disk to a given path in TYPO3s virtual file system.
-        *
         * This assumes that the local file exists, so no further check is done here!
+        * After a successful the original file must not exist anymore.
         *
-        * @param string $localFilePath
-        * @param Folder $targetFolder
-        * @param string $fileName The name to add the file under
-        * @param \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject File object to update (instead of creating a new object). With this parameter, this function can be used to "populate" a dummy file object with a real file underneath.
-        * @todo \TYPO3\CMS\Core\Resource\File $updateFileObject should be \TYPO3\CMS\Core\Resource\FileInterface, but indexer logic is only in \TYPO3\CMS\Core\Resource\File
-        * @return FileInterface
+        * @param string $localFilePath (within PATH_site)
+        * @param string $targetFolderIdentifier
+        * @param string $newFileName optional, if not given original name is used
+        * @param boolean $removeOriginal if set the original file will be removed after successful operation
+        * @return string the identifier of the new file
         * @throws \RuntimeException
         * @throws \InvalidArgumentException
         */
-       public function addFile($localFilePath, Folder $targetFolder, $fileName, \TYPO3\CMS\Core\Resource\AbstractFile $updateFileObject = NULL) {
+       public function addFile($localFilePath, $targetFolderIdentifier, $newFileName = '', $removeOriginal = TRUE) {
                $localFilePath = $this->canonicalizeAndCheckFilePath($localFilePath);
                // as for the "virtual storage" for backwards-compatibility, this check always fails, as the file probably lies under PATH_site
                // thus, it is not checked here
-               if (GeneralUtility::isFirstPartOfStr($localFilePath, $this->absoluteBasePath) && $this->storage->getUid() > 0) {
+               // @ todo is check in storage
+               if (GeneralUtility::isFirstPartOfStr($localFilePath, $this->absoluteBasePath) && $this->storageUid > 0) {
                        throw new \InvalidArgumentException('Cannot add a file that is already part of this storage.', 1314778269);
                }
-               $relativeTargetPath = ltrim($targetFolder->getIdentifier(), '/');
-               $relativeTargetPath .= $this->sanitizeFileName($fileName ? $fileName : PathUtility::basename($localFilePath));
-               $targetPath = $this->absoluteBasePath . $relativeTargetPath;
-               if (is_uploaded_file($localFilePath)) {
-                       $moveResult = move_uploaded_file($localFilePath, $targetPath);
+               $newFileName = $this->sanitizeFileName($newFileName !== '' ? $newFileName : PathUtility::basename($localFilePath));
+               $newFileIdentifier = $this->canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier) . $newFileName;
+               $targetPath = $this->absoluteBasePath . $newFileIdentifier;
+
+               if ($removeOriginal) {
+                       if (is_uploaded_file($localFilePath)) {
+                               $result = move_uploaded_file($localFilePath, $targetPath);
+                       } else {
+                               $result = rename($localFilePath, $targetPath);
+                       }
                } else {
-                       $moveResult = rename($localFilePath, $targetPath);
+                       $result = copy($localFilePath, $targetPath);
                }
-               if ($moveResult !== TRUE) {
-                       throw new \RuntimeException('Moving file ' . $localFilePath . ' to ' . $targetPath . ' failed.', 1314803096);
+               if ($result === FALSE || !file_exists($targetPath)) {
+                       throw new \RuntimeException('Adding file ' . $localFilePath . ' at ' . $newFileIdentifier . ' failed.');
                }
                clearstatcache();
                // Change the permissions of the file
                GeneralUtility::fixPermissions($targetPath);
-               $fileInfo = $this->getFileInfoByIdentifier($relativeTargetPath);
-               if ($updateFileObject) {
-                       $updateFileObject->updateProperties($fileInfo);
-                       return $updateFileObject;
-               } else {
-                       $fileObject = $this->getFileObject($fileInfo);
-                       return $fileObject;
-               }
-       }
-
-       /**
-        * Checks if a resource exists - does not care for the type (file or folder).
-        *
-        * @param $identifier
-        * @return boolean
-        */
-       public function resourceExists($identifier) {
-               $absoluteResourcePath = $this->getAbsolutePath($identifier);
-               return file_exists($absoluteResourcePath);
+               return $newFileIdentifier;
        }
 
        /**
         * Checks if a file exists.
         *
-        * @param string $identifier
+        * @param string $fileIdentifier
+        *
         * @return boolean
         */
-       public function fileExists($identifier) {
-               $absoluteFilePath = $this->getAbsolutePath($identifier);
+       public function fileExists($fileIdentifier) {
+               $absoluteFilePath = $this->getAbsolutePath($fileIdentifier);
                return is_file($absoluteFilePath);
        }
 
        /**
-        * Checks if a file inside a storage folder exists
+        * Checks if a file inside a folder exists
         *
         * @param string $fileName
-        * @param Folder $folder
+        * @param string $folderIdentifier
         * @return boolean
         */
-       public function fileExistsInFolder($fileName, Folder $folder) {
-               $identifier = ltrim($folder->getIdentifier(), '/') . $fileName;
+       public function fileExistsInFolder($fileName, $folderIdentifier) {
+               $identifier = $folderIdentifier . '/' . $fileName;
+               $identifier = $this->canonicalizeAndCheckFileIdentifier($identifier);
                return $this->fileExists($identifier);
        }
 
        /**
         * Checks if a folder exists.
         *
-        * @param string $identifier
+        * @param string $folderIdentifier
+        *
         * @return boolean
         */
-       public function folderExists($identifier) {
-               $absoluteFilePath = $this->getAbsolutePath($identifier);
+       public function folderExists($folderIdentifier) {
+               $absoluteFilePath = $this->getAbsolutePath($folderIdentifier);
                return is_dir($absoluteFilePath);
        }
 
        /**
-        * Checks if a file inside a storage folder exists.
+        * Checks if a folder inside a folder exists.
         *
         * @param string $folderName
-        * @param Folder $folder
+        * @param string $folderIdentifier
         * @return boolean
         */
-       public function folderExistsInFolder($folderName, Folder $folder) {
-               $identifier = $folder->getIdentifier() . $folderName;
+       public function folderExistsInFolder($folderName, $folderIdentifier) {
+               $identifier = $folderIdentifier . '/' . $folderName;
                $identifier = $this->canonicalizeAndCheckFolderIdentifier($identifier);
                return $this->folderExists($identifier);
        }
 
        /**
-        * Returns a folder within the given folder.
+        * Returns the Identifier for a folder within a given folder.
+        *
+        * @param string $folderName The name of the target folder
+        * @param string $folderIdentifier
         *
-        * @param string $name The name of the folder to get
-        * @param Folder $parentFolder
-        * @return Folder
+        * @return string
         */
-       public function getFolderInFolder($name, Folder $parentFolder) {
-               $folderIdentifier = $parentFolder->getIdentifier() . $name . '/';
-               return $this->getFolder($folderIdentifier);
+       public function getFolderInFolder($folderName, $folderIdentifier) {
+               $folderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($folderIdentifier . '/' . $folderName);
+               return $folderIdentifier;
        }
 
        /**
         * Replaces the contents (and file-specific metadata) of a file object with a local file.
         *
-        * @param \TYPO3\CMS\Core\Resource\AbstractFile $file
+        * @param string $fileIdentifier
         * @param string $localFilePath
         * @return boolean TRUE if the operation succeeded
         * @throws \RuntimeException
         */
-       public function replaceFile(\TYPO3\CMS\Core\Resource\AbstractFile $file, $localFilePath) {
-               $filePath = $this->getAbsolutePath($file);
+       public function replaceFile($fileIdentifier, $localFilePath) {
+               $filePath = $this->getAbsolutePath($fileIdentifier);
                $result = rename($localFilePath, $filePath);
                if ($result === FALSE) {
-                       throw new \RuntimeException('Replacing file ' . $filePath . ' with ' . $localFilePath . ' failed.', 1315314711);
+                       throw new \RuntimeException('Replacing file ' . $fileIdentifier . ' with ' . $localFilePath . ' failed.', 1315314711);
                }
                return $result;
        }
 
        /**
-        * Adds a file at the specified location. This should only be used internally.
-        *
-        * @param string $localFilePath
-        * @param Folder $targetFolder
-        * @param string $targetFileName
-        * @return boolean TRUE if adding the file succeeded
-        * @throws \RuntimeException
-        */
-       public function addFileRaw($localFilePath, Folder $targetFolder, $targetFileName) {
-               $fileIdentifier = $targetFolder->getIdentifier() . $targetFileName;
-               $absoluteFilePath = $this->getAbsolutePath($fileIdentifier);
-               $result = copy($localFilePath, $absoluteFilePath);
-               if ($result === FALSE || !file_exists($absoluteFilePath)) {
-                       throw new \RuntimeException('Adding file ' . $localFilePath . ' at ' . $fileIdentifier . ' failed.');
-               }
-               return $fileIdentifier;
-       }
-
-       /**
-        * Deletes a file without access and usage checks. This should only be used internally.
-        *
-        * This accepts an identifier instead of an object because we might want to delete files that have no object
-        * associated with (or we don't want to create an object for) them - e.g. when moving a file to another storage.
-        *
-        * @param string $identifier
-        * @return boolean TRUE if removing the file succeeded
-        * @throws \RuntimeException
-        */
-       public function deleteFileRaw($identifier) {
-               $targetPath = $this->getAbsolutePath($identifier);
-
-               $result = unlink($targetPath);
-               if ($result === FALSE || file_exists($targetPath)) {
-                       throw new \RuntimeException('Deleting file ' . $identifier . ' failed.', 1320381534);
-               }
-               return TRUE;
-       }
-
-       /**
         * Copies a file *within* the current storage.
-        * Note that this is only about an intra-storage move action, where a file is just
-        * moved to another folder in the same storage.
+        * Note that this is only about an intra-storage copy action, where a file is just
+        * copied to another folder in the same storage.
         *
-        * @param FileInterface $file
-        * @param Folder $targetFolder
+        * @param string $fileIdentifier
+        * @param string $targetFolderIdentifier
         * @param string $fileName
-        * @return FileInterface The new (copied) file object.
+        * @return string the Identifier of the new file
         */
-       public function copyFileWithinStorage(FileInterface $file, Folder $targetFolder, $fileName) {
-               // TODO add unit test
-               $sourcePath = $this->getAbsolutePath($file);
-               $targetPath = $targetFolder->getIdentifier() . $fileName;
-               $targetPath = $this->canonicalizeAndCheckFileIdentifier($targetPath);
-
-               copy($sourcePath, $this->absoluteBasePath . $targetPath);
-               return $this->getFile($targetPath);
+       public function copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName) {
+               $sourcePath = $this->getAbsolutePath($fileIdentifier);
+               $newIdentifier = $targetFolderIdentifier . '/' . $fileName;
+               $newIdentifier = $this->canonicalizeAndCheckFileIdentifier($newIdentifier);
+
+               copy($sourcePath, $this->absoluteBasePath . $newIdentifier);
+               GeneralUtility::fixPermissions($this->absoluteBasePath . $newIdentifier);
+               return $newIdentifier;
        }
 
        /**
         * Moves a file *within* the current storage.
-        * Note that this is only about an intra-storage move action, where a file is just
+        * Note that this is only about an inner-storage move action, where a file is just
         * moved to another folder in the same storage.
         *
-        * @param FileInterface $file
-        * @param Folder $targetFolder
-        * @param string $fileName
-        * @return boolean
+        * @param string $fileIdentifier
+        * @param string $targetFolderIdentifier
+        * @param string $newFileName
+        *
+        * @return string
         * @throws \RuntimeException
         */
-       public function moveFileWithinStorage(FileInterface $file, Folder $targetFolder, $fileName) {
-               $sourcePath = $this->getAbsolutePath($file);
-               $targetIdentifier = $targetFolder->getIdentifier() . $fileName;
+       public function moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName) {
+               $sourcePath = $this->getAbsolutePath($fileIdentifier);
+               $targetIdentifier = $targetFolderIdentifier . '/' . $newFileName;
                $targetIdentifier = $this->canonicalizeAndCheckFileIdentifier($targetIdentifier);
                $result = rename($sourcePath, $this->getAbsolutePath($targetIdentifier));
                if ($result === FALSE) {
@@ -867,16 +780,17 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        /**
         * Copies a file to a temporary path and returns that path.
         *
-        * @param FileInterface $file
+        * @param string $fileIdentifier
         * @return string The temporary path
         * @throws \RuntimeException
         */
-       public function copyFileToTemporaryPath(FileInterface $file) {
-               $sourcePath = $this->getAbsolutePath($file);
-               $temporaryPath = $this->getTemporaryPathForFile($file);
+       protected function copyFileToTemporaryPath($fileIdentifier) {
+               $sourcePath = $this->getAbsolutePath($fileIdentifier);
+               $temporaryPath = $this->getTemporaryPathForFile($fileIdentifier);
                $result = copy($sourcePath, $temporaryPath);
+               touch($temporaryPath, filemtime($sourcePath));
                if ($result === FALSE) {
-                       throw new \RuntimeException('Copying file ' . $file->getIdentifier() . ' to temporary path failed.', 1320577649);
+                       throw new \RuntimeException('Copying file ' . $fileIdentifier . ' to temporary path failed.', 1320577649);
                }
                return $temporaryPath;
        }
@@ -886,19 +800,32 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * moving a folder. The old identifier is used as the key, the new one as the value.
         *
         * @param array $filesAndFolders
-        * @param string $relativeSourcePath
-        * @param string $relativeTargetPath
+        * @param string $sourceFolderIdentifier
+        * @param string $targetFolderIdentifier
+        *
         * @return array
         * @throws \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException
         */
-       protected function createIdentifierMap(array $filesAndFolders, $relativeSourcePath, $relativeTargetPath) {
+       protected function createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier) {
                $identifierMap = array();
-               $identifierMap[$relativeSourcePath] = $relativeTargetPath;
+               $identifierMap[$sourceFolderIdentifier] = $targetFolderIdentifier;
                foreach ($filesAndFolders as $oldItem) {
-                       $oldIdentifier = $relativeSourcePath . $oldItem['path'];
-                       $newIdentifier = $relativeTargetPath . $oldItem['path'];
-                       if (!$this->resourceExists($newIdentifier)) {
-                               throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(sprintf('File "%1$s" was not found (should have been copied/moved from "%2$s").', $newIdentifier, $oldIdentifier), 1330119453);
+                       if ($oldItem['type'] == 'dir') {
+                               $oldIdentifier = $oldItem['identifier'];
+                               $newIdentifier = $this->canonicalizeAndCheckFolderIdentifier(
+                                       str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
+                               );
+                       } else {
+                               $oldIdentifier = $oldItem['identifier'];
+                               $newIdentifier = $this->canonicalizeAndCheckFileIdentifier(
+                                       str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
+                               );
+                       }
+                       if (!file_exists($this->getAbsolutePath($newIdentifier))) {
+                               throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
+                                       sprintf('File "%1$s" was not found (should have been copied/moved from "%2$s").', $newIdentifier, $oldIdentifier),
+                                       1330119453
+                               );
                        }
                        $identifierMap[$oldIdentifier] = $newIdentifier;
                }
@@ -908,46 +835,51 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        /**
         * Folder equivalent to moveFileWithinStorage().
         *
-        * @param Folder $folderToMove
-        * @param Folder $targetFolder
+        * @param string $sourceFolderIdentifier
+        * @param string $targetFolderIdentifier
         * @param string $newFolderName
+        *
         * @return array A map of old to new file identifiers
         * @throws \RuntimeException
         */
-       public function moveFolderWithinStorage(Folder $folderToMove, Folder $targetFolder, $newFolderName) {
-               $relativeSourcePath = $folderToMove->getIdentifier();
-               $sourcePath = $this->getAbsolutePath($relativeSourcePath);
-               $relativeTargetPath = $this->canonicalizeAndCheckFolderIdentifier($targetFolder->getIdentifier() . $newFolderName);
+       public function moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName) {
+               $sourcePath = $this->getAbsolutePath($sourceFolderIdentifier);
+               $relativeTargetPath = $this->canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
                $targetPath = $this->getAbsolutePath($relativeTargetPath);
                // get all files and folders we are going to move, to have a map for updating later.
-               $filesAndFolders = $this->getFileAndFoldernamesInPath($sourcePath, TRUE);
+               $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, TRUE);
                $result = rename($sourcePath, $targetPath);
                if ($result === FALSE) {
                        throw new \RuntimeException('Moving folder ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320711817);
                }
                // Create a mapping from old to new identifiers
-               $identifierMap = $this->createIdentifierMap($filesAndFolders, $relativeSourcePath, $relativeTargetPath);
+               $identifierMap = $this->createIdentifierMap($filesAndFolders, $sourceFolderIdentifier, $relativeTargetPath);
                return $identifierMap;
        }
 
        /**
         * Folder equivalent to copyFileWithinStorage().
         *
-        * @param Folder $folderToCopy
-        * @param Folder $targetFolder
+        * @param string $sourceFolderIdentifier
+        * @param string $targetFolderIdentifier
         * @param string $newFolderName
+        *
         * @return boolean
         * @throws \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException
         */
-       public function copyFolderWithinStorage(Folder $folderToCopy, Folder $targetFolder, $newFolderName) {
+       public function copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName) {
                // This target folder path already includes the topmost level, i.e. the folder this method knows as $folderToCopy.
                // We can thus rely on this folder being present and just create the subfolder we want to copy to.
-               $newFolderName = $this->canonicalizeAndCheckFolderIdentifier($targetFolder->getIdentifier() . '/' . $newFolderName);
-               $targetFolderPath = $this->getAbsoluteBasePath() . $newFolderName . '/';
+               $newFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
+               $sourceFolderPath = $this->getAbsolutePath($sourceFolderIdentifier);
+               $targetFolderPath = $this->getAbsolutePath($newFolderIdentifier);
+
                mkdir($targetFolderPath);
-               $sourceFolderPath = $this->getAbsolutePath($folderToCopy);
                /** @var $iterator \RecursiveDirectoryIterator */
-               $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($sourceFolderPath), \RecursiveIteratorIterator::SELF_FIRST);
+               $iterator = new \RecursiveIteratorIterator(
+                       new \RecursiveDirectoryIterator($sourceFolderPath),
+                       \RecursiveIteratorIterator::SELF_FIRST
+               );
                // Rewind the iterator as this is important for some systems e.g. Windows
                $iterator->rewind();
                while ($iterator->valid()) {
@@ -956,66 +888,44 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                        $fileName = $current->getFilename();
                        $itemSubPath = GeneralUtility::fixWindowsFilePath($iterator->getSubPathname());
                        if ($current->isDir() && !($fileName === '..' || $fileName === '.')) {
-                               mkdir($targetFolderPath . $itemSubPath);
+                               GeneralUtility::mkdir($targetFolderPath . '/' . $itemSubPath);
                        } elseif ($current->isFile()) {
-                               $result = copy($sourceFolderPath . $itemSubPath, $targetFolderPath . $itemSubPath);
+                               $result = copy($sourceFolderPath . '/' . $itemSubPath, $targetFolderPath . '/' . $itemSubPath);
                                if ($result === FALSE) {
+                                       // rollback
+                                       GeneralUtility::rmdir($targetFolderIdentifier, TRUE);
                                        throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
                                                'Copying file "' . $sourceFolderPath . $itemSubPath . '" to "' . $targetFolderPath . $itemSubPath . '" failed.',
                                                1330119452
                                        );
+
                                }
                        }
                        $iterator->next();
                }
+               GeneralUtility::fixPermissions($targetFolderPath, TRUE);
                return TRUE;
        }
 
        /**
-        * Move a folder from another storage.
-        *
-        * @param Folder $folderToMove
-        * @param Folder $targetParentFolder
-        * @param string $newFolderName
-        * @return boolean
-        */
-       public function moveFolderBetweenStorages(Folder $folderToMove, Folder $targetParentFolder, $newFolderName) {
-               // TODO implement a clever shortcut here if both storages are of type local
-               return parent::moveFolderBetweenStorages($folderToMove, $targetParentFolder, $newFolderName);
-       }
-
-       /**
-        * Copy a folder from another storage.
-        *
-        * @param Folder $folderToCopy
-        * @param Folder $targetParentFolder
-        * @param string $newFolderName
-        * @return boolean
-        */
-       public function copyFolderBetweenStorages(Folder $folderToCopy, Folder $targetParentFolder, $newFolderName) {
-               // TODO implement a clever shortcut here if both storages are of type local
-               return parent::copyFolderBetweenStorages($folderToCopy, $targetParentFolder, $newFolderName);
-       }
-
-       /**
         * Renames a file in this storage.
         *
-        * @param FileInterface $file
+        * @param string $fileIdentifier
         * @param string $newName The target path (including the file name!)
         * @return string The identifier of the file after renaming
         * @throws \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
         * @throws \RuntimeException
         */
-       public function renameFile(FileInterface $file, $newName) {
+       public function renameFile($fileIdentifier, $newName) {
                // Makes sure the Path given as parameter is valid
                $newName = $this->sanitizeFileName($newName);
-               $newIdentifier = rtrim(GeneralUtility::fixWindowsFilePath(PathUtility::dirname($file->getIdentifier())), '/') . '/' . $newName;
+               $newIdentifier = rtrim(GeneralUtility::fixWindowsFilePath(PathUtility::dirname($fileIdentifier)), '/') . '/' . $newName;
                $newIdentifier = $this->canonicalizeAndCheckFileIdentifier($newIdentifier);
                // The target should not exist already
                if ($this->fileExists($newIdentifier)) {
                        throw new \TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException('The target file already exists.', 1320291063);
                }
-               $sourcePath = $this->getAbsolutePath($file);
+               $sourcePath = $this->getAbsolutePath($fileIdentifier);
                $targetPath = $this->getAbsolutePath($newIdentifier);
                $result = rename($sourcePath, $targetPath);
                if ($result === FALSE) {
@@ -1028,47 +938,56 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        /**
         * Renames a folder in this storage.
         *
-        * @param Folder $folder
-        * @param string $newName The target path (including the file name!)
-        * @return array A map of old to new file identifiers
+        * @param string $folderIdentifier
+        * @param string $newName
+        * @return array A map of old to new file identifiers of all affected files and folders
         * @throws \RuntimeException if renaming the folder failed
         */
-       public function renameFolder(Folder $folder, $newName) {
-               // Makes sure the path given as parameter is valid
+       public function renameFolder($folderIdentifier, $newName) {
+               $folderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($folderIdentifier);
                $newName = $this->sanitizeFileName($newName);
-               $newName = $this->canonicalizeAndCheckFolderIdentifier($newName);
-               $relativeSourcePath = $folder->getIdentifier();
-               $sourcePath = $this->getAbsolutePath($relativeSourcePath);
-               $relativeTargetPath = $this->canonicalizeAndCheckFolderIdentifier(PathUtility::dirname($relativeSourcePath). '/' . $newName);
-               $targetPath = $this->getAbsolutePath($relativeTargetPath);
+
+               $newIdentifier = PathUtility::dirname($folderIdentifier) . '/' . $newName;
+               $newIdentifier = $this->canonicalizeAndCheckFolderIdentifier($newIdentifier);
+
+               $sourcePath = $this->getAbsolutePath($folderIdentifier);
+               $targetPath = $this->getAbsolutePath($newIdentifier);
                // get all files and folders we are going to move, to have a map for updating later.
-               $filesAndFolders = $this->getFileAndFoldernamesInPath($sourcePath, TRUE);
+               $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, TRUE);
                $result = rename($sourcePath, $targetPath);
                if ($result === FALSE) {
                        throw new \RuntimeException(sprintf('Renaming folder "%1$s" to "%2$s" failed."', $sourcePath, $targetPath), 1320375116);
                }
                try {
                        // Create a mapping from old to new identifiers
-                       $identifierMap = $this->createIdentifierMap($filesAndFolders, $relativeSourcePath, $relativeTargetPath);
+                       $identifierMap = $this->createIdentifierMap($filesAndFolders, $folderIdentifier, $newIdentifier);
                } catch (\Exception $e) {
                        rename($targetPath, $sourcePath);
-                       throw new \RuntimeException(sprintf('Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"', $sourcePath, $targetPath, $e->getMessage()), 1334160746);
+                       throw new \RuntimeException(
+                               sprintf(
+                                       'Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"',
+                                       $sourcePath, $targetPath, $e->getMessage()
+                               ),
+                               1334160746
+                       );
                }
                return $identifierMap;
        }
 
        /**
-        * Removes a file from this storage.
+        * Removes a file from the filesystem. This does not check if the file is
+        * still used or if it is a bad idea to delete it for some other reason
+        * this has to be taken care of in the upper layers (e.g. the Storage)!
         *
-        * @param FileInterface $file
+        * @param string $fileIdentifier
         * @return boolean TRUE if deleting the file succeeded
         * @throws \RuntimeException
         */
-       public function deleteFile(FileInterface $file) {
-               $filePath = $this->getAbsolutePath($file);
+       public function deleteFile($fileIdentifier) {
+               $filePath = $this->getAbsolutePath($fileIdentifier);
                $result = unlink($filePath);
                if ($result === FALSE) {
-                       throw new \RuntimeException('Deletion of file ' . $file->getIdentifier() . ' failed.', 1320855304);
+                       throw new \RuntimeException('Deletion of file ' . $fileIdentifier . ' failed.', 1320855304);
                }
                return $result;
        }
@@ -1076,16 +995,19 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        /**
         * Removes a folder from this storage.
         *
-        * @param Folder $folder
-        * @param bool $deleteRecursively
+        * @param string $folderIdentifier
+        * @param boolean $deleteRecursively
         * @return boolean
         * @throws \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException
         */
-       public function deleteFolder(Folder $folder, $deleteRecursively = FALSE) {
-               $folderPath = $this->getAbsolutePath($folder);
+       public function deleteFolder($folderIdentifier, $deleteRecursively = FALSE) {
+               $folderPath = $this->getAbsolutePath($folderIdentifier);
                $result = GeneralUtility::rmdir($folderPath, $deleteRecursively);
                if ($result === FALSE) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException('Deleting folder "' . $folder->getIdentifier() . '" failed.', 1330119451);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException(
+                               'Deleting folder "' . $folderIdentifier . '" failed.',
+                               1330119451
+                       );
                }
                return $result;
        }
@@ -1093,11 +1015,11 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        /**
         * Checks if a folder contains files and (if supported) other folders.
         *
-        * @param Folder $folder
+        * @param string $folderIdentifier
         * @return boolean TRUE if there are no files and folders within $folder
         */
-       public function isFolderEmpty(Folder $folder) {
-               $path = $this->getAbsolutePath($folder);
+       public function isFolderEmpty($folderIdentifier) {
+               $path = $this->getAbsolutePath($folderIdentifier);
                $dirHandle = opendir($path);
                while ($entry = readdir($dirHandle)) {
                        if ($entry !== '.' && $entry !== '..') {
@@ -1105,60 +1027,38 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                                return FALSE;
                        }
                }
+               closedir($dirHandle);
                return TRUE;
        }
 
        /**
-        * Returns a (local copy of) a file for processing it. This makes a copy
-        * first when in writable mode, so if you change the file,
-        * you have to update it yourself afterwards.
+        * Returns (a local copy of) a file for processing it. This makes a copy
+        * first when in writable mode, so if you change the file, you have to update it yourself afterwards.
         *
-        * @param FileInterface $file
-        * @param boolean $writable Set this to FALSE if you only need the file for read operations. This might speed up things, e.g. by using a cached local version. Never modify the file if you have set this flag!
+        * @param string $fileIdentifier
+        * @param boolean $writable Set this to FALSE if you only need the file for read operations.
+        *                          This might speed up things, e.g. by using a cached local version.
+        *                          Never modify the file if you have set this flag!
         * @return string The path to the file on the local disk
         */
-       public function getFileForLocalProcessing(FileInterface $file, $writable = TRUE) {
+       public function getFileForLocalProcessing($fileIdentifier, $writable = TRUE) {
                if ($writable === FALSE) {
-                       // TODO check if this is ok or introduce additional measures against file changes
-                       return $this->getAbsolutePath($file);
+                       return $this->getAbsolutePath($fileIdentifier);
                } else {
-                       // TODO check if this might also serve as a dump basic implementation in the abstract driver.
-                       return $this->copyFileToTemporaryPath($file);
+                       return $this->copyFileToTemporaryPath($fileIdentifier);
                }
        }
 
-       /**
-        * Returns the permissions of a file as an array (keys r, w) of boolean flags
-        *
-        * @param FileInterface $file The file object to check
-        * @return array
-        * @throws \RuntimeException If fetching the permissions failed
-        */
-       public function getFilePermissions(FileInterface $file) {
-               $filePath = $this->getAbsolutePath($file);
-               return $this->getPermissions($filePath);
-       }
-
-       /**
-        * Returns the permissions of a folder as an array (keys r, w) of boolean flags
-        *
-        * @param Folder $folder
-        * @return array
-        * @throws \RuntimeException If fetching the permissions failed
-        */
-       public function getFolderPermissions(Folder $folder) {
-               $folderPath = $this->getAbsolutePath($folder);
-               return $this->getPermissions($folderPath);
-       }
 
        /**
-        * Helper function to unify access to permission information
+        * Returns the permissions of a file/folder as an array (keys r, w) of boolean flags
         *
-        * @param string $path
+        * @param string $identifier
         * @return array
-        * @throws \RuntimeException If fetching the permissions failed
+        * @throws \RuntimeException
         */
-       protected function getPermissions($path) {
+       public function getPermissions($identifier) {
+               $path = $this->getAbsolutePath($identifier);
                $permissionBits = fileperms($path);
                if ($permissionBits === FALSE) {
                        throw new \RuntimeException('Error while fetching permissions for ' . $path, 1319455097);
@@ -1170,49 +1070,49 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        }
 
        /**
-        * Checks if a given object or identifier is within a container, e.g. if
+        * Checks if a given identifier is within a container, e.g. if
         * a file or folder is within another folder.
         * This can e.g. be used to check for webmounts.
         *
-        * @param Folder $container
-        * @param mixed $content An object or an identifier to check
-        * @return boolean TRUE if $content is within $container, always FALSE if $container is not within this storage
+        * @param string $folderIdentifier
+        * @param string $identifier identifier to be checked against $folderIdentifier
+        *
+        * @return boolean TRUE if $content is within $folderIdentifier
         */
-       public function isWithin(Folder $container, $content) {
-               if ($container->getStorage() != $this->storage) {
-                       return FALSE;
-               }
-               if ($content instanceof FileInterface || $content instanceof Folder) {
-                       $content = $container->getIdentifier();
-               }
-               $folderPath = $container->getIdentifier();
-               $content = '/' . ltrim($content, '/');
-               return GeneralUtility::isFirstPartOfStr($content, $folderPath);
+       public function isWithin($folderIdentifier, $identifier) {
+               $folderPath = $this->canonicalizeAndCheckFolderIdentifier($folderIdentifier);
+               $identifier = $this->canonicalizeAndCheckFileIdentifier($identifier);
+               return GeneralUtility::isFirstPartOfStr($identifier, $folderPath);
        }
 
        /**
-        * Creates a new file and returns the matching file object for it.
+        * Creates a new (empty) file and returns the identifier.
         *
         * @param string $fileName
-        * @param Folder $parentFolder
-        * @return \TYPO3\CMS\Core\Resource\File
+        * @param string $parentFolderIdentifier
+        * @return string
         * @throws \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException
         * @throws \RuntimeException
         */
-       public function createFile($fileName, Folder $parentFolder) {
+       public function createFile($fileName, $parentFolderIdentifier) {
                if (!$this->isValidFilename($fileName)) {
-                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException('Invalid characters in fileName "' . $fileName . '"', 1320572272);
+                       throw new \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException(
+                               'Invalid characters in fileName "' . $fileName . '"',
+                               1320572272
+                       );
                }
-               $filePath = $parentFolder->getIdentifier() . $this->sanitizeFileName(ltrim($fileName, '/'));
-               $absoluteFilePath = $this->getAbsolutePath($filePath);
+               $parentFolderIdentifier = $this->canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
+               $fileIdentifier =  $this->canonicalizeAndCheckFileIdentifier(
+                       $parentFolderIdentifier . $this->sanitizeFileName(ltrim($fileName, '/'))
+               );
+               $absoluteFilePath = $this->getAbsolutePath($fileIdentifier);
                $result = touch($absoluteFilePath);
                GeneralUtility::fixPermissions($absoluteFilePath);
                clearstatcache();
                if ($result !== TRUE) {
-                       throw new \RuntimeException('Creating file ' . $filePath . ' failed.', 1320569854);
+                       throw new \RuntimeException('Creating file ' . $fileIdentifier . ' failed.', 1320569854);
                }
-               $fileInfo = $this->getFileInfoByIdentifier($filePath);
-               return $this->getFileObject($fileInfo);
+               return $fileIdentifier;
        }
 
        /**
@@ -1221,31 +1121,31 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * external location. So this might be an expensive operation (both in terms of
         * processing resources and money) for large files.
         *
-        * @param FileInterface $file
+        * @param string $fileIdentifier
         * @return string The file contents
         */
-       public function getFileContents(FileInterface $file) {
-               $filePath = $this->getAbsolutePath($file);
+       public function getFileContents($fileIdentifier) {
+               $filePath = $this->getAbsolutePath($fileIdentifier);
                return file_get_contents($filePath);
        }
 
        /**
         * Sets the contents of a file to the specified value.
         *
-        * @param FileInterface $file
+        * @param string $fileIdentifier
         * @param string $contents
         * @return integer The number of bytes written to the file
         * @throws \RuntimeException if the operation failed
         */
-       public function setFileContents(FileInterface $file, $contents) {
-               $filePath = $this->getAbsolutePath($file);
+       public function setFileContents($fileIdentifier, $contents) {
+               $filePath = $this->getAbsolutePath($fileIdentifier);
                $result = file_put_contents($filePath, $contents);
 
                // Make sure later calls to filesize() etc. return correct values.
                clearstatcache(TRUE, $filePath);
 
                if ($result === FALSE) {
-                       throw new \RuntimeException('Setting contents of file "' . $file->getIdentifier() . '" failed.', 1325419305);
+                       throw new \RuntimeException('Setting contents of file "' . $fileIdentifier . '" failed.', 1325419305);
                }
                return $result;
        }
@@ -1270,15 +1170,15 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                return $this->charsetConversion;
        }
 
-
        /**
         * Returns the role of an item (currently only folders; can later be extended for files as well)
         *
-        * @param \TYPO3\CMS\Core\Resource\ResourceInterface $item
+        * @param string $folderIdentifier
         * @return string
         */
-       public function getRole(\TYPO3\CMS\Core\Resource\ResourceInterface $item) {
-               $role = $this->mappingFolderNameToRole[$item->getName()];
+       public function getRole($folderIdentifier) {
+               $name = PathUtility::basename($folderIdentifier);
+               $role = $this->mappingFolderNameToRole[$name];
                if (empty($role)) {
                        $role = FolderInterface::ROLE_DEFAULT;
                }
index fdbc793..8a5ba35 100644 (file)
@@ -72,7 +72,7 @@ class FileExtensionFilter {
                                $fileReferenceUid = $parts[count($parts) - 1];
                                $fileReference = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileReferenceObject($fileReferenceUid);
                                $file = $fileReference->getOriginalFile();
-                               if ($this->isAllowed($file)) {
+                               if ($this->isAllowed($file->getIdentifier())) {
                                        $cleanValues[] = $value;
                                } else {
                                        // Remove the erroneously created reference record again
@@ -93,10 +93,10 @@ class FileExtensionFilter {
         * @param string $itemIdentifier
         * @param string $parentIdentifier
         * @param array $additionalInformation Additional information about the inspected item
-        * @param \TYPO3\CMS\Core\Resource\Driver\AbstractDriver $driver
+        * @param \TYPO3\CMS\Core\Resource\Driver\DriverInterface $driver
         * @return boolean|integer -1 if the file should not be included in a listing
         */
-       public function filterFileList($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, \TYPO3\CMS\Core\Resource\Driver\AbstractDriver $driver) {
+       public function filterFileList($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, \TYPO3\CMS\Core\Resource\Driver\DriverInterface $driver) {
                $returnCode = TRUE;
                // Early return in case no file filters are set at all
                if ($this->allowedFileExtensions === NULL && $this->disallowedFileExtensions === NULL) {
@@ -104,8 +104,7 @@ class FileExtensionFilter {
                }
                // Check that this is a file and not a folder
                if ($driver->fileExists($itemIdentifier)) {
-                       $file = $driver->getFile($itemIdentifier);
-                       if (!$this->isAllowed($file)) {
+                       if (!$this->isAllowed($itemName)) {
                                $returnCode = -1;
                        }
                }
@@ -118,9 +117,9 @@ class FileExtensionFilter {
         * @param \TYPO3\CMS\Core\Resource\FileInterface $file
         * @return boolean
         */
-       protected function isAllowed(\TYPO3\CMS\Core\Resource\FileInterface $file) {
+       protected function isAllowed($fileName) {
                $result = TRUE;
-               $fileExt = strtolower($file->getExtension());
+               $fileExt = pathinfo($fileName, PATHINFO_EXTENSION);
                // Check allowed file extensions
                if ($this->allowedFileExtensions !== NULL && count($this->allowedFileExtensions) > 0 && !in_array($fileExt, $this->allowedFileExtensions)) {
                        $result = FALSE;
index b4def81..19a3bfd 100644 (file)
@@ -50,10 +50,10 @@ class FileNameFilter {
         * @param string $itemIdentifier
         * @param string $parentIdentifier
         * @param array $additionalInformation Additional information (driver dependent) about the inspected item
-        * @param \TYPO3\CMS\Core\Resource\Driver\AbstractDriver $driverInstance
+        * @param \TYPO3\CMS\Core\Resource\Driver\DriverInterface $driverInstance
         * @return boolean|integer -1 if the file should not be included in a listing
         */
-       static public function filterHiddenFilesAndFolders($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, \TYPO3\CMS\Core\Resource\Driver\AbstractDriver $driverInstance) {
+       static public function filterHiddenFilesAndFolders($itemName, $itemIdentifier, $parentIdentifier, array $additionalInformation, \TYPO3\CMS\Core\Resource\Driver\DriverInterface $driverInstance) {
                // Only apply the filter if you want to hide the hidden files
                if (self::$showHiddenFilesAndFolders === FALSE && substr($itemName, 0, 1) == '.') {
                        return -1;
index 544f60f..e636bf4 100644 (file)
@@ -241,19 +241,8 @@ class Folder implements FolderInterface {
         */
        public function getSubfolders($start = 0, $numberOfItems = 0, $filterMode = self::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS) {
                list($backedUpFilters, $useFilters) = $this->prepareFiltersInStorage($filterMode);
-
-               $folderObjects = array();
-               $folderArray = $this->storage->getFolderList($this->identifier, $start, $numberOfItems, $useFilters);
-               if (count($folderArray) > 0) {
-                       /** @var $factory ResourceFactory */
-                       $factory = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
-                       foreach ($folderArray as $folder) {
-                               $folderObjects[$folder['name']] = $factory->createFolderObject($this->storage, $folder['identifier'], $folder['name']);
-                       }
-               }
-
+               $folderObjects = $this->storage->getFoldersInFolder($this, $start, $numberOfItems, $useFilters);
                $this->restoreBackedUpFiltersInStorage($backedUpFilters);
-
                return $folderObjects;
        }
 
index b840569..bb8e058 100644 (file)
@@ -97,7 +97,7 @@ class ResourceFactory implements \TYPO3\CMS\Core\SingletonInterface {
         *
         * @param string $driverIdentificationString The driver class (or identifier) to use.
         * @param array $driverConfiguration The configuration of the storage
-        * @return Driver\AbstractDriver
+        * @return Driver\DriverInterface
         * @throws \InvalidArgumentException
         */
        public function getDriverObject($driverIdentificationString, array $driverConfiguration) {
index a2e8875..ccf961b 100644 (file)
@@ -91,10 +91,11 @@ class ResourceStorage {
        const SIGNAL_PreFolderRename = 'preFolderRename';
        const SIGNAL_PostFolderRename = 'postFolderRename';
        const SIGNAL_PreGeneratePublicUrl = 'preGeneratePublicUrl';
+
        /**
         * The storage driver instance belonging to this storage.
         *
-        * @var Driver\AbstractDriver
+        * @var Driver\DriverInterface
         */
        protected $driver;
 
@@ -201,14 +202,14 @@ class ResourceStorage {
        /**
         * Constructor for a storage object.
         *
-        * @param Driver\AbstractDriver $driver
+        * @param Driver\DriverInterface $driver
         * @param array $storageRecord The storage record row from the database
         */
-       public function __construct(Driver\AbstractDriver $driver, array $storageRecord) {
+       public function __construct(Driver\DriverInterface $driver, array $storageRecord) {
                $this->storageRecord = $storageRecord;
                $this->configuration = ResourceFactory::getInstance()->convertFlexFormDataToConfigurationArray($storageRecord['configuration']);
                $this->driver = $driver;
-               $this->driver->setStorage($this);
+               $this->driver->setStorageUid($storageRecord['uid']);
                try {
                        $this->driver->processConfiguration();
                } catch (Exception\InvalidConfigurationException $e) {
@@ -277,10 +278,10 @@ class ResourceStorage {
        /**
         * Sets the storage that belongs to this storage.
         *
-        * @param Driver\AbstractDriver $driver
+        * @param Driver\DriverInterface $driver
         * @return ResourceStorage
         */
-       public function setDriver(Driver\AbstractDriver $driver) {
+       public function setDriver(Driver\DriverInterface $driver) {
                $this->driver = $driver;
                return $this;
        }
@@ -288,7 +289,7 @@ class ResourceStorage {
        /**
         * Returns the driver object belonging to this storage.
         *
-        * @return Driver\AbstractDriver
+        * @return Driver\DriverInterface
         */
        protected function getDriver() {
                return $this->driver;
@@ -489,7 +490,8 @@ class ResourceStorage {
                        // as otherwise the user would see the whole storage without any restrictions for the filemounts
                        throw new Exception\FolderDoesNotExistException('Folder for file mount ' . $folderIdentifier . ' does not exist.', 1334427099);
                }
-               $folderObject = $this->driver->getFolder($folderIdentifier);
+               $data = $this->driver->getFolderInfoByIdentifier($folderIdentifier);
+               $folderObject = ResourceFactory::getInstance()->createFolderObject($this, $data['identifier'], $data['name']);
                if (empty($additionalData)) {
                        $additionalData = array(
                                'path' => $folderIdentifier,
@@ -532,13 +534,13 @@ class ResourceStorage {
                $identifier = $subject->getIdentifier();
 
                // Allow access to processing folder
-               if ($this->driver->isWithin($this->getProcessingFolder(), $identifier)) {
+               if ($this->driver->isWithin($this->getProcessingFolder()->getIdentifier(), $identifier)) {
                        $isWithinFilemount = TRUE;
                } else {
                        // Check if the identifier of the subject is within at
                        // least one of the file mounts
                        foreach ($this->fileMounts as $fileMount) {
-                               if ($this->driver->isWithin($fileMount['folder'], $identifier)) {
+                               if ($this->driver->isWithin($fileMount['folder']->getIdentifier(), $identifier)) {
                                        $isWithinFilemount = TRUE;
                                        break;
                                }
@@ -633,7 +635,7 @@ class ResourceStorage {
                }
                // Check 5: "File permissions" of the driver (only when file isn't marked as missing)
                if (!$isMissing) {
-                       $filePermissions = $this->driver->getFilePermissions($file);
+                       $filePermissions = $this->driver->getPermissions($file->getIdentifier());
                        if ($isReadCheck && !$filePermissions['r']) {
                                return FALSE;
                        }
@@ -686,7 +688,7 @@ class ResourceStorage {
                        return FALSE;
                }
                // Check 4: "Folder permissions" of the driver
-               $folderPermissions = $this->driver->getFolderPermissions($folder);
+               $folderPermissions = $this->driver->getPermissions($folder->getIdentifier());
                if ($isReadCheck && !$folderPermissions['r']) {
                        return FALSE;
                }
@@ -1096,7 +1098,7 @@ class ResourceStorage {
                $this->assureFileAddPermissions($localFilePath, $targetFolder, $targetFileName);
                $targetFolder = $targetFolder ?: $this->getDefaultFolder();
                $targetFileName = $targetFileName ?: PathUtility::basename($localFilePath);
-               if ($conflictMode === 'cancel' && $this->driver->fileExistsInFolder($targetFileName, $targetFolder)) {
+               if ($conflictMode === 'cancel' && $this->driver->fileExistsInFolder($targetFileName, $targetFolder->getIdentifier())) {
                        throw new Exception\ExistingTargetFileNameException('File "' . $targetFileName . '" already exists in folder ' . $targetFolder->getIdentifier(), 1322121068);
                } elseif ($conflictMode === 'changeName') {
                        $targetFileName = $this->getUniqueName($targetFolder, $targetFileName);
@@ -1105,7 +1107,8 @@ class ResourceStorage {
                // so just use the name as is in that case
                $this->emitPreFileAddSignal($targetFileName, $targetFolder);
 
-               $file = $this->driver->addFile($localFilePath, $targetFolder, $targetFileName);
+               $fileIdentifier = $this->driver->addFile($localFilePath, $targetFolder->getIdentifier(), $targetFileName);
+               $file = ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($this->getUid(), $fileIdentifier);
 
                $this->emitPostFileAddSignal($file, $targetFolder);
 
@@ -1125,11 +1128,10 @@ class ResourceStorage {
                if (!file_exists($localFilePath)) {
                        throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1319552745);
                }
-               $file = $this->driver->addFile($localFilePath, $this->getProcessingFolder(), $processedFile->getName());
-               if ($file instanceof File) {
-                       $file->setIndexable(FALSE);
-               }
-               return $file;
+               $fileIdentifier = $this->driver->addFile($localFilePath, $this->getProcessingFolder()->getIdentifier(), $processedFile->getName());
+               // @todo check if we have to update the processed file other then the identifier
+               $processedFile->setIdentifier($fileIdentifier);
+               return $processedFile;
        }
 
        /**
@@ -1188,7 +1190,7 @@ class ResourceStorage {
                        $this->emitPreGeneratePublicUrl($resourceObject, $relativeToCurrentScript, array('publicUrl' => &$publicUrl));
                        // If slot did not handle the signal, use the default way to determine public URL
                        if ($publicUrl === NULL) {
-                               $publicUrl = $this->driver->getPublicUrl($resourceObject, $relativeToCurrentScript);
+                               $publicUrl = $this->driver->getPublicUrl($resourceObject->getIdentifier(), $relativeToCurrentScript);
                        }
                }
                return $publicUrl;
@@ -1221,10 +1223,7 @@ class ResourceStorage {
         * @return string Path to local file (either original or copied to some temporary local location)
         */
        public function getFileForLocalProcessing(FileInterface $fileObject, $writable = TRUE) {
-               $filePath = $this->driver->getFileForLocalProcessing($fileObject, $writable);
-               // @todo: shouldn't this go in the driver? this function is called from the indexing service
-               // @todo: and recursively calls itself over and over again, this is left out for now with getModificationTime()
-               // touch($filePath, $fileObject->getModificationTime());
+               $filePath = $this->driver->getFileForLocalProcessing($fileObject->getIdentifier(), $writable);
                return $filePath;
        }
 
@@ -1250,7 +1249,7 @@ class ResourceStorage {
         * @internal
         */
        public function getFileInfo(FileInterface $fileObject) {
-               return $this->driver->getFileInfo($fileObject);
+               return $this->getFileInfoByIdentifier($fileObject->getIdentifier());
        }
 
        /**
@@ -1307,8 +1306,9 @@ class ResourceStorage {
         * @return string
         */
        public function getFolderIdentifierFromFileIdentifier($fileIdentifier) {
-               return $this->driver->getFolderIdentifierForFile($fileIdentifier);
+               return $this->driver->getParentFolderIdentifierOfIdentifier($fileIdentifier);
        }
+
        /**
         * Returns a list of files in a given path, filtered by some custom filter methods.
         *
@@ -1324,21 +1324,7 @@ class ResourceStorage {
         */
        public function getFileList($path, $start = 0, $numberOfItems = 0, $useFilters = TRUE, $loadIndexRecords = TRUE, $recursive = FALSE) {
                GeneralUtility::logDeprecatedFunction();
-               // This also checks for read permissions on folder
-               $folder = $this->getFolder($path);
-               $rows = array();
-               if ($loadIndexRecords) {
-                       $rows = $this->getFileIndexRepository()->findByFolder($folder);
-               }
-               $filters = $useFilters == TRUE ? $this->fileAndFolderNameFilters : array();
-               $items = $this->driver->getFileList($path, $start, $numberOfItems, $filters, $rows, $recursive);
-
-               // We should not sort when fetching a recursive list, as these are indexed numerically
-               if ($recursive === FALSE) {
-                       uksort($items, 'strnatcasecmp');
-               }
-
-               return $items;
+               return $this->getFilesInFolder($this->getFolder($path), $start, $numberOfItems, $useFilters, $recursive);
        }
 
        /**
@@ -1355,7 +1341,7 @@ class ResourceStorage {
                $rows = $this->getFileIndexRepository()->findByFolder($folder);
 
                $filters = $useFilters == TRUE ? $this->fileAndFolderNameFilters : array();
-               $fileIdentifiers = $this->driver->getFileIdentifierListInFolder($folder->getIdentifier(), $recursive, $filters);
+               $fileIdentifiers = array_values($this->driver->getFilesInFolder($folder->getIdentifier(), $start, $maxNumberOfItems, $recursive, $filters));
                $fileIdentifiersCount = count($fileIdentifiers);
                $items = array();
                if ($maxNumberOfItems === 0) {
@@ -1389,9 +1375,22 @@ class ResourceStorage {
         */
        public function getFileIdentifiersInFolder($folderIdentifier, $useFilters = TRUE, $recursive = FALSE) {
                $filters = $useFilters == TRUE ? $this->fileAndFolderNameFilters : array();
-               return $this->driver->getFileIdentifierListInFolder($folderIdentifier, $recursive, $filters);
+               return $this->driver->getFilesInFolder($folderIdentifier, 0, 0, $recursive, $filters);
+       }
+
+       /**
+        * @param string $folderIdentifier
+        * @param boolean $useFilters
+        * @param boolean $recursive
+        *
+        * @return array
+        */
+       public function getFolderIdentifiersInFolder($folderIdentifier, $useFilters = TRUE, $recursive = FALSE) {
+               $filters = $useFilters == TRUE ? $this->fileAndFolderNameFilters : array();
+               return $this->driver->getFoldersInFolder($folderIdentifier, 0, 0, $recursive, $filters);
        }
 
+
        /**
         * Returns TRUE if the specified file exists.
         *
@@ -1400,7 +1399,7 @@ class ResourceStorage {
         */
        public function hasFile($identifier) {
                // Allow if identifier is in processing folder
-               if (!$this->driver->isWithin($this->getProcessingFolder(), $identifier)) {
+               if (!$this->driver->isWithin($this->getProcessingFolder()->getIdentifier(), $identifier)) {
                        $this->assureFolderReadPermission();
                }
                return $this->driver->fileExists($identifier);
@@ -1415,7 +1414,7 @@ class ResourceStorage {
         */
        public function hasFileInFolder($fileName, Folder $folder) {
                $this->assureFolderReadPermission($folder);
-               return $this->driver->fileExistsInFolder($fileName, $folder);
+               return $this->driver->fileExistsInFolder($fileName, $folder->getIdentifier());
        }
 
        /**
@@ -1428,7 +1427,7 @@ class ResourceStorage {
         */
        public function getFileContents($file) {
                $this->assureFileReadPermission($file);
-               return $this->driver->getFileContents($file);
+               return $this->driver->getFileContents($file->getIdentifier());
        }
 
        /**
@@ -1446,7 +1445,7 @@ class ResourceStorage {
                // Check if user is allowed to edit
                $this->assureFileWritePermissions($file);
                // Call driver method to update the file and update file index entry afterwards
-               $result = $this->driver->setFileContents($file, $contents);
+               $result = $this->driver->setFileContents($file->getIdentifier(), $contents);
                $this->getIndexer()->updateIndexEntry($file);
                return $result;
        }
@@ -1465,7 +1464,8 @@ class ResourceStorage {
         */
        public function createFile($fileName, Folder $targetFolderObject) {
                $this->assureFileAddPermissions('', $targetFolderObject, $fileName);
-               return $this->driver->createFile($fileName, $targetFolderObject);
+               $newFileIdentifier = $this->driver->createFile($fileName, $targetFolderObject->getIdentifier());
+               return ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($this->getUid(), $newFileIdentifier);
        }
 
        /**
@@ -1481,7 +1481,7 @@ class ResourceStorage {
 
                $this->emitPreFileDeleteSignal($fileObject);
 
-               $result = $this->driver->deleteFile($fileObject);
+               $result = $this->driver->deleteFile($fileObject->getIdentifier());
                if ($result === FALSE) {
                        throw new Exception\FileOperationErrorException('Deleting the file "' . $fileObject->getIdentifier() . '\' failed.', 1329831691);
                }
@@ -1527,11 +1527,12 @@ class ResourceStorage {
                // Call driver method to create a new file from an existing file object,
                // and return the new file object
                if ($sourceStorage === $this) {
-                       $newFileObject = $this->driver->copyFileWithinStorage($file, $targetFolder, $targetFileName);
+                       $newFileObjectIdentifier = $this->driver->copyFileWithinStorage($file->getIdentifier(), $targetFolder->getIdentifier(), $targetFileName);
                } else {
                        $tempPath = $file->getForLocalProcessing();
-                       $newFileObject = $this->driver->addFile($tempPath, $targetFolder, $targetFileName);
+                       $newFileObjectIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $targetFileName);
                }
+               $newFileObject = ResourceFactory::getInstance()->getFileObjectByStorageAndIdentifier($this->getUid(), $newFileObjectIdentifier);
                $this->emitPostFileCopySignal($file, $targetFolder);
                return $newFileObject;
        }
@@ -1569,15 +1570,15 @@ class ResourceStorage {
                // Call driver method to move the file and update the index entry
                try {
                        if ($sourceStorage === $this) {
-                               $newIdentifier = $this->driver->moveFileWithinStorage($file, $targetFolder, $targetFileName);
+                               $newIdentifier = $this->driver->moveFileWithinStorage($file->getIdentifier(), $targetFolder->getIdentifier(), $targetFileName);
                                if (!$file instanceof AbstractFile) {
                                        throw new \RuntimeException('The given file is not of type AbstractFile.', 1384209025);
                                }
                                $file->updateProperties(array('identifier' => $newIdentifier));
                        } else {
                                $tempPath = $file->getForLocalProcessing();
-                               $newIdentifier = $this->driver->addFileRaw($tempPath, $targetFolder, $targetFileName);
-                               $sourceStorage->driver->deleteFileRaw($file->getIdentifier());
+                               $newIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $targetFileName);
+                               $sourceStorage->driver->deleteFile($file->getIdentifier());
                                $file->updateProperties(array('storage' => $this->getUid(), 'identifier' => $newIdentifier));
                        }
                        $this->getIndexer()->updateIndexEntry($file);
@@ -1610,7 +1611,7 @@ class ResourceStorage {
 
                // Call driver method to rename the file and update the index entry
                try {
-                       $newIdentifier = $this->driver->renameFile($file, $targetFileName);
+                       $newIdentifier = $this->driver->renameFile($file->getIdentifier(), $targetFileName);
                        $file->updateProperties(array('identifier' => $newIdentifier));
                        $this->getIndexer()->updateIndexEntry($file);
                } catch (\RuntimeException $e) {
@@ -1639,9 +1640,8 @@ class ResourceStorage {
                if (!file_exists($localFilePath)) {
                        throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1325842622);
                }
-               // TODO check permissions
                $this->emitPreFileReplaceSignal($file, $localFilePath);
-               $result = $this->driver->replaceFile($file, $localFilePath);
+               $result = $this->driver->replaceFile($file->getIdentifier(), $localFilePath);
                $this->getIndexer()->updateIndexEntry($file);
                $this->emitPostFileReplaceSignal($file, $localFilePath);
                return $result;
@@ -1675,7 +1675,7 @@ class ResourceStorage {
         ********************/
        /**
         * Returns an array with all file objects in a folder and its subfolders, with the file identifiers as keys.
-        *
+        * @todo check if this is a duplicate
         * @param Folder $folder
         * @return File[]
         */
@@ -1687,7 +1687,7 @@ class ResourceStorage {
                        foreach ($folder->getSubfolders() as $subfolder) {
                                $folderQueue[] = $subfolder;
                        }
-                       foreach ($folder->getFiles() as $file) {
+                       foreach ($folder->getFiles() as $file) { /** @var FileInterface $file */
                                $files[$file->getIdentifier()] = $file;
                        }
                }
@@ -1718,7 +1718,7 @@ class ResourceStorage {
                // Get all file objects now so we are able to update them after moving the folder
                $fileObjects = $this->getAllFileObjectsInFolder($folderToMove);
                if ($sourceStorage === $this) {
-                       $fileMappings = $this->driver->moveFolderWithinStorage($folderToMove, $targetParentFolder, $newFolderName);
+                       $fileMappings = $this->driver->moveFolderWithinStorage($folderToMove->getIdentifier(), $targetParentFolder->getIdentifier(), $newFolderName);
                } else {
                        $fileMappings = $this->moveFolderBetweenStorages($folderToMove, $targetParentFolder, $newFolderName);
                }
@@ -1741,9 +1741,10 @@ class ResourceStorage {
         * @param string $newFolderName
         *
         * @return boolean
+        * @throws \RuntimeException
         */
        protected function moveFolderBetweenStorages(Folder $folderToMove, Folder $targetParentFolder, $newFolderName) {
-               return $this->getDriver()->moveFolderBetweenStorages($folderToMove, $targetParentFolder, $newFolderName);
+               throw new \RuntimeException('Not yet implemented');
        }
 
        /**
@@ -1766,7 +1767,7 @@ class ResourceStorage {
                // that also updates the file object properties
                try {
                        if ($sourceStorage === $this) {
-                               $this->driver->copyFolderWithinStorage($folderToCopy, $targetParentFolder, $newFolderName);
+                               $this->driver->copyFolderWithinStorage($folderToCopy->getIdentifier(), $targetParentFolder->getIdentifier(), $newFolderName);
                                $returnObject = $this->getFolder($targetParentFolder->getSubfolder($newFolderName)->getIdentifier());
                        } else {
                                $this->copyFolderBetweenStorages($folderToCopy, $targetParentFolder, $newFolderName);
@@ -1786,9 +1787,10 @@ class ResourceStorage {
         * @param string $newFolderName
         *
         * @return boolean
+        * @throws \RuntimeException
         */
        protected function copyFolderBetweenStorages(Folder $folderToCopy, Folder $targetParentFolder, $newFolderName) {
-               return $this->getDriver()->copyFolderBetweenStorages($folderToCopy, $targetParentFolder, $newFolderName);
+               throw new \RuntimeException('Not yet implemented');
        }
 
        /**
@@ -1801,7 +1803,6 @@ class ResourceStorage {
         * @return Folder
         */
        public function renameFolder($folderObject, $newName) {
-               // TODO unit tests
 
                // Renaming the folder should check if the parent folder is writable
                // We cannot do this however because we cannot extract the parent folder from a folder currently
@@ -1810,14 +1811,14 @@ class ResourceStorage {
                }
 
                $returnObject = NULL;
-               if ($this->driver->folderExistsInFolder($newName, $folderObject)) {
+               if ($this->driver->folderExistsInFolder($newName, $folderObject->getIdentifier())) {
                        throw new \InvalidArgumentException('The folder ' . $newName . ' already exists in folder ' . $folderObject->getIdentifier(), 1325418870);
                }
 
                $this->emitPreFolderRenameSignal($folderObject, $newName);
 
                $fileObjects = $this->getAllFileObjectsInFolder($folderObject);
-               $fileMappings = $this->driver->renameFolder($folderObject, $newName);
+               $fileMappings = $this->driver->renameFolder($folderObject->getIdentifier(), $newName);
                // Update the identifier of all file objects
                foreach ($fileObjects as $oldIdentifier => $fileObject) {
                        $newIdentifier = $fileMappings[$oldIdentifier];
@@ -1840,7 +1841,7 @@ class ResourceStorage {
         * @return boolean
         */
        public function deleteFolder($folderObject, $deleteRecursively = FALSE) {
-               $isEmpty = $this->driver->isFolderEmpty($folderObject);
+               $isEmpty = $this->driver->isFolderEmpty($folderObject->getIdentifier());
                $this->assureFolderDeletePermission($folderObject, ($deleteRecursively && !$isEmpty));
                if (!$isEmpty && !$deleteRecursively) {
                        throw new \RuntimeException('Could not delete folder "' . $folderObject->getIdentifier() . '" because it is not empty.', 1325952534);
@@ -1848,7 +1849,7 @@ class ResourceStorage {
 
                $this->emitPreFolderDeleteSignal($folderObject);
 
-               $result = $this->driver->deleteFolder($folderObject, $deleteRecursively);
+               $result = $this->driver->deleteFolder($folderObject->getIdentifier(), $deleteRecursively);
 
                $this->emitPostFolderDeleteSignal($folderObject);
 
@@ -1863,44 +1864,64 @@ class ResourceStorage {
         * @param integer $numberOfItems The number of items to list; if not set, return all items
         * @param boolean $useFilters If FALSE, the list is returned without any filtering; otherwise, the filters defined for this storage are used.
         * @return array Information about the folders found.
+        * @deprecated since TYPO3 6.2, will be removed to versions later
         */
        public function getFolderList($path, $start = 0, $numberOfItems = 0, $useFilters = TRUE) {
+               GeneralUtility::logDeprecatedFunction();
                // Permissions are checked in $this->fetchFolderListFromDriver()
                $filters = $useFilters === TRUE ? $this->fileAndFolderNameFilters : array();
                return $this->fetchFolderListFromDriver($path, $start, $numberOfItems, $filters);
        }
 
        /**
+        * @param Folder $folder
+        * @param integer $start
+        * @param integer $maxNumberOfItems
+        * @param boolean $useFilters
+        * @param boolean $recursive
+        *
+        * @return Folder[]
+        */
+       public function getFoldersInFolder(Folder $folder, $start = 0, $maxNumberOfItems = 0, $useFilters = TRUE, $recursive = FALSE) {
+               $filters = $useFilters == TRUE ? $this->fileAndFolderNameFilters : array();
+               $folderIdentifiers = $this->driver->getFoldersInFolder($folder->getIdentifier(), $start, $maxNumberOfItems, $recursive, $filters);
+
+               $processingIdentifier = $this->getProcessingFolder()->getIdentifier();
+               if (isset($folderIdentifiers[$processingIdentifier])) {
+                       unset($folderIdentifiers[$processingIdentifier]);
+               }
+               $folders = array();
+               foreach ($folderIdentifiers as $folderIdentifier) {
+                       $folders[$folderIdentifier] = $this->getFolder($folderIdentifier);
+               }
+               return $folders;
+       }
+
+       /**
         * @param $path
         * @param integer $start
         * @param integer $numberOfItems
         * @param array $folderFilterCallbacks
         * @param boolean $recursive
         * @return array
+        * @deprecated since 6.2, will be removed 2 versions later
         */
        public function fetchFolderListFromDriver($path, $start = 0, $numberOfItems = 0, array $folderFilterCallbacks = array(), $recursive = FALSE) {
+               GeneralUtility::logDeprecatedFunction();
                // This also checks for access to that path and throws exceptions accordingly
-               if ($this->getFolder($path) === NULL) {
+               $parentFolder = $this->getFolder($path);
+               if ($parentFolder === NULL) {
                        return array();
                }
-               $items = $this->driver->getFolderList($path, $start, $numberOfItems, $folderFilterCallbacks, $recursive);
-               if (!empty($items)) {
-                       // Exclude the _processed_ folder, so it won't get indexed etc
-                       // The processed folder might be any sub folder in storage
-                       $processingFolder = $this->getProcessingFolder();
-                       if ($processingFolder) {
-                               $processedFolderIdentifier = $this->processingFolder->getIdentifier();
-                               $processedFolderIdentifier = trim($processedFolderIdentifier, '/');
-                               $processedFolderIdentifierParts = explode('/', $processedFolderIdentifier);
-                               $processedFolderName = array_pop($processedFolderIdentifierParts);
-                               $processedFolderParent = implode('/', $processedFolderIdentifierParts);
-                               if ($processedFolderParent === trim($path, '/') && isset($items[$processedFolderName])) {
-                                       unset($items[$processedFolderName]);
-                               }
-                       }
-                       uksort($items, 'strnatcasecmp');
+               $folders = $this->getFoldersInFolder($parentFolder, $start, $numberOfItems, count($folderFilterCallbacks) > 0, $recursive);
+               $folderInfo = array();
+               foreach ($folders as $folder) {
+                       $folderInfo[$folder->getIdentifier()] = array(
+                               'name' => $folder->getName(),
+                               'identifier' => $folder->getIdentifier()
+                       );
                }
-               return $items;
+               return $folderInfo;
        }
 
        /**
@@ -1923,7 +1944,7 @@ class ResourceStorage {
         */
        public function hasFolderInFolder($folderName, Folder $folder) {
                $this->assureFolderReadPermission($folder);
-               return $this->driver->folderExistsInFolder($folderName, $folder);
+               return $this->driver->folderExistsInFolder($folderName, $folder->getIdentifier());
        }
 
        /**
@@ -1941,24 +1962,14 @@ class ResourceStorage {
        public function createFolder($folderName, Folder $parentFolder = NULL) {
                if ($parentFolder === NULL) {
                        $parentFolder = $this->getRootLevelFolder();
-               }
-               if (!$this->driver->folderExists($parentFolder->getIdentifier())) {
+               } elseif (!$this->driver->folderExists($parentFolder->getIdentifier())) {
                        throw new \InvalidArgumentException('Parent folder "' . $parentFolder->getIdentifier() . '" does not exist.', 1325689164);
                }
                if (!$this->checkFolderActionPermission('add', $parentFolder)) {
                        throw new Exception\InsufficientFolderWritePermissionsException('You are not allowed to create directories in the folder "' . $parentFolder->getIdentifier() . '"', 1323059807);
                }
-               // TODO this only works with hirachical file systems
-               $folderParts = GeneralUtility::trimExplode('/', $folderName, TRUE);
-               foreach ($folderParts as $folder) {
-                       // TODO check if folder creation succeeded
-                       if ($this->hasFolderInFolder($folder, $parentFolder)) {
-                               $parentFolder = $this->driver->getFolderInFolder($folder, $parentFolder);
-                       } else {
-                               $parentFolder = $this->driver->createFolder($folder, $parentFolder);
-                       }
-               }
-               return $parentFolder;
+               $newFolder = $this->getDriver()->createFolder($folderName, $parentFolder->getIdentifier(), TRUE);
+               return $this->getFolder($newFolder);
        }
 
        /**
@@ -1967,21 +1978,17 @@ class ResourceStorage {
         * @return Folder
         */
        public function getDefaultFolder() {
-               return $this->driver->getDefaultFolder();
+               return $this->getFolder($this->driver->getDefaultFolder());
        }
 
        /**
         * @param string $identifier
         *
-        * @throws Exception\NotInMountPointException
-        * @throws Exception\FolderDoesNotExistException
         * @return Folder
         */
        public function getFolder($identifier) {
-               if (!$this->driver->folderExists($identifier)) {
-                       throw new Exception\FolderDoesNotExistException('Folder ' . $identifier . ' does not exist.', 1320575630);
-               }
-               $folder = $this->driver->getFolder($identifier);
+               $data = $this->driver->getFolderInfoByIdentifier($identifier);
+               $folder = ResourceFactory::getInstance()->createFolderObject($this, $data['identifier'], $data['name']);
                $this->assureFolderReadPermission($folder);
 
                return $folder;
@@ -1998,7 +2005,7 @@ class ResourceStorage {
                        $mount = reset($this->fileMounts);
                        return $mount['folder'];
                } else {
-                       return $this->driver->getRootLevelFolder();
+                       return ResourceFactory::getInstance()->createFolderObject($this, $this->driver->getRootLevelFolder(), '');
                }
        }
 
@@ -2264,7 +2271,6 @@ class ResourceStorage {
         * @return string A unique fileName inside $folder, based on $theFile.
         * @see \TYPO3\CMS\Core\Utility\File\BasicFileUtility::getUniqueName()
         */
-       // TODO check if this should be moved back to Folder
        protected function getUniqueName(Folder $folder, $theFile, $dontCheckForUnique = FALSE) {
                static $maxNumber = 99, $uniqueNamePrefix = '';
                // Fetches info about path, name, extention of $theFile
@@ -2279,7 +2285,7 @@ class ResourceStorage {
                // The destinations file
                $theDestFile = $fileInfo['file'];
                // If the file does NOT exist we return this fileName
-               if (!$this->driver->fileExistsInFolder($theDestFile, $folder) || $dontCheckForUnique) {
+               if (!$this->driver->fileExistsInFolder($theDestFile, $folder->getIdentifier()) || $dontCheckForUnique) {
                        return $theDestFile;
                }
                // Well the fileName in its pure form existed. Now we try to append
@@ -2292,7 +2298,6 @@ class ResourceStorage {
                        if ($a <= $maxNumber) {
                                $insert = '_' . sprintf('%02d', $a);
                        } else {
-                               // TODO remove constant 6
                                $insert = '_' . substr(md5(uniqId('')), 0, 6);
                        }
                        $theTestFile = $theTempFileBody . $insert . $theOrigExt;
@@ -2335,13 +2340,6 @@ class ResourceStorage {
        }
 
        /**
-        * @return \TYPO3\CMS\Core\Resource\FileRepository
-        */
-       protected function getFileRepository() {
-               return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
-       }
-
-       /**
         * @return \TYPO3\CMS\Core\Resource\Index\FileIndexRepository
         */
        protected function getFileIndexRepository() {
@@ -2368,7 +2366,7 @@ class ResourceStorage {
                $folderRole = FolderInterface::ROLE_DEFAULT;
 
                if (method_exists($this->driver, 'getRole')) {
-                       $folderRole = $this->driver->getRole($folder);
+                       $folderRole = $this->driver->getRole($folder->getIdentifier());
                }
 
                if ($folder->getIdentifier() === $this->getProcessingFolder()->getIdentifier()) {
@@ -2382,8 +2380,7 @@ class ResourceStorage {
         * Getter function to return the folder where the files can
         * be processed. does not check for access rights here
         *
-        * @todo check if we need to implement "is writable" capability
-        * @return Folder the processing folder, can be empty as well, if the storage doesn't have a processing folder
+        * @return Folder
         */
        public function getProcessingFolder() {
                if (!isset($this->processingFolder)) {
@@ -2391,31 +2388,11 @@ class ResourceStorage {
                        if (!empty($this->storageRecord['processingfolder'])) {
                                $processingFolder = $this->storageRecord['processingfolder'];
                        }
-                       $processingFolder = '/' . trim($processingFolder, '/') . '/';
-                       // this way, we also worry about deeplinked folders like typo3temp/_processed_
                        if ($this->driver->folderExists($processingFolder) === FALSE) {
-                               // TODO: This assumes that we have a hirarchical storage.
-                               // TODO: Recursive creation of folders should go to the driver, so that we can just call $this->driver->createFolder() here.
-                               $processingFolderParts = explode('/', $processingFolder);
-                               $parentFolder = $this->driver->getRootLevelFolder();
-                               foreach ($processingFolderParts as $folderPart) {
-                                       if ($folderPart === '') {
-                                               continue;
-                                       }
-                                       if (!$this->driver->folderExistsInFolder($folderPart, $parentFolder)) {
-                                               $parentFolder = $this->driver->createFolder($folderPart, $parentFolder);
-                                       } else {
-                                               // We do not use the Folder API here to get the subfolder
-                                               // Because permission checks are triggered then, which is not wanted
-                                               // Since the whole method assumes that folders are hirarchical,
-                                               // we can also asume it here to build the subfolder identifier
-                                               // and fetch it directly from the driver.
-                                               $subFolderIdentifier = $parentFolder->getIdentifier() . $folderPart;
-                                               $parentFolder = $this->driver->getFolder($subFolderIdentifier);
-                                       }
-                               }
+                               $processingFolder = $this->createFolder($processingFolder);
                        }
-                       $this->processingFolder = $this->driver->getFolder($processingFolder);
+                       $data = $this->driver->getFolderInfoByIdentifier($processingFolder);
+                       $this->processingFolder = ResourceFactory::getInstance()->createFolderObject($this, $data['identifier'], $data['name']);
                }
                return $this->processingFolder;
        }
index 4ee49b8..fa6311d 100644 (file)
@@ -43,7 +43,7 @@ class FileProcessingService {
        protected $storage;
 
        /**
-        * @var Resource\Driver\AbstractDriver
+        * @var Resource\Driver\DriverInterface
         */
        protected $driver;
 
@@ -64,9 +64,9 @@ class FileProcessingService {
         * Creates this object.
         *
         * @param Resource\ResourceStorage $storage
-        * @param Resource\Driver\AbstractDriver $driver
+        * @param Resource\Driver\DriverInterface $driver
         */
-       public function __construct(Resource\ResourceStorage $storage, Resource\Driver\AbstractDriver $driver) {
+       public function __construct(Resource\ResourceStorage $storage, Resource\Driver\DriverInterface $driver) {
                $this->storage = $storage;
                $this->driver = $driver;
 
index 42a145b..e58706a 100644 (file)
@@ -4,7 +4,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Resource\Driver;
 /***************************************************************
  *  Copyright notice
  *
- *  (c) 2011-2013 Andreas Wolf <andreas.wolf@ikt-werk.de>
+ *  (c) 2013 Steffen Ritter <steffen.ritter@typo3.org>
  *  All rights reserved
  *
  *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -30,7 +30,6 @@ namespace TYPO3\CMS\Core\Tests\Unit\Resource\Driver;
 /**
  * Test case for the abstract driver.
  *
- * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
  */
 class AbstractDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
 
@@ -39,6 +38,11 @@ class AbstractDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCas
         */
        protected $fixture;
 
+
+       public function setUp() {
+               parent::setUp();
+               $this->fixture = $this->createDriverFixture();
+       }
        /**
         * @return \TYPO3\CMS\Core\Resource\Driver\AbstractDriver
         */
@@ -46,80 +50,10 @@ class AbstractDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCas
                return $this->getMockForAbstractClass('TYPO3\\CMS\\Core\\Resource\\Driver\\AbstractDriver', array(), '', FALSE);
        }
 
-       public function filenameValidationDataProvider() {
-               return array(
-                       'all-lowercase filename with extension' => array(
-                               'testfile.txt',
-                               TRUE
-                       ),
-                       'regular filename with mixed case and extension' => array(
-                               'someFilename.jpg',
-                               TRUE
-                       ),
-                       'filename with german umlauts' => array(
-                               'anÜmläütTestfile.jpg',
-                               TRUE
-                       ),
-                       'filename with double extension' => array(
-                               'someCompressedFile.tar.gz',
-                               TRUE
-                       ),
-                       'filename with dash' => array(
-                               'foo-bar',
-                               TRUE
-                       ),
-                       'filename with number' => array(
-                               'some23Number',
-                               TRUE
-                       ),
-                       'filename with whitespace' => array(
-                               'some whitespace',
-                               TRUE
-                       ),
-                       'filename with tab' => array(
-                               'some' . TAB . 'tag',
-                               TRUE
-                       ),
-                       'filename with carriage return' => array(
-                               'some' . CR . 'CarriageReturn',
-                               FALSE
-                       ),
-                       'filename with linefeed' => array(
-                               'some' . LF . 'Linefeed',
-                               FALSE
-                       ),
-                       'filename with leading slash' => array(
-                               '/invalidAsFilename',
-                               FALSE
-                       ),
-                       'filename with null character' => array(
-                               'someFile' . chr(0) . 'name',
-                               FALSE
-                       )
-               );
-       }
-
-       /**
-        * @test
-        * @dataProvider filenameValidationDataProvider
-        */
-       public function filenamesAreCorrectlyValidated($filename, $expectedResult) {
-               $fixture = $this->createDriverFixture(array());
-               $result = $fixture->isValidFilename($filename);
-               $this->assertEquals($expectedResult, $result);
-       }
-
        /**
         * @test
         */
-       public function getFolderCorrectlySetsFolderName() {
-               $identifier = '/someFolder/someSubfolder/';
-               $fixture = $this->createDriverFixture(array());
-               $fixture->setStorage($this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE));
-               $mockedFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
-               $mockedFactory->expects($this->once())->method('createFolderObject')->with($this->anything(), $this->anything(), 'someSubfolder');
-               \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', $mockedFactory);
-               $fixture->getFolder($identifier);
+       public function isCaseSensitiveFileSystemReturnsTrueIfNothingIsConfigured() {
+               $this->assertTrue($this->fixture->isCaseSensitiveFileSystem());
        }
-
 }
index 86c9c47..f9a18f9 100644 (file)
@@ -71,7 +71,7 @@ class DriverRegistryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        public function registerDriverClassThrowsExceptionIfShortnameIsAlreadyTakenByAnotherDriverClass() {
                $this->setExpectedException('InvalidArgumentException', '', 1314979451);
                $className = get_class($this->getMockForAbstractClass('TYPO3\\CMS\\Core\\Resource\\Driver\\AbstractDriver'));
-               $className2 = '\stdClass';
+               $className2 = get_class($this->getMockForAbstractClass('TYPO3\\CMS\\Core\\Resource\\Driver\\DriverInterface'));
                $this->fixture->registerDriverClass($className, 'foobar');
                $this->fixture->registerDriverClass($className2, 'foobar');
        }
index db1cf84..c8bec51 100644 (file)
@@ -39,6 +39,11 @@ use \org\bovigo\vfs\vfsStreamWrapper;
 class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
 
        /**
+        * @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver
+        */
+       protected $localDriver = NULL;
+
+       /**
         * @var array A backup of registered singleton instances
         */
        protected $singletonInstances = array();
@@ -48,19 +53,6 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        static private $testDirs = array();
 
-       public function setUp() {
-               parent::setUp();
-               $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
-               // use a mocked file repository to avoid updating the index when doing property update tests
-               $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository');
-               \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances();
-               \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository', $mockedRepository);
-       }
-
-       public function tearDown() {
-               \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
-               parent::tearDown();
-       }
 
        static public function tearDownAfterClass() {
                foreach (self::$testDirs as $dir) {
@@ -103,26 +95,26 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         *
         * IMPORTANT: Call this only after setting up the virtual file system (with the addTo* methods)!
         *
-        * @param $driverConfiguration
-        * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
+        * @param array $driverConfiguration
         * @param array $mockedDriverMethods
         * @return \TYPO3\CMS\Core\Resource\Driver\LocalDriver
         */
-       protected function createDriverFixture($driverConfiguration, \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject = NULL, $mockedDriverMethods = array()) {
-               $this->initializeVfs();
-               if ($storageObject == NULL) {
-                       $storageObject = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
+       protected function createDriverFixture($driverConfiguration = array(), $mockedDriverMethods = array()) {
+                       // it's important to do that here, so vfsContents could have been set before
+               if (!isset($driverConfiguration['basePath'])) {
+                       $this->initializeVfs();
+                       $driverConfiguration['basePath'] = $this->getMountRootUrl();
                }
+               /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $driver */
                $mockedDriverMethods[] = 'isPathValid';
-               $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
+               $driver = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
                $driver->expects($this->any())
                        ->method('isPathValid')
                        ->will(
                                $this->returnValue(TRUE)
                        );
 
-               $storageObject->setDriver($driver);
-               $driver->setStorage($storageObject);
+               $driver->setStorageUid(5);
                $driver->processConfiguration();
                $driver->initialize();
                return $driver;
@@ -131,36 +123,18 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
        /**
         * @test
         */
-       public function rootLevelFolderIsCreatedWithCorrectArguments() {
-               $mockedMount = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $fixture = $this->createDriverFixture(array('basePath' => $this->getMountRootUrl()), $mockedMount);
-               $mockedFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
-               $mockedFactory->expects($this->once())->method('createFolderObject')->with($this->equalTo($mockedMount), $this->equalTo('/'), $this->equalTo(''));
-               \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', $mockedFactory);
-               $fixture->getRootLevelFolder();
-               \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', new \TYPO3\CMS\Core\Resource\ResourceFactory());
-       }
-
-       /**
-        * @test
-        */
        public function getDefaultFolderReturnsFolderForUserUploadPath() {
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $folder = $fixture->getDefaultFolder();
-               $this->assertStringEndsWith('user_upload/', $folder->getIdentifier());
+               $fixture = $this->createDriverFixture();
+               $folderIdentifier = $fixture->getDefaultFolder();
+               $this->assertEquals('/user_upload/', $folderIdentifier);
        }
 
        /**
         * @test
         */
        public function defaultLevelFolderFolderIsCreatedIfItDoesntExist() {
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fixture->getDefaultFolder();
-               $this->assertFileExists($this->getUrlInMount('/user_upload/'));
+               $fixture = $this->createDriverFixture();
+               $this->assertFileExists($this->getUrlInMount($fixture->getDefaultFolder()));
        }
 
        /**
@@ -172,12 +146,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someSubdir' => array()
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $parentFolder = $fixture->getFolder('/someDir');
-               $folder = $fixture->getFolderInFolder('someSubdir', $parentFolder);
-               $this->assertEquals('/someDir/someSubdir/', $folder->getIdentifier());
+               $fixture = $this->createDriverFixture();
+               $folder = $fixture->getFolderInFolder('someSubdir', '/someDir/');
+               $this->assertEquals('/someDir/someSubdir/', $folder);
        }
 
        /**
@@ -185,11 +156,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function createFolderCreatesFolderOnDisk() {
                $this->addToMount(array('some' => array('folder' => array())));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
-               $fixture->createFolder('path', $mockedFolder);
+               $fixture = $this->createDriverFixture();
+               $fixture->createFolder('path', '/some/folder/');
                $this->assertFileExists($this->getUrlInMount('/some/folder/'));
                $this->assertFileExists($this->getUrlInMount('/some/folder/path'));
        }
@@ -199,15 +167,12 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function createFolderReturnsFolderObject() {
                $this->addToMount(array('some' => array('folder' => array())));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
-               $createdFolder = $fixture->createFolder('path', $mockedFolder);
-               $this->assertEquals('/some/folder/path/', $createdFolder->getIdentifier());
+               $fixture = $this->createDriverFixture();
+               $createdFolder = $fixture->createFolder('path', '/some/folder/');
+               $this->assertEquals('/some/folder/path/', $createdFolder);
        }
 
-       public function createFolderSanitizesFolderNameBeforeCreationDataProvider() {
+       public static function createFolderSanitizesFolderNameBeforeCreationDataProvider() {
                return array(
                        'folder name with NULL character' => array(
                                'some' . chr(0) . 'Folder',
@@ -226,46 +191,25 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function createFolderSanitizesFolderNameBeforeCreation($newFolderName, $expectedFolderName) {
                $this->addToMount(array('some' => array('folder' => array())));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
-               $fixture->createFolder($newFolderName, $mockedFolder);
+               $fixture = $this->createDriverFixture();
+               $fixture->createFolder($newFolderName, '/some/folder/');
                $this->assertFileExists($this->getUrlInMount('/some/folder/' . $expectedFolderName));
        }
 
        /**
         * @test
         */
-       public function driverConfigVerificationFailsIfConfiguredBasePathDoesNotExist() {
-               $this->setExpectedException('TYPO3\\CMS\\Core\\Resource\\Exception\\InvalidConfigurationException', '', 1299233097);
-               $driverConfiguration = array(
-                       'basePath' => vfsStream::url($this->basedir . 'doesntexist/')
-               );
-               $this->assertFalse(file_exists($driverConfiguration['basePath']));
-               \TYPO3\CMS\Core\Resource\Driver\LocalDriver::verifyConfiguration($driverConfiguration);
-       }
-
-       /**
-        * @test
-        */
        public function basePathIsNormalizedWithTrailingSlash() {
-               $driverConfiguration = array(
-                       'basePath' => $this->getMountRootUrl()
-               );
-               $fixture = $this->createDriverFixture($driverConfiguration);
-               $this->assertEquals('/', substr($fixture->getAbsoluteBasePath(), -1));
+               $fixture = $this->createDriverFixture();
+               $this->assertEquals('/', substr($fixture->_call('getAbsoluteBasePath'), -1));
        }
 
        /**
         * @test
         */
        public function noSecondSlashIsAddedIfBasePathAlreadyHasTrailingSlash() {
-               $driverConfiguration = array(
-                       'basePath' => $this->getMountRootUrl()
-               );
-               $fixture = $this->createDriverFixture($driverConfiguration);
-               $this->assertNotEquals('/', substr($fixture->getAbsoluteBasePath(), -2, 1));
+               $fixture = $this->createDriverFixture();
+               $this->assertNotEquals('/', substr($fixture->_call('getAbsoluteBasePath'), -2, 1));
        }
 
        /**
@@ -277,11 +221,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'file1.ext' => 'asdfg'
                        )
                ));
-               $mockedFile = $this->getSimpleFileMock('someFolder/file1.ext');
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $path = $fixture->getAbsolutePath($mockedFile);
+               $fixture = $this->createDriverFixture();
+               $path = $fixture->_call('getAbsolutePath', '/someFolder/file1.ext');
                $this->assertTrue(file_exists($path));
                $this->assertEquals($this->getUrlInMount('/someFolder/file1.ext'), $path);
        }
@@ -290,7 +231,6 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function addFileMovesFileToCorrectLocation() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
                $this->addToMount(array('targetFolder' => array()));
                $this->addToVfs(array(
                        'sourceFolder' => array(
@@ -298,13 +238,11 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        )
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
+                       array(),
                        array('getMimeTypeOfFile')
                );
                $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
-               $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'file');
+               $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'file');
                $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/file')));
        }
 
@@ -312,7 +250,6 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function addFileUsesFilenameIfGiven() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
                $this->addToMount(array('targetFolder' => array()));
                $this->addToVfs(array(
                        'sourceFolder' => array(
@@ -320,13 +257,11 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        )
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
+                       array(),
                        array('getMimeTypeOfFile')
                );
                $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
-               $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'targetFile');
+               $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'targetFile');
                $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/targetFile')));
        }
 
@@ -334,29 +269,20 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function addFileFailsIfFileIsInDriverStorage() {
-               $mockedFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
-               $mockedFolder->expects($this->any())->method('getIdentifier')->will($this->returnValue('/targetFolder/'));
                $this->setExpectedException('InvalidArgumentException', '', 1314778269);
                $this->addToMount(array(
                        'targetFolder' => array(
                                'file' => 'asdf'
                        )
                ));
-               $storageObject = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $storageObject->expects($this->any())->method('getUid')->will($this->returnValue('1'));
-               $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       $storageObject
-               );
-               $fixture->addFile($this->getUrlInMount('/targetFolder/file'), $mockedFolder, 'file');
+               $fixture = $this->createDriverFixture();
+               $fixture->addFile($this->getUrlInMount('/targetFolder/file'), '/targetFolder/', 'file');
        }
 
        /**
         * @test
         */
-       public function addFileReturnsFileObject() {
-               $mockedFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
-               $mockedFolder->expects($this->any())->method('getIdentifier')->will($this->returnValue('/targetFolder/'));
+       public function addFileReturnsFileIdentifier() {
                $this->addToMount(array('targetFolder' => array()));
                $this->addToVfs(array(
                        'sourceFolder' => array(
@@ -364,79 +290,13 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        )
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
+                       array(),
                        array('getMimeTypeOfFile')
                );
                $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
-               $fileObject = $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'file');
-               $this->assertInstanceOf('TYPO3\\CMS\\Core\\Resource\\File', $fileObject);
-               $this->assertEquals('file', $fileObject->getName());
-               $this->assertEquals('/targetFolder/file', $fileObject->getIdentifier());
-       }
-
-       /**
-        * @test
-        */
-       public function addFileRawCreatesCopyOfFile() {
-               $this->addToMount(array('targetFolder' => array()));
-               $this->addToVfs(array(
-                       'sourceFolder' => array(
-                               'file' => 'asdf'
-                       )
-               ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
-               $fileIdentifier = $fixture->addFileRaw($this->getUrl('sourceFolder/file'), $this->getSimpleFolderMock('/targetFolder/'), 'somefile');
-               $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
-               $this->assertTrue(file_exists($this->getUrlInMount('targetFolder/somefile')));
-               $this->assertEquals('/targetFolder/somefile', $fileIdentifier);
-       }
-
-       /**
-        * @test
-        */
-       public function deleteFileRawRemovesFile() {
-               $this->addToMount(array(
-                       'targetFolder' => array(
-                               'file' => 'asdjlkfa'
-                       )
-               ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $this->assertTrue(file_exists($this->getUrlInMount('targetFolder/file')));
-               $fixture->deleteFileRaw('/targetFolder/file');
-               $this->assertFalse(file_exists($this->getUrlInMount('targetFolder/file')));
-       }
-
-       /**
-        * @test
-        */
-       public function replacingFileUpdatesMetadataInFileObject() {
-               $this->addToMount(array(
-                       'targetFolder' => array(
-                               'file' => 'asdjlkfa'
-                       )
-               ));
-               $this->addToVfs(array(
-                       'sourceFolder' => array(
-                               'file' => 'asjdalks'
-                       )
-               ));
-               $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
-                       array('getMimeTypeOfFile')
-               );
-               $mockedFile = $this->getSimpleFileMock('/targetFolder/file', array('updateProperties'));
-               // does not update properties itself but leaves that to the indexer
-               $mockedFile->expects($this->never())->method('updateProperties');
-               $fixture->replaceFile($mockedFile, $this->getUrl('sourceFolder/file'));
+               $fileIdentifier = $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'file');
+               $this->assertEquals('file', basename($fileIdentifier));
+               $this->assertEquals('/targetFolder/file', $fileIdentifier);
        }
 
        /**
@@ -447,9 +307,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'file' => 'asdf',
                        'folder' => array()
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                // Using slashes at the beginning of paths because they will be stored in the DB this way.
                $this->assertTrue($fixture->fileExists('/file'));
                $this->assertTrue($fixture->folderExists('/folder/'));
@@ -461,20 +319,17 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function existenceChecksInFolderWorkForFilesAndFolders() {
-               $mockedFolder = $this->getSimpleFolderMock('/subfolder/');
                $this->addToMount(array(
                        'subfolder' => array(
                                'file' => 'asdf',
                                'folder' => array()
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $this->assertTrue($fixture->fileExistsInFolder('file', $mockedFolder));
-               $this->assertTrue($fixture->folderExistsInFolder('folder', $mockedFolder));
-               $this->assertFalse($fixture->fileExistsInFolder('nonexistingFile', $mockedFolder));
-               $this->assertFalse($fixture->folderExistsInFolder('nonexistingFolder', $mockedFolder));
+               $fixture = $this->createDriverFixture();
+               $this->assertTrue($fixture->fileExistsInFolder('file', '/subfolder/'));
+               $this->assertTrue($fixture->folderExistsInFolder('folder', '/subfolder/'));
+               $this->assertFalse($fixture->fileExistsInFolder('nonexistingFile', '/subfolder/'));
+               $this->assertFalse($fixture->folderExistsInFolder('nonexistingFolder', '/subfolder/'));
        }
 
        /**
@@ -489,15 +344,10 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        )
                ));
                $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl(),
                        'baseUri' => $baseUri
                ));
-               $mockedFile1 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
-               $mockedFile1->expects($this->any())->method('getIdentifier')->will($this->returnValue('/file.ext'));
-               $mockedFile2 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
-               $mockedFile2->expects($this->any())->method('getIdentifier')->will($this->returnValue('/subfolder/file2.ext'));
-               $this->assertEquals($baseUri . '/file.ext', $fixture->getPublicUrl($mockedFile1));
-               $this->assertEquals($baseUri . '/subfolder/file2.ext', $fixture->getPublicUrl($mockedFile2));
+               $this->assertEquals($baseUri . '/file.ext', $fixture->getPublicUrl('/file.ext'));
+               $this->assertEquals($baseUri . '/subfolder/file2.ext', $fixture->getPublicUrl('/subfolder/file2.ext'));
        }
 
        /**
@@ -508,15 +358,11 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'file.ext' => $fileContents
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFile = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
-               $mockedFile->expects($this->any())->method('getIdentifier')->will($this->returnValue('/file.ext'));
-               $this->assertEquals($fileContents, $fixture->getFileContents($mockedFile), 'File contents could not be read');
+               $fixture = $this->createDriverFixture();
+               $this->assertEquals($fileContents, $fixture->getFileContents('/file.ext'), 'File contents could not be read');
                $newFileContents = 'asdfgh';
-               $fixture->setFileContents($mockedFile, $newFileContents);
-               $this->assertEquals($newFileContents, $fixture->getFileContents($mockedFile), 'New file contents could not be read.');
+               $fixture->setFileContents('/file.ext', $newFileContents);
+               $this->assertEquals($newFileContents, $fixture->getFileContents('/file.ext'), 'New file contents could not be read.');
        }
 
        /**
@@ -527,40 +373,30 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'file.ext' => $fileContents
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFile = $this->getSimpleFileMock('/file.ext');
+               $fixture = $this->createDriverFixture();
                $newFileContents = 'asdfgh';
-               $bytesWritten = $fixture->setFileContents($mockedFile, $newFileContents);
+               $bytesWritten = $fixture->setFileContents('/file.ext', $newFileContents);
                $this->assertEquals(strlen($newFileContents), $bytesWritten);
        }
 
        /**
         * @test
-        * @depends existenceChecksWorkForFilesAndFolders
-        * @return \TYPO3\CMS\Core\Resource\Driver\LocalDriver The driver fixture
         */
        public function newFilesCanBeCreated() {
-               $this->addToMount(array(
-                       'someDir' => array()
-               ));
-               /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
-               list($basedir, $fixture) = $this->prepareRealTestEnvironment();
-               mkdir($basedir . '/someDir');
-               $fixture->createFile('testfile.txt', $fixture->getFolder('someDir'));
-               $this->assertTrue($fixture->fileExists('/someDir/testfile.txt'));
-               return $fixture;
+               $fixture = $this->createDriverFixture();
+               $fixture->createFile('testfile.txt', '/');
+               $this->assertTrue($fixture->fileExists('/testfile.txt'));
        }
 
        /**
         * @test
-        * @depends newFilesCanBeCreated
+        *
         */
-       public function createdFilesAreEmpty(\TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture) {
-               $fixture->expects($this->any())->method('isPathValid')->will($this->returnValue(TRUE));
-               $mockedFile = $this->getSimpleFileMock('/someDir/testfile.txt');
-               $fileData = $fixture->getFileContents($mockedFile);
+       public function createdFilesAreEmpty() {
+               $fixture = $this->createDriverFixture();
+               $fixture->createFile('testfile.txt', '/');
+               $this->assertTrue($fixture->fileExists('/testfile.txt'));
+               $fileData = $fixture->getFileContents('/testfile.txt');
                $this->assertEquals(0, strlen($fileData));
        }
 
@@ -584,7 +420,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
                list($basedir, $fixture) = $this->prepareRealTestEnvironment();
                mkdir($basedir . '/someDir');
-               $fixture->createFile('testfile.txt', $fixture->getFolder('/someDir'));
+               $fixture->createFile('testfile.txt', '/someDir');
                $this->assertEquals($testpattern, decoct(fileperms($basedir . '/someDir/testfile.txt') & 0777));
        }
 
@@ -602,9 +438,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'someFileAtRootLevel' => 'foobar'
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
+                       array(),
                        array('getMimeTypeOfFile')
                );
                $subdirFileInfo = $fixture->getFileInfoByIdentifier('/someDir/someFile');
@@ -618,20 +452,16 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function getFileThrowsExceptionIfFileDoesNotExist() {
                $this->setExpectedException('InvalidArgumentException', '', 1314516809);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                $fixture->getFileInfoByIdentifier('/some/file/at/a/random/path');
        }
 
        /**
         * @test
         */
-       public function getFileListReturnsEmptyArrayForEmptyDirectory() {
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fileList = $fixture->getFileList('/');
+       public function getFilesInFolderReturnsEmptyArrayForEmptyDirectory() {
+               $fixture = $this->createDriverFixture();
+               $fileList = $fixture->getFilesInFolder('/');
                $this->assertEmpty($fileList);
        }
 
@@ -646,13 +476,12 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                );
                $this->addToMount($dirStructure);
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
+                       array(),
                                // Mocked because finfo() can not deal with vfs streams and throws warnings
                        array('getMimeTypeOfFile')
                );
-               $fileList = $fixture->getFileList('/');
-               $this->assertEquals(array('file1', 'file2'), array_keys($fileList));
+               $fileList = $fixture->getFilesInFolder('/');
+               $this->assertEquals(array('/file1', '/file2'), array_keys($fileList));
        }
 
        /**
@@ -671,13 +500,12 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                );
                $this->addToMount($dirStructure);
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
+                       array(),
                                // Mocked because finfo() can not deal with vfs streams and throws warnings
                        array('getMimeTypeOfFile')
                );
-               $fileList = $fixture->getFileList('/', 0, 0, array(), array(), TRUE);
-               $this->assertEquals(array('aDir/subdir/file4', 'aDir/file3', 'file1', 'file2'), array_keys($fileList));
+               $fileList = $fixture->getFilesInFolder('/', 0, 0, TRUE);
+               $this->assertEquals(array('/aDir/subdir/file4', '/aDir/file3', '/file1', '/file2'), array_keys($fileList));
        }
 
        /**
@@ -686,16 +514,14 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
        public function getFileListFailsIfDirectoryDoesNotExist() {
                $this->setExpectedException('InvalidArgumentException', '', 1314349666);
                $this->addToMount(array('somefile' => ''));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fixture->getFileList('somedir/');
+               $fixture = $this->createDriverFixture();
+               $fixture->getFilesInFolder('somedir/');
        }
 
        /**
         * @test
         */
-       public function getFileListCallsConfiguredCallbackFunctionWithGivenItemName() {
+       public function getFileInFolderCallsConfiguredCallbackFunctionWithGivenItemName() {
                $dirStructure = array(
                        'file2' => 'fdsa'
                );
@@ -707,12 +533,10 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        )
                );
                $this->addToMount($dirStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                // the callback function will throw an exception used to check if it was called with correct $itemName
                $this->setExpectedException('InvalidArgumentException', '$itemName', 1336159604);
-               $fixture->getFileList('/', 0, 0, $callback);
+               $fixture->getFilesInFolder('/', 0, 0, FALSE, $callback);
        }
 
        /**
@@ -740,8 +564,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                );
                $this->addToMount($dirStructure);
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
+                       array(),
                                // Mocked because finfo() can not deal with vfs streams and throws warnings
                        array('getMimeTypeOfFile')
                );
@@ -751,8 +574,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'filterFilename',
                        ),
                );
-               $fileList = $fixture->getFileList('/', 0, 0, $filterCallbacks);
-               $this->assertNotContains('fileA', array_keys($fileList));
+               $fileList = $fixture->getFilesInFolder('/', 0, 0, FALSE, $filterCallbacks);
+               $this->assertNotContains('/fileA', array_keys($fileList));
        }
 
        /**
@@ -765,11 +588,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'file' => 'asdfg'
                );
                $this->addToMount($dirStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fileList = $fixture->getFolderList('/');
-               $this->assertEquals(array('dir1', 'dir2'), array_keys($fileList));
+               $fixture = $this->createDriverFixture();
+               $fileList = $fixture->getFoldersInFolder('/');
+               $this->assertEquals(array('/dir1/', '/dir2/'), array_keys($fileList));
        }
 
        /**
@@ -782,31 +603,11 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'file1' => ''
                );
                $this->addToMount($dirStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
 
-               $fileList = $fixture->getFolderList('/');
+               $fileList = $fixture->getFoldersInFolder('/');
 
-               $this->assertEquals(array('.someHiddenDir', 'aDir'), array_keys($fileList));
-       }
-
-       /**
-        * @test
-        */
-       public function getFolderListUsesCorrectPathForItems() {
-               $this->addToMount(array(
-                       'dir1' => array(
-                               'subdir1' => array()
-                       )
-               ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $folderList = $fixture->getFolderList('/');
-               $this->assertEquals('/dir1/', $folderList['dir1']['identifier']);
-               $folderList = $fixture->getFolderList('/dir1/');
-               $this->assertEquals('/dir1/subdir1/', $folderList['subdir1']['identifier']);
+               $this->assertEquals(array('/.someHiddenDir/', '/aDir/'), array_keys($fileList));
        }
 
        /**
@@ -821,10 +622,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        '..' => array(),
                        '.' => array()
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fileList = $fixture->getFolderList('/');
+               $fixture = $this->createDriverFixture();
+               $fileList = $fixture->getFoldersInFolder('/');
                $this->assertEmpty($fileList);
        }
 
@@ -837,16 +636,14 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'folderB' => array()
                );
                $this->addToMount($dirStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                $filterCallbacks = array(
                        array(
                                'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
                                'filterFilename',
                        ),
                );
-               $folderList = $fixture->getFolderList('/', 0, 0, $filterCallbacks);
+               $folderList = $fixture->getFoldersInFolder('/', 0, 0, $filterCallbacks);
                $this->assertNotContains('folderA', array_keys($folderList));
        }
 
@@ -855,11 +652,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function getFolderListFailsIfDirectoryDoesNotExist() {
                $this->setExpectedException('InvalidArgumentException', '', 1314349666);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                vfsStream::create(array($this->basedir => array('somefile' => '')));
-               $fixture->getFolderList('somedir/');
+               $fixture->getFoldersInFolder('somedir/');
        }
 
        /**
@@ -869,13 +664,10 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $contents = '68b329da9893e34099c7d8ad5cb9c940';
                $expectedMd5Hash = '8c67dbaf0ba22f2e7fbc26413b86051b';
                $expectedSha1Hash = 'a60cd808ba7a0bcfa37fa7f3fb5998e1b8dbcd9d';
-               $mockedFile = $this->getSimpleFileMock('/hashFile');
                $this->addToMount(array('hashFile' => $contents));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $this->assertEquals($expectedSha1Hash, $fixture->hash($mockedFile, 'sha1'));
-               $this->assertEquals($expectedMd5Hash, $fixture->hash($mockedFile, 'md5'));
+               $fixture = $this->createDriverFixture();
+               $this->assertEquals($expectedSha1Hash, $fixture->hash('/hashFile', 'sha1'));
+               $this->assertEquals($expectedMd5Hash, $fixture->hash('/hashFile', 'md5'));
        }
 
        /**
@@ -883,10 +675,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function hashingWithUnsupportedAlgorithmFails() {
                $this->setExpectedException('InvalidArgumentException', '', 1304964032);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $fixture->hash($this->getSimpleFileMock('/hashFile'), uniqid());
+               $fixture = $this->createDriverFixture();
+               $fixture->hash('/hashFile', uniqid());
        }
 
        /**
@@ -900,13 +690,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someFile' => $fileContents
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ), NULL, array('copyFileToTemporaryPath'));
-               $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
-               // TODO add parameter expectation for $mockedFile as soon as PHPUnit supports object identity matching in parameter expectations
+               $fixture = $this->createDriverFixture(array(), array('copyFileToTemporaryPath'));
                $fixture->expects($this->once())->method('copyFileToTemporaryPath');
-               $fixture->getFileForLocalProcessing($mockedFile);
+               $fixture->getFileForLocalProcessing('/someDir/someFile');
        }
 
        /**
@@ -919,12 +705,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someFile' => $fileContents
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
-               $filePath = $fixture->getFileForLocalProcessing($mockedFile, FALSE);
-               $this->assertEquals($filePath, $this->getMountRootUrl() . 'someDir/someFile');
+               $fixture = $this->createDriverFixture();
+               $filePath = $fixture->getFileForLocalProcessing('/someDir/someFile', FALSE);
+               $this->assertEquals($filePath, $this->getUrlInMount('someDir/someFile'));
        }
 
        /**
@@ -937,11 +720,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someFile' => $fileContents
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
-               $filePath = GeneralUtility::fixWindowsFilePath($fixture->copyFileToTemporaryPath($mockedFile));
+               $fixture = $this->createDriverFixture();
+               $filePath = GeneralUtility::fixWindowsFilePath($fixture->_call('copyFileToTemporaryPath', '/someDir/someFile'));
                $this->assertContains('/typo3temp/', $filePath);
                $this->assertEquals($fileContents, file_get_contents($filePath));
        }
@@ -955,7 +735,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                touch($basedir . '/someFile');
                chmod($basedir . '/someFile', 448);
                clearstatcache();
-               $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFilePermissions($this->getSimpleFileMock('/someFile')));
+               $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getPermissions('/someFile'));
        }
 
        /**
@@ -972,7 +752,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                touch($basedir . '/someForbiddenFile');
                chmod($basedir . '/someForbiddenFile', 0);
                clearstatcache();
-               $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $fixture->getFilePermissions($this->getSimpleFileMock('/someForbiddenFile')));
+               $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $fixture->getPermissions('/someForbiddenFile'));
        }
 
        /**
@@ -984,7 +764,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                mkdir($basedir . '/someFolder');
                chmod($basedir . '/someFolder', 448);
                clearstatcache();
-               $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFolderPermissions($this->getSimpleFolderMock('/someFolder')));
+               $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getPermissions('/someFolder'));
        }
 
        /**
@@ -1001,7 +781,7 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                mkdir($basedir . '/someForbiddenFolder');
                chmod($basedir . '/someForbiddenFolder', 0);
                clearstatcache();
-               $result = $fixture->getFolderPermissions($this->getSimpleFolderMock('/someForbiddenFolder'));
+               $result = $fixture->getPermissions('/someForbiddenFolder');
                // Change permissions back to writable, so the sub-folder can be removed in tearDown
                chmod($basedir . '/someForbiddenFolder', 0777);
                $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $result);
@@ -1065,115 +845,38 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'testfile' => 'asdfg'
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
+               $fixture = $this->createDriverFixture();
                /** @var $fileObject vfsStreamContent */
                $fileObject = vfsStreamWrapper::getRoot()->getChild($this->mountDir)->getChild('testfile');
                // just use an "arbitrary" user here - it is only important that
                $fileObject->chown(vfsStream::OWNER_USER_1);
                $fileObject->chgrp($group);
                $fileObject->chmod($permissions);
-               $this->assertEquals($expectedResult, $fixture->getFilePermissions($this->getSimpleFileMock('/testfile')));
+               $this->assertEquals($expectedResult, $fixture->getPermissions('/testfile'));
        }
 
        /**
         * @test
         */
        public function isWithinRecognizesFilesWithinFolderAndInOtherFolders() {
-               $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ), $mockedStorage);
-               $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/test.jpg'));
-               $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/subFolder/test.jpg'));
-               $this->assertFalse($fixture->isWithin($mockedFolder, '/someFolderWithALongName/test.jpg'));
+               $fixture = $this->createDriverFixture();
+               $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/test.jpg'));
+               $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/subFolder/test.jpg'));
+               $this->assertFalse($fixture->isWithin('/someFolder/', '/someFolderWithALongName/test.jpg'));
        }
 
        /**
         * @test
         */
        public function isWithinAcceptsFileAndFolderObjectsAsContent() {
-               $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ), $mockedStorage);
-               $mockedSubfolder = $this->getSimpleFolderMock('/someFolder/subfolder/');
-               $mockedFile = $this->getSimpleFileMock('/someFolder/test.jpg');
-               $this->assertTrue($fixture->isWithin($mockedFolder, $mockedFile));
-               $this->assertTrue($fixture->isWithin($mockedFolder, $mockedSubfolder));
-       }
-
-       /**
-        * @test
-        */
-       public function isWithinAlwaysReturnsFalseIfFolderIsWithinDifferentStorage() {
-               $mockedStorage1 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $mockedStorage2 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage1, '/someFolder/', 'someFolder');
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ), $mockedStorage2);
-               $fileIdentifier = '/someFolder/test.jpg';
-               $subfolderIdentifier = '/someFolder/subfolder/';
-               $mockedFile = $this->getSimpleFileMock($fileIdentifier);
-               $mockedSubfolder = $this->getSimpleFolderMock($subfolderIdentifier);
-               $this->assertFalse($fixture->isWithin($mockedFolder, $mockedFile));
-               $this->assertFalse($fixture->isWithin($mockedFolder, $fileIdentifier));
-               $this->assertFalse($fixture->isWithin($mockedFolder, $mockedSubfolder));
-               $this->assertFalse($fixture->isWithin($mockedFolder, $subfolderIdentifier));
+               $fixture = $this->createDriverFixture();
+               $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/test.jpg'));
+               $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/subfolder/'));
        }
 
        /**********************************
         * Copy/move file
         **********************************/
-       /**
-        * @param $identifier
-        * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
-        * @return \TYPO3\CMS\Core\Resource\File
-        */
-       protected function mockFileForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
-               if (!$storage) {
-                       $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               }
-               $fileObject = new \TYPO3\CMS\Core\Resource\File(array('identifier' => $identifier, 'name' => basename($identifier), 'storage' => $storage), $storage);
-               return $fileObject;
-       }
-
-       /**
-        * @param $identifier
-        * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
-        * @return \TYPO3\CMS\Core\Resource\Folder
-        */
-       protected function mockFolderForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
-               if (!$storage) {
-                       $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               }
-               $folderObject = new \TYPO3\CMS\Core\Resource\Folder($storage, $identifier, basename($identifier), 0);
-               return $folderObject;
-       }
-
-       /**
-        * Prepares a simple two-folder environment with /someFolder/ and /targetFolder/. /someFolder contains a file with random
-        * contents
-        *
-        * @return array $mockedFolder, $sourceFolder, $fileContents, $fixture
-        */
-       protected function _prepareFolderEnvironmentForMoveTest() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $sourceFolder = $this->getSimpleFolderMock('/someFolder/');
-               $fileContents = uniqid();
-               $this->addToMount(array(
-                       'targetFolder' => array(),
-                       'someFolder' => array('file' => $fileContents)
-               ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               return array($mockedFolder, $sourceFolder, $fileContents, $fixture);
-       }
 
        /**
         * @test
@@ -1185,15 +888,10 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                        'targetFolder' => array()
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
-                               // Mocked because finfo() can not deal with vfs streams and throws warnings
+                       array(),
                        array('getMimeTypeOfFile')
                );
-               $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
-               $targetFolder = $this->mockFolderForCopyingAndMoving('/targetFolder/', $storage);
-               $fixture->copyFileWithinStorage($sourceFile, $targetFolder, 'someFile');
+               $fixture->copyFileWithinStorage('/someFile', '/targetFolder/', 'someFile');
                $this->assertFileEquals($this->getUrlInMount('/someFile'), $this->getUrlInMount('/targetFolder/someFile'));
        }
 
@@ -1201,18 +899,13 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function filesCanBeMovedWithinStorage() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
                $fileContents = uniqid();
                $this->addToMount(array(
                        'targetFolder' => array(),
                        'someFile' => $fileContents
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
+               $fixture = $this->createDriverFixture();
+               $newIdentifier = $fixture->moveFileWithinStorage('/someFile', '/targetFolder/', 'file');
                $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/file')));
                $this->assertFileNotExists($this->getUrlInMount('/someFile'));
                $this->assertEquals('/targetFolder/file', $newIdentifier);
@@ -1222,21 +915,17 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function fileMetadataIsChangedAfterMovingFile() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
                $fileContents = uniqid();
                $this->addToMount(array(
                        'targetFolder' => array(),
                        'someFile' => $fileContents
                ));
                $fixture = $this->createDriverFixture(
-                       array('basePath' => $this->getMountRootUrl()),
-                       NULL,
+                       array(),
                                // Mocked because finfo() can not deal with vfs streams and throws warnings
                        array('getMimeTypeOfFile')
                );
-               $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
+               $newIdentifier = $fixture->moveFileWithinStorage('/someFile', '/targetFolder/', 'file');
                $fileMetadata = $fixture->getFileInfoByIdentifier($newIdentifier);
                $this->assertEquals($newIdentifier, $fileMetadata['identifier']);
        }
@@ -1268,11 +957,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function renamingFilesChangesFilenameOnDisk(array $filesystemStructure, $oldFileIdentifier, $newFileName, $expectedNewIdentifier) {
                $this->addToMount($filesystemStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $file = $this->getSimpleFileMock($oldFileIdentifier);
-               $newIdentifier = $fixture->renameFile($file, $newFileName);
+               $fixture = $this->createDriverFixture();
+               $newIdentifier = $fixture->renameFile($oldFileIdentifier, $newFileName);
                $this->assertFalse($fixture->fileExists($oldFileIdentifier));
                $this->assertTrue($fixture->fileExists($newIdentifier));
                $this->assertEquals($expectedNewIdentifier, $newIdentifier);
@@ -1286,11 +972,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'targetFolder' => array('file' => '', 'newFile' => '')
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $file = $this->getSimpleFileMock('/targetFolder/file');
-               $fixture->renameFile($file, 'newFile');
+               $fixture = $this->createDriverFixture();
+               $fixture->renameFile('/targetFolder/file', 'newFile');
        }
 
        /**
@@ -1327,11 +1010,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         */
        public function renamingFoldersChangesFolderNameOnDisk(array $filesystemStructure, $oldFolderIdentifier, $newFolderName, $expectedNewIdentifier) {
                $this->addToMount($filesystemStructure);
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock($oldFolderIdentifier);
-               $mapping = $fixture->renameFolder($mockedFolder, $newFolderName);
+               $fixture = $this->createDriverFixture();
+               $mapping = $fixture->renameFolder($oldFolderIdentifier, $newFolderName);
                $this->assertFalse($fixture->folderExists($oldFolderIdentifier));
                $this->assertTrue($fixture->folderExists($expectedNewIdentifier));
                $this->assertEquals($expectedNewIdentifier, $mapping[$oldFolderIdentifier]);
@@ -1345,16 +1025,14 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'sourceFolder' => array(
                                'subFolder' => array('file' => $fileContents),
-                               'file' => 'asdfg'
+                               'file2' => 'asdfg'
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
-               $mappingInformation = $fixture->renameFolder($sourceFolder, 'newFolder');
+               $fixture = $this->createDriverFixture();
+               $mappingInformation = $fixture->renameFolder('/sourceFolder/', 'newFolder');
+               $this->isTrue(is_array($mappingInformation));
                $this->assertEquals('/newFolder/', $mappingInformation['/sourceFolder/']);
-               $this->assertEquals('/newFolder/file', $mappingInformation['/sourceFolder/file']);
+               $this->assertEquals('/newFolder/file2', $mappingInformation['/sourceFolder/file2']);
                $this->assertEquals('/newFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
                $this->assertEquals('/newFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
        }
@@ -1369,12 +1047,9 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'file' => 'asdfg'
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ), NULL, array('createIdentifierMap'));
+               $fixture = $this->createDriverFixture(array(), array('createIdentifierMap'));
                $fixture->expects($this->atLeastOnce())->method('createIdentifierMap')->will($this->throwException(new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException()));
-               $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
-               $fixture->renameFolder($sourceFolder, 'newFolder');
+               $fixture->renameFolder('/sourceFolder/', 'newFolder');
                $this->assertFileExists($this->getUrlInMount('/sourceFolder/file'));
        }
 
@@ -1386,11 +1061,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                $this->addToMount(array(
                        'emptyFolder' => array()
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/emptyFolder/');
-               $this->assertTrue($fixture->isFolderEmpty($mockedFolder));
+               $fixture = $this->createDriverFixture();
+               $this->assertTrue($fixture->isFolderEmpty('/emptyFolder/'));
                return $fixture;
        }
 
@@ -1403,11 +1075,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someFile' => ''
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/folderWithFile/');
-               $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
+               $fixture = $this->createDriverFixture();
+               $this->assertFalse($fixture->isFolderEmpty('/folderWithFile/'));
        }
 
        /**
@@ -1419,11 +1088,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'someFolder' => array()
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $mockedFolder = $this->getSimpleFolderMock('/folderWithSubfolder/');
-               $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
+               $fixture = $this->createDriverFixture();
+               $this->assertFalse($fixture->isFolderEmpty('/folderWithSubfolder/'));
        }
 
        /**********************************
@@ -1433,12 +1099,19 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function foldersCanBeMovedWithinStorage() {
+               $fileContents =  uniqid();
+               $this->addToMount(array(
+                       'sourceFolder' => array(
+                               'file' => $fileContents,
+                       ),
+                       'targetFolder' => array(),
+               ));
+               $fixture = $this->createDriverFixture();
                /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
-               list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
-               $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'someFolder');
+               $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'someFolder');
                $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/someFolder/')));
                $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/someFolder/file')));
-               $this->assertFileNotExists($this->getUrlInMount('/someFile'));
+               $this->assertFileNotExists($this->getUrlInMount('/sourceFolder'));
        }
 
        /**
@@ -1453,12 +1126,8 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
                                'file' => 'asdfg'
                        )
                ));
-               $fixture = $this->createDriverFixture(array(
-                       'basePath' => $this->getMountRootUrl()
-               ));
-               $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
-               $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $mappingInformation = $fixture->moveFolderWithinStorage($sourceFolder, $targetFolder, 'sourceFolder');
+               $fixture = $this->createDriverFixture();
+               $mappingInformation = $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'sourceFolder');
                $this->assertEquals('/targetFolder/sourceFolder/file', $mappingInformation['/sourceFolder/file']);
                $this->assertEquals('/targetFolder/sourceFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
                $this->assertEquals('/targetFolder/sourceFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
@@ -1468,9 +1137,14 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function folderCanBeRenamedWhenMoving() {
-               /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
-               list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
-               $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'newFolder');
+               $this->addToMount(array(
+                       'sourceFolder' => array(
+                               'file' => uniqid(),
+                       ),
+                       'targetFolder' => array(),
+               ));
+               $fixture = $this->createDriverFixture();
+               $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolder');
                $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/newFolder/')));
        }
 
@@ -1478,86 +1152,41 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
         * @test
         */
        public function copyFolderWithinStorageCopiesSingleFileToNewFolderName() {
-               $vfsBasedir = uniqid('base-');
-               $vfsStructure = array(
+               $this->addToMount(array(
                        'sourceFolder' => array(
                                'file' => uniqid(),
                        ),
                        'targetFolder' => array(),
-               );
-               vfsStream::setup($vfsBasedir);
-               vfsStream::create($vfsStructure);
-               /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject $fixture */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('getAbsolutePath', 'getAbsoluteBasePath'), array(), '', FALSE);
-               $fixture->expects($this->any())
-                       ->method('getAbsolutePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/sourceFolder/'));
-               $fixture->expects($this->any())
-                       ->method('getAbsoluteBasePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/'));
-               $sourceFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock->expects($this->any())->method('getIdentifier')->will($this->returnValue('targetFolder'));
-               $fixture->copyFolderWithinStorage($sourceFolderMock, $targetFolderMock, 'newFolderName');
-               $this->assertTrue(is_file('vfs://' . $vfsBasedir . '/targetFolder/newFolderName/file'));
+               ));
+               $fixture = $this->createDriverFixture();
+               $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
+               $this->assertTrue(is_file($this->getUrlInMount('/targetFolder/newFolderName/file')));
        }
 
        /**
         * @test
         */
        public function copyFolderWithinStorageCopiesSingleSubFolderToNewFolderName() {
-               $vfsBasedir = uniqid('base-');
-               $vfsStructure = array(
-                       'sourceFolder' => array(
-                               'subFolder' => array(),
-                       ),
-                       'targetFolder' => array(),
-               );
-               vfsStream::setup($vfsBasedir);
-               vfsStream::create($vfsStructure);
-               /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject $fixture */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('getAbsolutePath', 'getAbsoluteBasePath'), array(), '', FALSE);
-               $fixture->expects($this->any())
-                       ->method('getAbsolutePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/sourceFolder/'));
-               $fixture->expects($this->any())
-                       ->method('getAbsoluteBasePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/'));
-               $sourceFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock->expects($this->any())->method('getIdentifier')->will($this->returnValue('targetFolder'));
-               $fixture->copyFolderWithinStorage($sourceFolderMock, $targetFolderMock, 'newFolderName');
-               $this->assertTrue(is_dir('vfs://' . $vfsBasedir . '/targetFolder/newFolderName/subFolder'));
+               list($basePath, $fixture) = $this->prepareRealTestEnvironment();
+               GeneralUtility::mkdir_deep($basePath, '/sourceFolder/subFolder');
+               GeneralUtility::mkdir_deep($basePath, '/targetFolder');
+
+               $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
+               $this->isTrue(is_dir($basePath . '/targetFolder/newFolderName/subFolder'));
        }
 
        /**
         * @test
         */
        public function copyFolderWithinStorageCopiesFileInSingleSubFolderToNewFolderName() {
-               $vfsBasedir = uniqid('base-');
-               $vfsStructure = array(
-                       'sourceFolder' => array(
-                               'subFolder' => array(
-                                       'file' => uniqid(),
-                               ),
-                       ),
-                       'targetFolder' => array(),
-               );
-               vfsStream::setup($vfsBasedir);
-               vfsStream::create($vfsStructure);
-               /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject $fixture */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('getAbsolutePath', 'getAbsoluteBasePath'), array(), '', FALSE);
-               $fixture->expects($this->any())
-                       ->method('getAbsolutePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/sourceFolder/'));
-               $fixture->expects($this->any())
-                       ->method('getAbsoluteBasePath')
-                       ->will($this->returnValue('vfs://' . $vfsBasedir . '/'));
-               $sourceFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock = $this->getMock('TYPO3\CMS\Core\Resource\Folder', array(), array(), '', FALSE);
-               $targetFolderMock->expects($this->any())->method('getIdentifier')->will($this->returnValue('targetFolder'));
-               $fixture->copyFolderWithinStorage($sourceFolderMock, $targetFolderMock, 'newFolderName');
-               $this->assertTrue(is_file('vfs://' . $vfsBasedir . '/targetFolder/newFolderName/subFolder/file'));
+               list($basePath, $fixture) = $this->prepareRealTestEnvironment();
+               GeneralUtility::mkdir_deep($basePath, '/sourceFolder/subFolder');
+               GeneralUtility::mkdir_deep($basePath, '/targetFolder');
+               file_put_contents($basePath . '/sourceFolder/subFolder/file', uniqid());
+               GeneralUtility::fixPermissions($basePath . '/sourceFolder/subFolder/file');
+
+               $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
+               $this->assertTrue(is_file($basePath . '/targetFolder/newFolderName/subFolder/file'));
        }
 
 }
index 3c6dbb9..ab92afd 100644 (file)
@@ -68,7 +68,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
         */
        protected function prepareFixture($configuration, $mockPermissionChecks = FALSE, $driverObject = NULL, array $storageRecord = array()) {
                $permissionMethods = array('assureFileAddPermissions', 'checkFolderActionPermission', 'checkFileActionPermission', 'checkUserActionPermission', 'checkFileExtensionPermission', 'isWithinFileMountBoundaries');
-               $mockedMethods = NULL;
+               $mockedMethods = array();
                $configuration = $this->convertConfigurationArrayToFlexformXml($configuration);
                $overruleArray = array('configuration' => $configuration);
                \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($storageRecord, $overruleArray);
@@ -79,13 +79,13 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                if ($mockPermissionChecks) {
                        $mockedMethods = $permissionMethods;
                }
-               if ($mockedMethods === NULL) {
-                       $this->fixture = new \TYPO3\CMS\Core\Resource\ResourceStorage($driverObject, $storageRecord);
-               } else {
-                       $this->fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', $mockedMethods, array($driverObject, $storageRecord));
-                       foreach ($permissionMethods as $method) {
-                               $this->fixture->expects($this->any())->method($method)->will($this->returnValue(TRUE));
-                       }
+               $mockedMethods[] = 'getIndexer';
+
+
+               $this->fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', $mockedMethods, array($driverObject, $storageRecord));
+               $this->fixture->expects($this->any())->method('getIndexer')->will($this->returnValue($this->getMock('TYPO3\CMS\Core\Resource\Index\Indexer', array(), array(), '', FALSE)));
+               foreach ($permissionMethods as $method) {
+                       $this->fixture->expects($this->any())->method($method)->will($this->returnValue(TRUE));
                }
        }
 
@@ -133,7 +133,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                        $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
                }
                $storageObject->setDriver($driver);
-               $driver->setStorage($storageObject);
+               $driver->setStorageUid(6);
                $driver->processConfiguration();
                $driver->initialize();
                return $driver;
@@ -231,51 +231,6 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
        /**
         * @test
         */
-       public function addFileCallsDriverWithCorrectArguments() {
-               $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $this->addToMount(array(
-                       'targetFolder' => array(),
-                       'file.ext' => 'ajslkd'
-               ));
-               $this->initializeVfs();
-               $localFilePath = $this->getUrlInMount('file.ext');
-               $this->prepareFixture(array(), TRUE);
-               /** @var $file \TYPO3\CMS\Core\Resource\FileInterface */
-               $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileInterface', array(), array(), '', FALSE);
-               /** @var $driver \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
-               $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('addFile'), array(array('basePath' => $this->getUrlInMount('targetFolder/'))));
-               $driver->expects($this->once())->method('addFile')->with($this->equalTo($localFilePath), $this->anything(), $this->equalTo('file.ext'))->will($this->returnValue($file));
-               $this->fixture->setDriver($driver);
-               $this->fixture->addFile($localFilePath, $mockedFolder);
-       }
-
-       /**
-        * @test
-        */
-       public function addFileChangesFilenameIfFileExists() {
-               $mockedFolder = $this->getSimpleFolderMock('/');
-               $this->addToMount(array(
-                       'targetFolder' => array(
-                               'file.ext' => 'asdf',
-                               'file_01.ext' => 'asjdlkajs'
-                       ),
-                       'file.ext' => 'ajslkd'
-               ));
-               $this->initializeVfs();
-               $this->prepareFixture(array(), TRUE);
-               /** @var $file \TYPO3\CMS\Core\Resource\FileInterface */
-               $file = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileInterface', array(), array(), '', FALSE);
-               /** @var $driver \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
-               $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('addFile', 'fileExistsInFolder'), array(array('basePath' => $this->getUrlInMount('targetFolder/'))));
-               $driver->expects($this->once())->method('addFile')->with($this->anything(), $this->anything(), $this->equalTo('file_02.ext'))->will($this->returnValue($file));
-               $driver->expects($this->exactly(3))->method('fileExistsInFolder')->will($this->onConsecutiveCalls($this->returnValue(TRUE), $this->returnValue(TRUE), $this->returnValue(FALSE)));
-               $this->fixture->setDriver($driver);
-               $this->fixture->addFile($this->getUrlInMount('file.ext'), $mockedFolder);
-       }
-
-       /**
-        * @test
-        */
        public function getPublicUrlReturnsNullIfStorageIsNotOnline() {
                /** @var $driver \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
                $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array(), array(array('basePath' => $this->getMountRootUrl())));
@@ -323,7 +278,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
         */
        public function checkFolderPermissionsRespectsFilesystemPermissions($action, $permissionsFromDriver, $expectedResult) {
                $mockedDriver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver');
-               $mockedDriver->expects($this->any())->method('getFolderPermissions')->will($this->returnValue($permissionsFromDriver));
+               $mockedDriver->expects($this->any())->method('getPermissions')->will($this->returnValue($permissionsFromDriver));
                $mockedFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
                        // Let all other checks pass
                /** @var $fixture \TYPO3\CMS\Core\Resource\ResourceStorage */
@@ -453,7 +408,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
         * @test
         * @group integration
         */
-       public function moveFileCallsDriversRawMethodsWithCorrectArguments() {
+       public function moveFileCallsDriversMethodsWithCorrectArguments() {
                $localFilePath = '/path/to/localFile';
                $sourceFileIdentifier = '/sourceFile.ext';
                $fileInfoDummy = array(
@@ -471,7 +426,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                $this->initializeVfs();
                $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
                $sourceDriver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver');
-               $sourceDriver->expects($this->once())->method('deleteFileRaw')->with($this->equalTo($sourceFileIdentifier));
+               $sourceDriver->expects($this->once())->method('deleteFile')->with($this->equalTo($sourceFileIdentifier));
                $configuration = $this->convertConfigurationArrayToFlexformXml(array());
                $sourceStorage = new \TYPO3\CMS\Core\Resource\ResourceStorage($sourceDriver, array('configuration' => $configuration));
                $sourceFile = $this->getSimpleFileMock($sourceFileIdentifier);
@@ -482,7 +437,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                /** @var $driver \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
                $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array(), array(array('basePath' => $this->getMountRootUrl())));
                $driver->expects($this->once())->method('getFileInfoByIdentifier')->will($this->returnValue($fileInfoDummy));
-               $driver->expects($this->once())->method('addFileRaw')->with($localFilePath, $targetFolder, $this->equalTo('file.ext'))->will($this->returnValue('/targetFolder/file.ext'));
+               $driver->expects($this->once())->method('addFile')->with($localFilePath, '/targetFolder/', $this->equalTo('file.ext'))->will($this->returnValue('/targetFolder/file.ext'));
                /** @var $fixture \TYPO3\CMS\Core\Resource\ResourceStorage */
                $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array('assureFileMovePermissions'), array($driver, array('configuration' => $configuration)));
                $fixture->moveFile($sourceFile, $targetFolder, 'file.ext');
@@ -492,31 +447,6 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
         * @test
         * @group integration
         */
-       public function copyFileCallsDriversRawMethodsWithCorrectArguments() {
-               $localFilePath = '/path/to/localFile';
-               $sourceFileIdentifier = '/sourceFile.ext';
-               $this->addToMount(array(
-                       'targetFolder' => array()
-               ));
-               $this->initializeVfs();
-               $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
-               $storageConfiguration = $this->convertConfigurationArrayToFlexformXml(array());
-               $sourceStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               $sourceFile = $this->getSimpleFileMock($sourceFileIdentifier);
-               $sourceFile->expects($this->once())->method('getForLocalProcessing')->will($this->returnValue($localFilePath));
-               $sourceFile->expects($this->any())->method('getStorage')->will($this->returnValue($sourceStorage));
-               /** @var $driver \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
-               $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array(), array(array('basePath' => $this->getMountRootUrl())));
-               $driver->expects($this->once())->method('addFile')->with($localFilePath, $targetFolder, $this->equalTo('file.ext'));
-               /** @var $fixture \TYPO3\CMS\Core\Resource\ResourceStorage */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array('assureFileCopyPermissions'), array($driver, array('configuration' => $storageConfiguration)));
-               $fixture->copyFile($sourceFile, $targetFolder, 'file.ext');
-       }
-
-       /**
-        * @test
-        * @group integration
-        */
        public function storageUsesInjectedFilemountsToCheckForMountBoundaries() {
                $mockedFile = $this->getSimpleFileMock('/mountFolder/file');
                $this->addToMount(array(
@@ -532,42 +462,6 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                $this->fixture->isWithinFileMountBoundaries($mockedFile);
        }
 
-       /**
-        * This test is also valid for folders
-        *
-        * @test
-        */
-       public function getFileListReturnsFilesInCorrectOrder() {
-               $fileList = array(
-                       'file10' => '',
-                       'file2' => '',
-                       'File' => '',
-                       'fail' => ''
-               );
-               $this->prepareFixture(array(), TRUE);
-               $driver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), $this->fixture, array('getFileList'));
-               $driver->expects($this->once())->method('getFileList')->will($this->returnValue($fileList));
-               $fileList = $this->fixture->getFileList('/');
-               $this->assertEquals(array('fail', 'File', 'file2', 'file10'), array_keys($fileList));
-       }
-
-       /**
-        * @test
-        */
-       public function getFileListIgnoresCasingWhenSortingFilenames() {
-               $fileList = array(
-                       'aFile' => 'dfsdg',
-                       'zFile' => 'werw',
-                       'BFile' => 'asd',
-                       '12345' => 'fdsa',
-                       'IMG_1234.jpg' => 'asdf'
-               );
-               $this->prepareFixture(array(), TRUE);
-               $driver = $this->createDriverMock(array(), $this->fixture, array('getFileList'));
-               $driver->expects($this->once())->method('getFileList')->will($this->returnValue($fileList));
-               $fileList = $this->fixture->getFileList('/');
-               $this->assertEquals(array('12345', 'aFile', 'BFile', 'IMG_1234.jpg', 'zFile'), array_keys($fileList));
-       }
 
        /**
         * @test
@@ -606,7 +500,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                $mockedParentFolder = $this->getSimpleFolderMock('/someFolder/');
                $this->prepareFixture(array(), TRUE);
                $mockedDriver = $this->createDriverMock(array(), $this->fixture);
-               $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('newFolder'), $this->equalTo($mockedParentFolder))->will($this->returnValue(TRUE));
+               $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('newFolder'), $this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
                $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
                $this->fixture->createFolder('newFolder', $mockedParentFolder);
        }
@@ -628,24 +522,10 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
        /**
         * @test
         */
-       public function createFolderIgnoresLeadingAndTrailingSlashesWithFoldername() {
-               $mockedParentFolder = $this->getSimpleFolderMock('/someFolder/');
-               $this->prepareFixture(array(), TRUE);
-               $mockedDriver = $this->createDriverMock(array(), $this->fixture);
-               $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
-               $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('subFolder'));
-               $this->fixture->createFolder('/subFolder/', $mockedParentFolder);
-       }
-
-       /**
-        * @test
-        */
        public function createFolderUsesRootFolderAsParentFolderIfNotGiven() {
-               $mockedRootFolder = $this->getSimpleFolderMock('/');
                $this->prepareFixture(array(), TRUE);
                $mockedDriver = $this->createDriverMock(array(), $this->fixture);
-               $mockedDriver->expects($this->once())->method('getRootLevelFolder')->with()->will($this->returnValue($mockedRootFolder));
-               $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/'))->will($this->returnValue(TRUE));
+               $mockedDriver->expects($this->once())->method('getRootLevelFolder')->with()->will($this->returnValue('/'));
                $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('someFolder'));
                $this->fixture->createFolder('someFolder');
        }
@@ -691,33 +571,6 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
        /**
         * @test
         */
-       public function getFileListHandsOverRecursiveFALSEifNotExplicitlySet() {
-               $this->prepareFixture(array(), TRUE);
-               $driver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), $this->fixture, array('getFileList'));
-               $driver->expects($this->once())
-                       ->method('getFileList')
-                       ->with($this->anything(), $this->anything(), $this->anything(), $this->anything(), $this->anything(), FALSE)
-                       ->will($this->returnValue(array()));
-               $this->fixture->getFileList('/');
-       }
-
-       /**
-        * @test
-        */
-       public function getFileListHandsOverRecursiveTRUEifSet() {
-
-               $this->prepareFixture(array(), TRUE);
-               $driver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), $this->fixture, array('getFileList'));
-               $driver->expects($this->once())
-                       ->method('getFileList')
-                       ->with($this->anything(), $this->anything(), $this->anything(), $this->anything(), $this->anything(), TRUE)
-                       ->will($this->returnValue(array()));
-               $this->fixture->getFileList('/', 0, 0, TRUE, TRUE, TRUE);
-       }
-
-       /**
-        * @test
-        */
        public function getRoleReturnsDefaultForRegularFolders() {
                $folderIdentifier = uniqid();
                $this->addToMount(array(
@@ -730,119 +583,4 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                $this->assertSame(\TYPO3\CMS\Core\Resource\FolderInterface::ROLE_DEFAULT, $role);
        }
 
-       /**
-        * @test
-        */
-       public function getRoleReturnsCorrectValueForDefaultProcessingFolder() {
-               $this->prepareFixture(array());
-
-               $role = $this->fixture->getRole($this->getSimpleFolderMock('/' . ResourceStorage::DEFAULT_ProcessingFolder . '/'));
-
-               $this->assertSame(\TYPO3\CMS\Core\Resource\FolderInterface::ROLE_PROCESSING, $role);
-       }
-
-       /**
-        * @test
-        */
-       public function getRoleReturnsCorrectValueForConfiguredProcessingFolder() {
-               $folderIdentifier = uniqid();
-               $this->addToMount(array(
-                       $folderIdentifier => array()
-               ));
-               $this->prepareFixture(array(), FALSE, NULL, array('processingfolder' => '/' . $folderIdentifier . '/'));
-
-               $role = $this->fixture->getRole($this->getSimpleFolderMock('/' . $folderIdentifier . '/'));
-
-               $this->assertSame(\TYPO3\CMS\Core\Resource\FolderInterface::ROLE_PROCESSING, $role);
-       }
-
-       /**
-        * Data provider for fetchFolderListFromDriverReturnsFolderWithoutProcessedFolder function
-        */
-       public function fetchFolderListFromDriverReturnsFolderWithoutProcessedFolderDataProvider() {
-               return array(
-                       'Empty folderList returned' => array(
-                               'path' => '/',
-                               'processingFolder' => '_processed_',
-                               'folderList' => array(),
-                               'expectedItems' => array()
-                       ),
-                       'Empty _processed_ folder' => array(
-                               'path' => '/',
-                               'processingFolder' => '',
-                               'folderList' => array(
-                                       '_processed_' => array(),
-                                       '_temp_' => array(),
-                                       'user_upload' => array()
-                               ),
-                               'expectedItems' => array(
-                                       'user_upload' => array(),
-                                       '_temp_' => array()
-                               )
-                       ),
-                       '_processed_ folder not in folder list' => array(
-                               'path' => '/',
-                               'processingFolder' => '_processed_',
-                               'folderList' => array(
-                                       '_temp_' => array()
-                               ),
-                               'expectedItems' => array(
-                                       '_temp_' => array()
-                               )
-                       ),
-                       '_processed_ folder on root level' => array(
-                               'path' => '/',
-                               'processingFolder' => '_processed_',
-                               'folderList' => array(
-                                       '_processed_' => array(),
-                                       '_temp_' => array(),
-                                       'user_upload' => array()
-                               ),
-                               'expectedItems' => array(
-                                       'user_upload' => array(),
-                                       '_temp_' => array()
-                               )
-                       ),
-                       '_processed_ folder on second level' => array(
-                               'path' => 'Public/',
-                               'processingFolder' => 'Public/_processed_',
-                               'folderList' => array(
-                                       '_processed_' => array(),
-                                       '_temp_' => array(),
-                                       'user_upload' => array()
-                               ),
-                               'expectedItems' => array(
-                                       'user_upload' => array(),
-                                       '_temp_' => array()
-                               )
-                       ),
-                       '_processed_ folder on third level' => array(
-                               'path' => 'Public/Files/',
-                               'processingFolder' => 'Public/Files/_processed_',
-                               'folderList' => array(
-                                       '_processed_' => array(),
-                                       '_temp_' => array(),
-                                       'user_upload' => array()
-                               ),
-                               'expectedItems' => array(
-                                       'user_upload' => array(),
-                                       '_temp_' => array()
-                               )
-                       )
-               );
-       }
-
-       /**
-        * @test
-        * @dataProvider fetchFolderListFromDriverReturnsFolderWithoutProcessedFolderDataProvider
-        */
-       public function fetchFolderListFromDriverReturnsFolderWithoutProcessedFolder($path, $processingFolder, $folderList, $expectedItems) {
-               $driverMock = $this->createDriverMock(array(), NULL, array('getFolderList', 'folderExists'));
-               $driverMock->expects($this->once())->method('getFolderList')->will($this->returnValue($folderList));
-               $driverMock->expects($this->any())->method('folderExists')->will($this->returnValue(TRUE));
-
-               $this->prepareFixture(array(), TRUE, $driverMock, array('processingfolder' => $processingFolder));
-
-               $this->assertSame($expectedItems, $this->fixture->fetchFolderListFromDriver($path));
-       }
 }
index 4128525..c321203 100644 (file)
@@ -142,17 +142,11 @@ class FileExtensionFilterTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @dataProvider extensionFilterIgnoresCaseInAllowedExtensionCheckDataProvider
         */
        public function extensionFilterIgnoresCaseInAllowedExtensionCheck($fileExtension, $allowedExtensions, $disallowedExtensions, $isAllowed) {
-
-               /** @var \TYPO3\CMS\Core\Resource\File $file */
-               $file = new \TYPO3\CMS\Core\Resource\File(array('name' => 'file.' . $fileExtension),
-                       $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE)
-               );
-
                /** @var \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter $filter */
                $filter = $this->getAccessibleMock('\TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter', array('dummy'));
                $filter->setAllowedFileExtensions($allowedExtensions);
                $filter->setDisallowedFileExtensions($disallowedExtensions);
-               $result = $filter->_call('isAllowed', $file);
+               $result = $filter->_call('isAllowed', 'file.' . $fileExtension);
                $this->assertEquals($isAllowed, $result);
        }
 }
index 0091a0f..6aefe6c 100644 (file)
@@ -286,7 +286,7 @@ class FileList extends \TYPO3\CMS\Backend\RecordList\AbstractRecordList {
                // Only render the contents of a browsable storage
 
                if ($this->folderObject->getStorage()->isBrowsable()) {
-                       $folders = $storage->getFolderList($this->folderObject->getIdentifier());
+                       $folders = $storage->getFolderIdentifiersInFolder($this->folderObject->getIdentifier());
                        $files = $this->folderObject->getFiles();
                        $this->sort = trim($this->sort);
                        if ($this->sort !== '') {
@@ -338,7 +338,7 @@ class FileList extends \TYPO3\CMS\Backend\RecordList\AbstractRecordList {
                        $this->fieldArray = explode(',', $rowlist);
                        $folderObjects = array();
                        foreach ($folders as $folder) {
-                               $folderObjects[] = $storage->getFolder($folder['identifier']);
+                               $folderObjects[] = $storage->getFolder($folder);
                        }
 
                        $folderObjects = \TYPO3\CMS\Core\Resource\Utility\ListUtility::resolveSpecialFolderNames($folderObjects);