Completed
Push — stable10 ( 72d31a...5e7973 )
by Lukas
39:36 queued 28:45
created

MountPoint   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 235
Duplicated Lines 2.98 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 7
loc 235
rs 9.3999
wmc 33
lcom 2
cbo 4

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getMountPoint() 0 3 1
A setMountPoint() 0 3 1
B createStorage() 0 24 5
A getStorage() 0 6 2
B getStorageId() 0 17 5
B __construct() 0 29 6
A getNumericStorageId() 0 3 1
A getInternalPath() 0 10 3
A formatPath() 7 7 2
A wrapStorage() 0 7 2
A getOption() 0 3 2
A getOptions() 0 3 1
A getStorageRootId() 0 3 1
A getMountId() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Björn Schießle <[email protected]>
6
 * @author Georg Ehrke <[email protected]>
7
 * @author Jörn Friedrich Dreyer <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 * @author Robin McCorkell <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 * @author Vincent Petry <[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\Files\Filesystem;
33
use OC\Files\Storage\StorageFactory;
34
use OC\Files\Storage\Storage;
35
use OCP\Files\Mount\IMountPoint;
36
37
class MountPoint implements IMountPoint {
38
	/**
39
	 * @var \OC\Files\Storage\Storage $storage
40
	 */
41
	protected $storage = null;
42
	protected $class;
43
	protected $storageId;
44
45
	/**
46
	 * Configuration options for the storage backend
47
	 *
48
	 * @var array
49
	 */
50
	protected $arguments = array();
51
	protected $mountPoint;
52
53
	/**
54
	 * Mount specific options
55
	 *
56
	 * @var array
57
	 */
58
	protected $mountOptions = array();
59
60
	/**
61
	 * @var \OC\Files\Storage\StorageFactory $loader
62
	 */
63
	private $loader;
64
65
	/**
66
	 * Specified whether the storage is invalid after failing to
67
	 * instantiate it.
68
	 *
69
	 * @var bool
70
	 */
71
	private $invalidStorage = false;
72
73
	/** @var int|null  */
74
	protected $mountId;
75
76
	/**
77
	 * @param string|\OC\Files\Storage\Storage $storage
78
	 * @param string $mountpoint
79
	 * @param array $arguments (optional) configuration for the storage backend
80
	 * @param \OCP\Files\Storage\IStorageFactory $loader
81
	 * @param array $mountOptions mount specific options
82
	 * @param int|null $mountId
83
	 * @throws \Exception
84
	 */
85
	public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null, $mountId = null) {
86
		if (is_null($arguments)) {
87
			$arguments = array();
88
		}
89
		if (is_null($loader)) {
90
			$this->loader = new StorageFactory();
91
		} else {
92
			$this->loader = $loader;
0 ignored issues
show
Documentation Bug introduced by
$loader is of type object<OCP\Files\Storage\IStorageFactory>, but the property $loader was declared to be of type object<OC\Files\Storage\StorageFactory>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
93
		}
94
95
		if (!is_null($mountOptions)) {
96
			$this->mountOptions = $mountOptions;
97
		}
98
99
		$mountpoint = $this->formatPath($mountpoint);
100
		$this->mountPoint = $mountpoint;
101
		if ($storage instanceof Storage) {
102
			$this->class = get_class($storage);
103
			$this->storage = $this->loader->wrap($this, $storage);
104
		} else {
105
			// Update old classes to new namespace
106
			if (strpos($storage, 'OC_Filestorage_') !== false) {
107
				$storage = '\OC\Files\Storage\\' . substr($storage, 15);
108
			}
109
			$this->class = $storage;
110
			$this->arguments = $arguments;
111
		}
112
		$this->mountId = $mountId;
113
	}
114
115
	/**
116
	 * get complete path to the mount point, relative to data/
117
	 *
118
	 * @return string
119
	 */
120
	public function getMountPoint() {
121
		return $this->mountPoint;
122
	}
123
124
	/**
125
	 * Sets the mount point path, relative to data/
126
	 *
127
	 * @param string $mountPoint new mount point
128
	 */
129
	public function setMountPoint($mountPoint) {
130
		$this->mountPoint = $this->formatPath($mountPoint);
131
	}
132
133
	/**
134
	 * create the storage that is mounted
135
	 *
136
	 * @return \OC\Files\Storage\Storage
137
	 */
138
	private function createStorage() {
139
		if ($this->invalidStorage) {
140
			return null;
141
		}
142
143
		if (class_exists($this->class)) {
144
			try {
145
				return $this->loader->getInstance($this, $this->class, $this->arguments);
146
			} catch (\Exception $exception) {
147
				$this->invalidStorage = true;
148
				if ($this->mountPoint === '/') {
149
					// the root storage could not be initialized, show the user!
150
					throw new \Exception('The root storage could not be initialized. Please contact your local administrator.', $exception->getCode(), $exception);
151
				} else {
152
					\OCP\Util::writeLog('core', $exception->getMessage(), \OCP\Util::ERROR);
153
				}
154
				return null;
155
			}
156
		} else {
157
			\OCP\Util::writeLog('core', 'storage backend ' . $this->class . ' not found', \OCP\Util::ERROR);
158
			$this->invalidStorage = true;
159
			return null;
160
		}
161
	}
162
163
	/**
164
	 * @return \OC\Files\Storage\Storage
165
	 */
166
	public function getStorage() {
167
		if (is_null($this->storage)) {
168
			$this->storage = $this->createStorage();
169
		}
170
		return $this->storage;
171
	}
172
173
	/**
174
	 * @return string
175
	 */
176
	public function getStorageId() {
177
		if (!$this->storageId) {
178
			if (is_null($this->storage)) {
179
				$storage = $this->createStorage(); //FIXME: start using exceptions
180
				if (is_null($storage)) {
181
					return null;
182
				}
183
184
				$this->storage = $storage;
185
			}
186
			$this->storageId = $this->storage->getId();
187
			if (strlen($this->storageId) > 64) {
188
				$this->storageId = md5($this->storageId);
189
			}
190
		}
191
		return $this->storageId;
192
	}
193
194
	/**
195
	 * @return int
196
	 */
197
	public function getNumericStorageId() {
198
		return $this->getStorage()->getStorageCache()->getNumericId();
199
	}
200
201
	/**
202
	 * @param string $path
203
	 * @return string
204
	 */
205
	public function getInternalPath($path) {
206
		$path = Filesystem::normalizePath($path, true, false, true);
207
		if ($this->mountPoint === $path or $this->mountPoint . '/' === $path) {
208
			$internalPath = '';
209
		} else {
210
			$internalPath = substr($path, strlen($this->mountPoint));
211
		}
212
		// substr returns false instead of an empty string, we always want a string
213
		return (string)$internalPath;
214
	}
215
216
	/**
217
	 * @param string $path
218
	 * @return string
219
	 */
220 View Code Duplication
	private function formatPath($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
		$path = Filesystem::normalizePath($path);
222
		if (strlen($path) > 1) {
223
			$path .= '/';
224
		}
225
		return $path;
226
	}
227
228
	/**
229
	 * @param callable $wrapper
230
	 */
231
	public function wrapStorage($wrapper) {
232
		$storage = $this->getStorage();
233
		// storage can be null if it couldn't be initialized
234
		if ($storage != null) {
235
			$this->storage = $wrapper($this->mountPoint, $storage, $this);
236
		}
237
	}
238
239
	/**
240
	 * Get a mount option
241
	 *
242
	 * @param string $name Name of the mount option to get
243
	 * @param mixed $default Default value for the mount option
244
	 * @return mixed
245
	 */
246
	public function getOption($name, $default) {
247
		return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
248
	}
249
250
	/**
251
	 * Get all options for the mount
252
	 *
253
	 * @return array
254
	 */
255
	public function getOptions() {
256
		return $this->mountOptions;
257
	}
258
259
	/**
260
	 * Get the file id of the root of the storage
261
	 *
262
	 * @return int
263
	 */
264
	public function getStorageRootId() {
265
		return (int)$this->getStorage()->getCache()->getId('');
266
	}
267
268
	public function getMountId() {
269
		return $this->mountId;
270
	}
271
}
272