Completed
Push — master ( cdb5aa...909635 )
by Bernhard
10s
created

ReflectionClass::getMethod()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 12
c 0
b 0
f 0
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
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\Objct;
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 Objct 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
    public function getAnnotation($annotationName)
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
    public function getMethods($filter = ReflectionProperty::ALL_MODIFIERS)
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
    public function getProperties($filter = ReflectionProperty::ALL_MODIFIERS)
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