Completed
Pull Request — master (#25)
by ilyes
04:01
created

ReflectionClass::addAnnotationAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
/**
4
 * AppserverIo\Lang\Reflection\ReflectionClass
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2015 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/appserver-io/lang
18
 * @link      http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Lang\Reflection;
22
23
use AppserverIo\Lang\Object;
24
25
/**
26
 * A wrapper instance for a reflection class.
27
 *
28
 * @author    Tim Wagner <[email protected]>
29
 * @copyright 2015 TechDivision GmbH <[email protected]>
30
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
31
 * @link      https://github.com/appserver-io/lang
32
 * @link      http://www.appserver.io
33
 */
34
class ReflectionClass extends Object implements ClassInterface, \Serializable
35
{
36
37
    /**
38
     * The passed class name to invoke the method on.
39
     *
40
     * @var string
41
     */
42
    protected $passedName;
43
44
    /**
45
     * The class annotations.
46
     *
47
     * @var array|null
48
     */
49
    protected $annotations;
50
51
    /**
52
     * The class methods in an associative, three dimensional array with modifiers and method names as keys.
53
     *
54
     * @var array
55
     */
56
    protected $methods;
57
58
    /**
59
     * The class properties in an associative, three dimensional array with modifiers and property names as keys.
60
     *
61
     * @var array
62
     */
63
    protected $properties;
64
65
    /**
66
     * Array with annotations names we want to ignore when loaded.
67
     *
68
     * @var array
69
     */
70
    protected $annotationsToIgnore;
71
72
    /**
73
     * Array with annotation aliases used when create annotation instances.
74
     *
75
     * @var array
76
     */
77
    protected $annotationAliases;
78
79
    /**
80
     * Initializes the timed object with the passed data.
81
     *
82
     * @param string $name                The class name to invoke the method on
83
     * @param array  $annotationsToIgnore An array with annotations names we want to ignore when loaded
84
     * @param array  $annotationAliases   An array with annotation aliases used when create annotation instances
85
     */
86 24
    public function __construct($name, array $annotationsToIgnore = array(), array $annotationAliases = array())
87
    {
88
        // initialize property default values here, as declarative default values may break thread safety,
89
        // when utilizing static and non-static access on class methods within same thread context!
90 24
        $this->passedName = '';
91 24
        $this->annotations = null;
92 24
        $this->methods = array();
93 24
        $this->properties = array();
94 24
        $this->annotationsToIgnore = array();
95 24
        $this->annotationAliases = array();
96
97 24
        $this->passedName = $name;
98 24
        $this->annotationsToIgnore = $annotationsToIgnore;
99 24
        $this->annotationAliases = $annotationAliases;
100 24
    }
101
102
    /**
103
     * This method returns the class name as
104
     * a string.
105
     *
106
     * @return string
107
     */
108 1
    public static function __getClass()
109
    {
110 1
        return __CLASS__;
111
    }
112
113
    /**
114
     * Returns the class name passed to the constructor.
115
     *
116
     * @return string The class name passed to the constructor
117
     */
118 21
    protected function getPassedName()
119
    {
120 21
        return $this->passedName;
121
    }
122
123
    /**
124
     * Returns the class name.
125
     *
126
     * @return string The class name
127
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getClassName()
128
     */
129 2
    public function getName()
130
    {
131 2
        return $this->toPhpReflectionClass()->getName();
132
    }
133
134
    /**
135
     * Returns the short class name (without namespace).
136
     *
137
     * @return string The short class name
138
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getClassName()
139
     */
140
    public function getShortName()
141
    {
142
        return $this->toPhpReflectionClass()->getShortName();
143
    }
144
145
    /**
146
     * Returns an array with annotation names we want to ignore when loaded.
147
     *
148
     * @return array The annotation names we want to ignore
149
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getAnnotationsToIgnore()
150
     */
151 16
    public function getAnnotationsToIgnore()
152
    {
153 16
        return $this->annotationsToIgnore;
154
    }
155
156
    /**
157
     * Returns an array with annotation aliases used when create annotation instances.
158
     *
159
     * @return array The annotation aliases used when create annotation instances
160
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getAnnotationAliases()
161
     */
162 17
    public function getAnnotationAliases()
163
    {
164 17
        return $this->annotationAliases;
165
    }
166
167
    /**
168
     * Registers the annotation alias for the passed class name.
169
     *
170
     * @param string $annotationName      The alias
171
     * @param string $annotationClassName The resolving class name
172
     *
173
     * @return void
174
     * @see \AppserverIo\Lang\Reflection\ClassInterface::addAnnotationAlias()
175
     */
176 1
    public function addAnnotationAlias($annotationName, $annotationClassName)
177
    {
178 1
        $this->annotationAliases[$annotationName] = $annotationClassName;
179 1
    }
180
181
    /**
182
     * Returns the class annotations.
183
     *
184
     * @return array The class annotations
185
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getAnnotations()
186
     */
187 4
    public function getAnnotations()
188
    {
189
190
        // check if the annotations has been loaded
191 4
        if (isset($this->annotations) === false) {
192 4
            $this->annotations = ReflectionAnnotation::fromReflectionClass($this);
193
        }
194
195
        // return the annotations
196 4
        return $this->annotations;
197
    }
198
199
    /**
200
     * Queries whether the reflection class has an annotation with the passed name or not.
201
     *
202
     * @param string $annotationName The annotation we want to query
203
     *
204
     * @return boolean TRUE if the reflection class has the annotation, else FALSE
205
     * @see \AppserverIo\Lang\Reflection\ClassInterface::hasAnnotation()
206
     */
207 1
    public function hasAnnotation($annotationName)
208
    {
209 1
        $annotations = $this->getAnnotations();
210 1
        return isset($annotations[$annotationName]);
211
    }
212
213
    /**
214
     * Returns the annotation instance with the passed name.
215
     *
216
     * @param string $annotationName The name of the requested annotation instance
217
     *
218
     * @return \AppserverIo\Lang\Reflection\AnnotationInterface|null The requested annotation instance
219
     * @throws \AppserverIo\Lang\Reflection\ReflectionException Is thrown if the requested annotation is not available
220
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getAnnotation()
221
     */
222 3 View Code Duplication
    public function getAnnotation($annotationName)
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...
223
    {
224
225
        // first check if the method is available
226 3
        $annotations = $this->getAnnotations();
227 3
        if (isset($annotations[$annotationName])) {
228
            // if yes, return it
229 2
            return $annotations[$annotationName];
230
        }
231
232
        // if not, throw an exception
233 1
        throw new ReflectionException(sprintf('The requested reflection annotation %s is not available', $annotationName));
234
    }
235
236
    /**
237
     * Returns the class methods.
238
     *
239
     * @param integer $filter Filter the results to include only methods with certain attributes
240
     *
241
     * @return array The class methods
242
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getMethods()
243
     * @link http://php.net/manual/en/reflectionclass.getmethods.php
244
     */
245 10 View Code Duplication
    public function getMethods($filter = ReflectionProperty::ALL_MODIFIERS)
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...
246
    {
247
248
        // check if the methods for the requested filter has been loaded
249 10
        if (isset($this->methods[$filter]) === false) {
250 10
            $this->methods[$filter] = ReflectionMethod::fromReflectionClass($this, $filter, $this->getAnnotationsToIgnore(), $this->getAnnotationAliases());
251
        }
252
253
        // return the requested method
254 10
        return $this->methods[$filter];
255
    }
256
257
    /**
258
     * Queries whether the reflection class has an method with the passed name or not.
259
     *
260
     * @param string $name The method we want to query
261
     *
262
     * @return boolean TRUE if the reflection class has the method, else FALSE
263
     * @see \AppserverIo\Lang\Reflection\ClassInterface::hasMethod()
264
     */
265 2
    public function hasMethod($name)
266
    {
267 2
        $methods = $this->getMethods();
268 2
        return isset($methods[$name]);
269
    }
270
271
    /**
272
     * Returns the requested reflection method.
273
     *
274
     * @param string $name The name of the reflection method to return
275
     *
276
     * @return \AppserverIo\Lang\Reflection\ReflectionMethod The requested reflection method
277
     * @throws \AppserverIo\Lang\Reflection\ReflectionException Is thrown if the requested method is not available
278
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getMethod()
279
     * @link http://php.net/manual/en/reflectionclass.getmethod.php
280
     */
281 8
    public function getMethod($name)
282
    {
283
284
        // first check if the method is available
285 8
        $methods = $this->getMethods();
286 8
        if (isset($methods[$name])) {
287
            // if yes, return it
288 7
            return $methods[$name];
289
        }
290
291
        // if not, throw an exception
292 1
        throw new ReflectionException(sprintf('The requested reflection method %s is not available', $name));
293
    }
294
295
    /**
296
     * Returns the class properties.
297
     *
298
     * @param integer $filter Filter the results to include only properties with certain attributes
299
     *
300
     * @return array The class properties
301
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getProperties()
302
     * @link http://php.net/manual/en/reflectionclass.getproperties.php
303
     */
304 1 View Code Duplication
    public function getProperties($filter = ReflectionProperty::ALL_MODIFIERS)
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...
305
    {
306
307
        // check if the properties for the requested filter has been loaded
308 1
        if (isset($this->properties[$filter]) === false) {
309 1
            $this->properties[$filter] = ReflectionProperty::fromReflectionClass($this, $filter, $this->getAnnotationsToIgnore(), $this->getAnnotationAliases());
310
        }
311
312
        // return the requested properties
313 1
        return $this->properties[$filter];
314
    }
315
316
    /**
317
     * Queries whether the reflection class has an property with the passed name or not.
318
     *
319
     * @param string $name The property we want to query
320
     *
321
     * @return boolean TRUE if the reflection class has the property, else FALSE
322
     * @see \AppserverIo\Lang\Reflection\ClassInterface::hasProperty()
323
     */
324 1
    public function hasProperty($name)
325
    {
326 1
        $properties = $this->getProperties();
327 1
        return isset($properties[$name]);
328
    }
329
330
    /**
331
     * Returns the requested reflection property.
332
     *
333
     * @param string $name The name of the reflection property to return
334
     *
335
     * @return \AppserverIo\Lang\Reflection\ReflectionProperty The requested reflection property
336
     * @throws \AppserverIo\Lang\Reflection\ReflectionException Is thrown if the requested property is not available
337
     * @see \AppserverIo\Lang\Reflection\ClassInterface::getProperty()
338
     * @link http://php.net/manual/en/reflectionclass.getproperty.php
339
     */
340
    public function getProperty($name)
341
    {
342
343
        // first check if the property is available
344
        $properties = $this->getProperties();
345
        if (isset($properties[$name])) {
346
            // if yes, return it
347
            return $properties[$name];
348
        }
349
350
        // if not, throw an exception
351
        throw new ReflectionException(sprintf('The requested reflection property %s is not available', $name));
352
    }
353
354
    /**
355
     * Returns a new annotation instance.
356
     *
357
     * You can pass a random number of arguments to this function. These
358
     * arguments will be passed to the constructor of the new instance.
359
     *
360
     * @return object A new annotation instance initialized with the passed arguments
361
     * @see \AppserverIo\Lang\Reflection\ClassInterface::newInstance()
362
     */
363
    public function newInstance()
364
    {
365
        return $this->newInstanceArgs(func_get_args());
366
    }
367
368
    /**
369
     * Returns a new annotation instance.
370
     *
371
     * @param array $args The arguments that will be passed to the instance constructor
372
     *
373
     * @return object A new annotation instance initialized with the passed arguments
374
     * @see \AppserverIo\Lang\Reflection\ClassInterface::newInstanceArgs()
375
     */
376 1
    public function newInstanceArgs(array $args = array())
377
    {
378
        // create a reflection instance of the found annotation name
379 1
        $reflectionClass = $this->toPhpReflectionClass();
380
381
        // create a new instance passing the found arguements to the constructor
382 1
        return $reflectionClass->newInstanceArgs($args);
383
    }
384
385
    /**
386
     * Serializes the timeout method and returns a string representation.
387
     *
388
     * @return string The serialized string representation of the instance
389
     * @see \Serializable::serialize()
390
     */
391 1
    public function serialize()
392
    {
393 1
        return serialize(get_object_vars($this));
394
    }
395
396
    /**
397
     * Restores the instance with the serialized data of the passed string.
398
     *
399
     * @param string $data The serialized method representation
400
     *
401
     * @return void
402
     * @see \Serializable::unserialize()
403
     */
404 1
    public function unserialize($data)
405
    {
406 1
        foreach (unserialize($data) as $propertyName => $propertyValue) {
407 1
            $this->$propertyName = $propertyValue;
408
        }
409 1
    }
410
411
    /**
412
     * Checks whether it implements the passed interface or not.
413
     *
414
     * @param string $interface The interface name
415
     *
416
     * @return boolean Returns TRUE on success or FALSE on failure
417
     * @see \AppserverIo\Lang\Reflection\ClassInterface::implementsInterface()
418
     */
419 1
    public function implementsInterface($interface)
420
    {
421 1
        return $this->toPhpReflectionClass()->implementsInterface($interface);
422
    }
423
424
    /**
425
     * Checks whether the class is an interface.
426
     *
427
     * @return boolean Returns TRUE on success or FALSE on failure
428
     * @see \AppserverIo\Lang\Reflection\ClassInterface::isInterface()
429
     */
430 1
    public function isInterface()
431
    {
432 1
        return $this->toPhpReflectionClass()->isInterface();
433
    }
434
435
    /**
436
     * Checks if the class is abstract.
437
     *
438
     * @return boolean Rturns TRUE on success or FALSE on failure
439
     * @see \AppserverIo\Lang\Reflection\ClassInterface::isAbstract()
440
     */
441 1
    public function isAbstract()
442
    {
443 1
        return $this->toPhpReflectionClass()->isInterface();
444
    }
445
446
    /**
447
     * Returns a PHP reflection class representation of this instance.
448
     *
449
     * @return \ReflectionClass The PHP reflection class instance
450
     * @see \AppserverIo\Lang\Reflection\ClassInterface::toPhpReflectionClass()
451
     */
452 21
    public function toPhpReflectionClass()
453
    {
454 21
        return new \ReflectionClass($this->getPassedName());
455
    }
456
457
    /**
458
     * Creates a new reflection class instance from the passed PHP reflection class.
459
     *
460
     * @param \ReflectionClass $reflectionClass     The PHP reflection class to load the data from
461
     * @param array            $annotationsToIgnore An array with annotations names we want to ignore when loaded
462
     * @param array            $annotationAliases   An array with annotation aliases used when create annotation instances
463
     *
464
     * @return \AppserverIo\Lang\Reflection\ReflectionClass The instance
465
     */
466 1
    public static function fromPhpReflectionClass(\ReflectionClass $reflectionClass, array $annotationsToIgnore = array(), array $annotationAliases = array())
467
    {
468 1
        return new ReflectionClass($reflectionClass->getName(), $annotationsToIgnore, $annotationAliases);
469
    }
470
}
471