]> source.dussan.org Git - nextcloud-server.git/commitdiff
add priority to storage wrappers
authorRobin Appelman <icewind@owncloud.com>
Thu, 26 Mar 2015 18:24:49 +0000 (19:24 +0100)
committerRobin Appelman <icewind@owncloud.com>
Thu, 26 Mar 2015 20:26:38 +0000 (21:26 +0100)
lib/private/files/filesystem.php
lib/private/files/storage/common.php
lib/private/files/storage/storagefactory.php
tests/lib/files/storage/storagefactory.php

index 351483d59c1b6ee62699f34c4cc373b55405e144..eef76125311e14ebf5b3a95f55a60f29361f04e8 100644 (file)
@@ -201,11 +201,13 @@ class Filesystem {
        private static $loader;
 
        /**
+        * @param string $wrapperName
         * @param callable $wrapper
+        * @param int $priority
         */
-       public static function addStorageWrapper($wrapperName, $wrapper) {
+       public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) {
                $mounts = self::getMountManager()->getAll();
-               if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $mounts)) {
+               if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $priority, $mounts)) {
                        // do not re-wrap if storage with this name already existed
                        return;
                }
index ed8852cb68d5e67f2da6f2014be3727f30fcb53f..21883d0413b33d06e2f0cd367c2062dd7d932a0b 100644 (file)
@@ -37,7 +37,6 @@ namespace OC\Files\Storage;
 
 use OC\Files\Cache\Cache;
 use OC\Files\Cache\Scanner;
-use OC\Files\Cache\Storage;
 use OC\Files\Filesystem;
 use OC\Files\Cache\Watcher;
 use OCP\Files\FileNameTooLongException;
@@ -56,7 +55,7 @@ use OCP\Files\ReservedWordException;
  * Some \OC\Files\Storage\Common methods call functions which are first defined
  * in classes which extend it, e.g. $this->stat() .
  */
-abstract class Common implements \OC\Files\Storage\Storage {
+abstract class Common implements Storage {
        protected $cache;
        protected $scanner;
        protected $watcher;
@@ -370,7 +369,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
                        $storage = $this;
                }
                if (!isset($this->storageCache)) {
-                       $this->storageCache = new Storage($storage);
+                       $this->storageCache = new \OC\Files\Cache\Storage($storage);
                }
                return $this->storageCache;
        }
index 5da192e4c727a50b07c7f69edbabe6226af2d4ec..31b4090eda2812465b18f60735174663eadde191 100644 (file)
@@ -31,9 +31,9 @@ use OCP\Files\Storage\IStorageFactory;
 
 class StorageFactory implements IStorageFactory {
        /**
-        * @var callable[] $storageWrappers
+        * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
         */
-       private $storageWrappers = array();
+       private $storageWrappers = [];
 
        /**
         * allow modifier storage behaviour by adding wrappers around storages
@@ -42,11 +42,12 @@ class StorageFactory implements IStorageFactory {
         *
         * @param string $wrapperName name of the wrapper
         * @param callable $callback callback
+        * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
         * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
         * @return bool true if the wrapper was added, false if there was already a wrapper with this
         * name registered
         */
-       public function addStorageWrapper($wrapperName, $callback, $existingMounts = []) {
+       public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
                if (isset($this->storageWrappers[$wrapperName])) {
                        return false;
                }
@@ -56,7 +57,7 @@ class StorageFactory implements IStorageFactory {
                        $mount->wrapStorage($callback);
                }
 
-               $this->storageWrappers[$wrapperName] = $callback;
+               $this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
                return true;
        }
 
@@ -89,7 +90,15 @@ class StorageFactory implements IStorageFactory {
         * @return \OCP\Files\Storage
         */
        public function wrap(IMountPoint $mountPoint, $storage) {
-               foreach ($this->storageWrappers as $wrapper) {
+               $wrappers = array_values($this->storageWrappers);
+               usort($wrappers, function ($a, $b) {
+                       return $b['priority'] - $a['priority'];
+               });
+               /** @var callable[] $wrappers */
+               $wrappers = array_map(function ($wrapper) {
+                       return $wrapper['wrapper'];
+               }, $wrappers);
+               foreach ($wrappers as $wrapper) {
                        $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
                }
                return $storage;
index 15519ef83fbda70dd89d1d416797b2a915910f3d..fcdff577dd59519bd9a98b0b49ee2f9c7ef834c5 100644 (file)
@@ -15,7 +15,14 @@ use Test\TestCase;
 use OC\Files\Storage\Wrapper\Wrapper;
 
 class DummyWrapper extends Wrapper {
+       public $data;
 
+       public function __construct($arguments) {
+               parent::__construct($arguments);
+               if (isset($arguments['data'])) {
+                       $this->data = $arguments['data'];
+               }
+       }
 }
 
 class StorageFactory extends TestCase {
@@ -42,4 +49,24 @@ class StorageFactory extends TestCase {
                $wrapped = $mount->getStorage();
                $this->assertInstanceOf('\OC\Files\Storage\Temporary', $wrapped);
        }
+
+       public function testWrapperPriority() {
+               $instance = new \OC\Files\Storage\StorageFactory();
+               $mount = new MountPoint('\OC\Files\Storage\Temporary', '/foo', [[]], $instance);
+               $instance->addStorageWrapper('dummy1', function ($mountPoint, IStorage $storage) {
+                       return new DummyWrapper(['storage' => $storage, 'data' => 1]);
+               }, 1);
+               $instance->addStorageWrapper('dummy2', function ($mountPoint, IStorage $storage) {
+                       return new DummyWrapper(['storage' => $storage, 'data' => 100]);
+               }, 100);
+               $instance->addStorageWrapper('dummy3', function ($mountPoint, IStorage $storage) {
+                       return new DummyWrapper(['storage' => $storage, 'data' => 50]);
+               }, 50);
+               /** @var \Test\Files\Storage\DummyWrapper $wrapped */
+               $wrapped = $mount->getStorage();
+               $this->assertInstanceOf('\Test\Files\Storage\DummyWrapper', $wrapped);
+               $this->assertEquals(1, $wrapped->data);// lowest priority is applied last, called first
+               $this->assertEquals(50, $wrapped->getWrapperStorage()->data);
+               $this->assertEquals(100, $wrapped->getWrapperStorage()->getWrapperStorage()->data);
+       }
 }