ReflectionMethod   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 330
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
eloc 51
dl 0
loc 330
ccs 64
cts 64
cp 1
rs 10
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
A hasAnnotation() 0 4 1
A serialize() 0 3 1
A addAnnotationAlias() 0 3 1
A invokeArgs() 0 3 1
A getAnnotationsToIgnore() 0 3 1
A unserialize() 0 4 2
A fromPhpReflectionMethod() 0 9 1
A getMethodName() 0 3 1
A getAnnotationAliases() 0 3 1
A getClassName() 0 3 1
A toPhpReflectionMethod() 0 3 1
A __getClass() 0 3 1
A invoke() 0 4 1
A getAnnotation() 0 12 2
A __construct() 0 15 1
A fromReflectionClass() 0 14 2
A getParameters() 0 10 2
A getAnnotations() 0 10 2
1
<?php
2
3
/**
4
 * AppserverIo\Lang\Reflection\ReflectionMethod
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 method.
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 ReflectionMethod extends Objct implements MethodInterface, \Serializable
35
{
36
37
    /**
38
     * Default filter for loading reflection methods from a reflection class.
39
     *
40
     * @var integer
41
     */
42
    const ALL_MODIFIERS = -1;
43
44
    /**
45
     * The class name to invoke the method on.
46
     *
47
     * @var string
48
     */
49
    protected $className;
50
51
    /**
52
     * The method name to invoke on the class.
53
     *
54
     * @var string
55
     */
56
    protected $methodName;
57
58
    /**
59
     * The method parameters.
60
     *
61
     * @var string
62
     */
63
    protected $parameters;
64
65
    /**
66
     * The method annotations.
67
     *
68
     * @var array
69
     */
70
    protected $annotations;
71
72
    /**
73
     * Array with annotations names we want to ignore when loaded.
74
     *
75
     * @var array
76
     */
77
    protected $annotationsToIgnore;
78
79
    /**
80
     * Array with annotation aliases used when create annotation instances.
81
     *
82
     * @var array
83
     */
84
    protected $annotationAliases;
85
86
    /**
87
     * Initializes the timeout method with the passed data.
88
     *
89
     * @param string $className           The class name to invoke the method on
90
     * @param string $methodName          The method name to invoke on the class
91
     * @param array  $annotationsToIgnore An array with annotations names we want to ignore when loaded
92
     * @param array  $annotationAliases   An array with annotation aliases used when create annotation instances
93
     */
94 17
    public function __construct($className, $methodName, array $annotationsToIgnore = array(), array $annotationAliases = array())
95
    {
96
        // initialize property default values here, as declarative default values may break thread safety,
97
        // when utilizing static and non-static access on class methods within same thread context!
98 17
        $this->className = '';
99 17
        $this->methodName = '';
100 17
        $this->parameters = null;
101 17
        $this->annotations = null;
102 17
        $this->annotationsToIgnore = array();
103 17
        $this->annotationAliases = array();
104
105 17
        $this->className = $className;
106 17
        $this->methodName = $methodName;
107 17
        $this->annotationsToIgnore = $annotationsToIgnore;
108 17
        $this->annotationAliases = $annotationAliases;
109 17
    }
110
111
    /**
112
     * This method returns the class name as
113
     * a string.
114
     *
115
     * @return string
116
     */
117 1
    public static function __getClass()
118
    {
119 1
        return __CLASS__;
120
    }
121
122
    /**
123
     * Returns the class name to invoke the method on.
124
     *
125
     * @return string The class name
126
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getClassName()
127
     */
128 11
    public function getClassName()
129
    {
130 11
        return $this->className;
131
    }
132
133
    /**
134
     * Returns the method name to invoke on the class.
135
     *
136
     * @return string The method name
137
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getMethodName()
138
     */
139 11
    public function getMethodName()
140
    {
141 11
        return $this->methodName;
142
    }
143
144
    /**
145
     * Returns an array with annotation names we want to ignore when loaded.
146
     *
147
     * @return array The annotation names we want to ignore
148
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getAnnotationsToIgnore()
149
     */
150 7
    public function getAnnotationsToIgnore()
151
    {
152 7
        return $this->annotationsToIgnore;
153
    }
154
155
    /**
156
     * Returns an array with annotation aliases used when create annotation instances.
157
     *
158
     * @return array The annotation aliases used when create annotation instances
159
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getAnnotationAliases()
160
     */
161 8
    public function getAnnotationAliases()
162
    {
163 8
        return $this->annotationAliases;
164
    }
165
166
    /**
167
     * Registers the annotation alias for the passed class name.
168
     *
169
     * @param string $annotationName      The alias
170
     * @param string $annotationClassName The resolving class name
171
     *
172
     * @return void
173
     * @see \AppserverIo\Lang\Reflection\MethodInterface::addAnnotationAlias()
174
     */
175 1
    public function addAnnotationAlias($annotationName, $annotationClassName)
176
    {
177 1
        $this->annotationAliases[$annotationName] = $annotationClassName;
178 1
    }
179
180
    /**
181
     * Returns the method parameters.
182
     *
183
     * @return array The method parameters
184
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getParameters()
185
     */
186 2
    public function getParameters()
187
    {
188
189
        // check if the parameters has been loaded
190 2
        if (isset($this->parameters) === false) {
191 2
            $this->parameters = ReflectionParameter::fromReflectionMethod($this);
0 ignored issues
show
Documentation Bug introduced by
It seems like AppserverIo\Lang\Reflect...ReflectionMethod($this) of type array or array is incompatible with the declared type string of property $parameters.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
192
        }
193
194
        // return the parameters
195 2
        return $this->parameters;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->parameters returns the type string which is incompatible with the documented return type array.
Loading history...
196
    }
197
198
    /**
199
     * Returns the method annotations.
200
     *
201
     * @return array The method annotations
202
     * @see \AppserverIo\Lang\Reflection\MethodInterface::getAnnotations()
203
     */
204 7
    public function getAnnotations()
205
    {
206
207
        // check if the annotations has been loaded
208 7
        if (isset($this->annotations) === false) {
209 7
            $this->annotations = ReflectionAnnotation::fromReflectionMethod($this);
210
        }
211
212
        // return the annotations
213 7
        return $this->annotations;
214
    }
215
216
    /**
217
     * Queries whether the reflection method has an annotation with the passed name or not.
218
     *
219
     * @param string $annotationName The annotation we want to query
220
     *
221
     * @return boolean TRUE if the reflection method has the annotation, else FALSE
222
     * @see \AppserverIo\Lang\Reflection\MethodInterface::hasAnnotation()
223
     */
224 2
    public function hasAnnotation($annotationName)
225
    {
226 2
        $annotations = $this->getAnnotations();
227 2
        return isset($annotations[$annotationName]);
228
    }
229
230
    /**
231
     * Returns the annotation instance with the passed name.
232
     *
233
     * @param string $annotationName The name of the requested annotation instance
234
     *
235
     * @return \AppserverIo\Lang\Reflection\AnnotationInterface|null The requested annotation instance
236
     * @throws \AppserverIo\Lang\Reflection\ReflectionException Is thrown if the requested annotation is not available
237
     * @see \AppserverIo\Lang\Reflection\MethodInterface::hasAnnotation()
238
     */
239 5
    public function getAnnotation($annotationName)
240
    {
241
242
        // first check if the method is available
243 5
        $annotations = $this->getAnnotations();
244 5
        if (isset($annotations[$annotationName])) {
245
            // if yes, return it
246 4
            return $annotations[$annotationName];
247
        }
248
249
        // if not, throw an exception
250 1
        throw new ReflectionException(sprintf('The requested reflection annotation %s is not available', $annotationName));
251
    }
252
253
    /**
254
     * Serializes the timeout method and returns a string representation.
255
     *
256
     * @return string The serialized string representation of the instance
257
     * @see \Serializable::serialize()
258
     */
259 1
    public function serialize()
260
    {
261 1
        return serialize(get_object_vars($this));
262
    }
263
264
    /**
265
     * Restores the instance with the serialized data of the passed string.
266
     *
267
     * @param string $data The serialized method representation
268
     *
269
     * @return void
270
     * @see \Serializable::unserialize()
271
     */
272 1
    public function unserialize($data)
273
    {
274 1
        foreach (unserialize($data) as $propertyName => $propertyValue) {
275 1
            $this->$propertyName = $propertyValue;
276
        }
277 1
    }
278
279
    /**
280
     * Invokes a reflected method. You cann pass a random number of additional
281
     * parameters that'll be passed to the method as parameters.
282
     *
283
     * @param object $object The object to invoke the method on
284
     *
285
     * @return mixed Returns the method result
286
     * @see \AppserverIo\Lang\Reflection\ReflectionMethod::invokeArgs()
287
     * @link http://php.net/manual/en/reflectionmethod.invoke.php
288
     */
289 1
    public function invoke($object)
290
    {
291 1
        $args = func_get_args(); // load the arguments, drop the first one (because this is always the instance itself)
292 1
        return $this->invokeArgs($object, array_splice($args, 1, 1));
293
    }
294
295
    /**
296
     * Invokes the reflected method and pass its arguments as array.
297
     *
298
     * @param object $object The object to invoke the method on
299
     * @param array  $args   The parameters to be passed to the function, as an array
300
     *
301
     * @return mixed Returns the method result
302
     * @link http://php.net/manual/en/reflectionmethod.invokeargs.php
303
     */
304 1
    public function invokeArgs($object, array $args = array())
305
    {
306 1
        return $this->toPhpReflectionMethod()->invokeArgs($object, $args);
307
    }
308
309
    /**
310
     * Returns a PHP reflection method representation of this instance.
311
     *
312
     * @return \ReflectionMethod The PHP reflection method instance
313
     * @see \AppserverIo\Lang\Reflection\MethodInterface::toPhpReflectionMethod()
314
     */
315 10
    public function toPhpReflectionMethod()
316
    {
317 10
        return new \ReflectionMethod($this->getClassName(), $this->getMethodName());
318
    }
319
320
    /**
321
     * Returns an array of reflection method instances from the passed reflection class.
322
     *
323
     * @param \AppserverIo\Lang\Reflection\ReflectionClass $reflectionClass     The reflection class to return the methods for
324
     * @param integer                                      $filter              The filter used for loading the methods
325
     * @param array                                        $annotationsToIgnore An array with annotations names we want to ignore when loaded
326
     * @param array                                        $annotationAliases   An array with annotation aliases used when create annotation instances
327
     *
328
     * @return array An array with ReflectionMethod instances
329
     */
330 10
    public static function fromReflectionClass(ReflectionClass $reflectionClass, $filter = -1, array $annotationsToIgnore = array(), array $annotationAliases = array())
331
    {
332
333
        // initialize the array for the reflection methods
334 10
        $reflectionMethods = array();
335
336
        // load the reflection methods and initialize the array with the reflection methods
337 10
        $phpReflectionClass = $reflectionClass->toPhpReflectionClass();
338 10
        foreach ($phpReflectionClass->getMethods($filter) as $phpReflectionMethod) {
339 10
            $reflectionMethods[$phpReflectionMethod->getName()] = ReflectionMethod::fromPhpReflectionMethod($phpReflectionMethod, $annotationsToIgnore, $annotationAliases);
340
        }
341
342
        // return the array with the initialized reflection methods
343 10
        return $reflectionMethods;
344
    }
345
346
    /**
347
     * Creates a new reflection method instance from the passed PHP reflection method.
348
     *
349
     * @param \ReflectionMethod $reflectionMethod    The reflection method to load the data from
350
     * @param array             $annotationsToIgnore An array with annotations names we want to ignore when loaded
351
     * @param array             $annotationAliases   An array with annotation aliases used when create annotation instances
352
     *
353
     * @return \AppserverIo\Lang\Reflection\ReflectionMethod The instance
354
     */
355 10
    public static function fromPhpReflectionMethod(\ReflectionMethod $reflectionMethod, array $annotationsToIgnore = array(), array $annotationAliases = array())
356
    {
357
358
        // load class and method name from the reflection class
359 10
        $className = $reflectionMethod->getDeclaringClass()->getName();
360 10
        $methodName = $reflectionMethod->getName();
361
362
        // initialize and return the timeout method instance
363 10
        return new ReflectionMethod($className, $methodName, $annotationsToIgnore, $annotationAliases);
364
    }
365
}
366