Passed
Push — master ( 23e8ae...e8872f )
by Robin
16:16 queued 12s
created

Manager::getSetupManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright Copyright (c) 2016, ownCloud, Inc.
7
 *
8
 * @author Björn Schießle <[email protected]>
9
 * @author Morris Jobke <[email protected]>
10
 * @author Robin Appelman <[email protected]>
11
 * @author Robin McCorkell <[email protected]>
12
 * @author Roeland Jago Douma <[email protected]>
13
 *
14
 * @license AGPL-3.0
15
 *
16
 * This code is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License, version 3,
18
 * as published by the Free Software Foundation.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License, version 3,
26
 * along with this program. If not, see <http://www.gnu.org/licenses/>
27
 *
28
 */
29
30
namespace OC\Files\Mount;
31
32
use OC\Cache\CappedMemoryCache;
33
use OC\Files\Filesystem;
34
use OC\Files\SetupManager;
35
use OC\Files\SetupManagerFactory;
36
use OCP\Files\Mount\IMountManager;
37
use OCP\Files\Mount\IMountPoint;
38
use OCP\Files\NotFoundException;
39
40
class Manager implements IMountManager {
41
	/** @var MountPoint[] */
42
	private array $mounts = [];
43
	/** @var CappedMemoryCache<IMountPoint> */
44
	private CappedMemoryCache $pathCache;
45
	/** @var CappedMemoryCache<IMountPoint[]> */
46
	private CappedMemoryCache $inPathCache;
47
	private SetupManager $setupManager;
48
49
	public function __construct(SetupManagerFactory $setupManagerFactory) {
50
		$this->pathCache = new CappedMemoryCache();
51
		$this->inPathCache = new CappedMemoryCache();
52
		$this->setupManager = $setupManagerFactory->create($this);
53
	}
54
55
	/**
56
	 * @param IMountPoint $mount
57
	 */
58
	public function addMount(IMountPoint $mount) {
59
		$this->mounts[$mount->getMountPoint()] = $mount;
60
		$this->pathCache->clear();
61
		$this->inPathCache->clear();
62
	}
63
64
	/**
65
	 * @param string $mountPoint
66
	 */
67
	public function removeMount(string $mountPoint) {
68
		$mountPoint = Filesystem::normalizePath($mountPoint);
69
		if (\strlen($mountPoint) > 1) {
70
			$mountPoint .= '/';
71
		}
72
		unset($this->mounts[$mountPoint]);
73
		$this->pathCache->clear();
74
		$this->inPathCache->clear();
75
	}
76
77
	/**
78
	 * @param string $mountPoint
79
	 * @param string $target
80
	 */
81
	public function moveMount(string $mountPoint, string $target) {
82
		$this->mounts[$target] = $this->mounts[$mountPoint];
83
		unset($this->mounts[$mountPoint]);
84
		$this->pathCache->clear();
85
		$this->inPathCache->clear();
86
	}
87
88
	/**
89
	 * Find the mount for $path
90
	 *
91
	 * @param string $path
92
	 * @return IMountPoint
93
	 */
94
	public function find(string $path): IMountPoint {
95
		$this->setupManager->setupForPath($path);
96
		$path = Filesystem::normalizePath($path);
97
98
		if (isset($this->pathCache[$path])) {
99
			return $this->pathCache[$path];
100
		}
101
102
		$current = $path;
103
		while (true) {
104
			$mountPoint = $current . '/';
105
			if (isset($this->mounts[$mountPoint])) {
106
				$this->pathCache[$path] = $this->mounts[$mountPoint];
107
				return $this->mounts[$mountPoint];
108
			} elseif ($current === '') {
109
				break;
110
			}
111
112
			$current = dirname($current);
113
			if ($current === '.' || $current === '/') {
114
				$current = '';
115
			}
116
		}
117
118
		throw new NotFoundException("No mount for path " . $path . " existing mounts: " . implode(",", array_keys($this->mounts)));
119
	}
120
121
	/**
122
	 * Find all mounts in $path
123
	 *
124
	 * @param string $path
125
	 * @return IMountPoint[]
126
	 */
127
	public function findIn(string $path): array {
128
		$this->setupManager->setupForPath($path);
129
		$path = $this->formatPath($path);
130
131
		if (isset($this->inPathCache[$path])) {
132
			return $this->inPathCache[$path];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->inPathCache[$path] returns the type OC\Cache\T which is incompatible with the type-hinted return array.
Loading history...
133
		}
134
135
		$result = [];
136
		$pathLength = \strlen($path);
137
		$mountPoints = array_keys($this->mounts);
138
		foreach ($mountPoints as $mountPoint) {
139
			if (substr($mountPoint, 0, $pathLength) === $path && \strlen($mountPoint) > $pathLength) {
140
				$result[] = $this->mounts[$mountPoint];
141
			}
142
		}
143
144
		$this->inPathCache[$path] = $result;
145
		return $result;
146
	}
147
148
	public function clear() {
149
		$this->mounts = [];
150
		$this->pathCache->clear();
151
		$this->inPathCache->clear();
152
	}
153
154
	/**
155
	 * Find mounts by storage id
156
	 *
157
	 * @param string $id
158
	 * @return IMountPoint[]
159
	 */
160
	public function findByStorageId(string $id): array {
161
		\OC_Util::setupFS();
162
		if (\strlen($id) > 64) {
163
			$id = md5($id);
164
		}
165
		$result = [];
166
		foreach ($this->mounts as $mount) {
167
			if ($mount->getStorageId() === $id) {
168
				$result[] = $mount;
169
			}
170
		}
171
		return $result;
172
	}
173
174
	/**
175
	 * @return IMountPoint[]
176
	 */
177
	public function getAll(): array {
178
		return $this->mounts;
179
	}
180
181
	/**
182
	 * Find mounts by numeric storage id
183
	 *
184
	 * @param int $id
185
	 * @return IMountPoint[]
186
	 */
187
	public function findByNumericId(int $id): array {
188
		$storageId = \OC\Files\Cache\Storage::getStorageId($id);
189
		return $this->findByStorageId($storageId);
190
	}
191
192
	/**
193
	 * @param string $path
194
	 * @return string
195
	 */
196
	private function formatPath(string $path): string {
197
		$path = Filesystem::normalizePath($path);
198
		if (\strlen($path) > 1) {
199
			$path .= '/';
200
		}
201
		return $path;
202
	}
203
204
	public function getSetupManager(): SetupManager {
205
		return $this->setupManager;
206
	}
207
}
208