Completed
Push — master ( 688c46...b38950 )
by Tim
8s
created

ActionDescriptor   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 76.34%

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 6
dl 0
loc 300
ccs 71
cts 93
cp 0.7634
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 20 1
A setMethodName() 0 4 1
A getMethodName() 0 4 1
A setRequestMethods() 0 4 1
A getRequestMethods() 0 4 1
A setRestrictions() 0 4 1
A getRestrictions() 0 4 1
A setDefaults() 0 4 1
A getDefaults() 0 4 1
A newDescriptorInstance() 0 4 1
A newAnnotationInstance() 0 4 1
C fromReflectionMethod() 0 79 14
A fromDeploymentDescriptor() 0 3 1
A fromConfiguration() 0 3 1
A merge() 0 15 3
1
<?php
2
3
/**
4
 * AppserverIo\Routlt\Description\ActionDescriptor
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       http://github.com/appserver-io/routlt
18
 * @link       http://www.appserver.io
19
 */
20
21
namespace AppserverIo\Routlt\Description;
22
23
use AppserverIo\Http\HttpProtocol;
24
use AppserverIo\Routlt\Annotations\Action;
25
use AppserverIo\Lang\Reflection\MethodInterface;
26
use AppserverIo\Lang\Reflection\ReflectionAnnotation;
27
use AppserverIo\Configuration\Interfaces\NodeInterface;
28
use AppserverIo\Description\AbstractNameAwareDescriptor;
29
30
/**
31
 * Annotation to map a request path info to an action method.
32
 *
33
 * @author     Tim Wagner <[email protected]>
34
 * @copyright  2015 TechDivision GmbH <[email protected]>
35
 * @license    http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
36
 * @link       http://github.com/appserver-io/routlt
37
 * @link       http://www.appserver.io
38
 */
39
class ActionDescriptor extends AbstractNameAwareDescriptor implements ActionDescriptorInterface
40
{
41
42
    /**
43
     * The action method name.
44
     *
45
     * @var string
46
     */
47
    protected $methodName;
48
49
    /**
50
     * The request methods the action is listening to.
51
     *
52
     * @var array
53
     */
54
    protected $requestMethods;
55
56
    /**
57
     * The restrictions for the route placeholders.
58
     *
59
     * @var array
60
     */
61
    protected $restrictions;
62
63
    /**
64
     * The defaults for the route placeholders.
65
     *
66
     * @var array
67
     */
68
    protected $defaults;
69
70
    /**
71
     * Initializes the descriptor with the default
72
     * request methods the action is listening to.
73
     */
74 9
    public function __construct()
75
    {
76
77
        // initialize restrictions and defaults
78 9
        $this->defaults = array();
79 9
        $this->restrictions = array();
80
81
        // initialize the request methods
82 9
        $this->requestMethods = array(
83 9
            HttpProtocol::METHOD_CONNECT,
84 9
            HttpProtocol::METHOD_DELETE,
85 9
            HttpProtocol::METHOD_GET,
86 9
            HttpProtocol::METHOD_HEAD,
87 9
            HttpProtocol::METHOD_OPTIONS,
88 9
            HttpProtocol::METHOD_POST,
89 9
            HttpProtocol::METHOD_PUT,
90 9
            HttpProtocol::METHOD_TRACE,
91
            HttpProtocol::METHOD_PATCH
92 9
        );
93 9
    }
94
95
    /**
96
     * Sets the action method name.
97
     *
98
     * @param string $methodName The action method name
99
     *
100
     * @return void
101
     */
102 8
    public function setMethodName($methodName)
103
    {
104 8
        $this->methodName = $methodName;
105 8
    }
106
107
    /**
108
     * Returns the action method name.
109
     *
110
     * @return string The action method name
111
     */
112 3
    public function getMethodName()
113
    {
114 3
        return $this->methodName;
115
    }
116
117
    /**
118
     * Sets the request methods the action is listening to.
119
     *
120
     * @param array $requestMethods The request methods
121
     *
122
     * @return void
123
     */
124 3
    public function setRequestMethods(array $requestMethods)
125
    {
126 3
        $this->requestMethods = $requestMethods;
127 3
    }
128
129
    /**
130
     * Returns the request methods the action is listening to.
131
     *
132
     * @return array The request methods
133
     */
134 8
    public function getRequestMethods()
135
    {
136 8
        return $this->requestMethods;
137
    }
138
139
    /**
140
     * Sets the restrictions for the route placeholders.
141
     *
142
     * @param array $restrictions The restrictions for the route placeholders
143
     *
144
     * @return void
145
     */
146
    public function setRestrictions(array $restrictions)
147
    {
148
        $this->restrictions = $restrictions;
149
    }
150
151
    /**
152
     * Returns the restrictions for the route placeholders.
153
     *
154
     * @return array The restrictions for the route placeholders
155
     */
156
    public function getRestrictions()
157
    {
158
        return $this->restrictions;
159
    }
160
161
    /**
162
     * Sets the defaults for the route placeholders.
163
     *
164
     * @param array $defaults The defaults for the route placeholders
165
     *
166
     * @return void
167
     */
168
    public function setDefaults(array $defaults)
169
    {
170
        $this->defaults = $defaults;
171
    }
172
173
    /**
174
     * Returns the defaults for the route placeholders.
175
     *
176
     * @return array The defaults for the route placeholders
177
     */
178
    public function getDefaults()
179
    {
180
        return $this->defaults;
181
    }
182
183
    /**
184
     * Returns a new descriptor instance.
185
     *
186
     * @return \AppserverIo\Routlt\Description\ActionDescriptorInterface The descriptor instance
187
     */
188 4
    public static function newDescriptorInstance()
189
    {
190 4
        return new ActionDescriptor();
191
    }
192
193
    /**
194
     * Returns a new annotation instance for the passed reflection method.
195
     *
196
     * @param \AppserverIo\Lang\Reflection\MethodInterface $reflectionMethod The reflection method with the action configuration
197
     *
198
     * @return \AppserverIo\Lang\Reflection\AnnotationInterface The reflection annotation
199
     */
200 7
    protected function newAnnotationInstance(MethodInterface $reflectionMethod)
201
    {
202 7
        return $reflectionMethod->getAnnotation(Action::ANNOTATION);
203
    }
204
205
    /**
206
     * Initializes the action configuration instance from the passed reflection method instance.
207
     *
208
     * @param \AppserverIo\Lang\Reflection\MethodInterface $reflectionMethod The reflection method with the action configuration
209
     *
210
     * @return \AppserverIo\Routlt\Description\ActionDescriptorInterface The initialized descriptor
211
     */
212 8
    public function fromReflectionMethod(MethodInterface $reflectionMethod)
213
    {
214
215
        // add the annotation alias to the reflection method
216 8
        $reflectionMethod->addAnnotationAlias(Action::ANNOTATION, Action::__getClass());
217
218
        // query if we've a method with a @Action annotation
219 8
        if ($reflectionMethod->hasAnnotation(Action::ANNOTATION) === false &&
220 8
            $reflectionMethod->getMethodName() !== 'perform') {
221
            // if not, do nothing
222 4
            return;
223
224
        // query whether we've the default perform() method WITHOUT an @Action annotation
225 8
        } elseif ($reflectionMethod->hasAnnotation(Action::ANNOTATION) === false &&
226 8
            $reflectionMethod->getMethodName() === 'perform') {
227
            // create an annotation instance manually
228 4
            $reflectionAnnotation = new ReflectionAnnotation(Action::__getClass());
229
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
230 4
        } else {
231
            // create a new annotation instance by default
232 7
            $reflectionAnnotation = $this->newAnnotationInstance($reflectionMethod);
233
        }
234
235
        // load method name
236 8
        $this->setMethodName($reflectionMethod->getMethodName());
237
238
        // initialize the annotation instance
239 8
        $annotationInstance = $reflectionAnnotation->newInstance(
240 8
            $reflectionAnnotation->getAnnotationName(),
241 8
            $reflectionAnnotation->getValues()
242 8
        );
243
244
        // load the default name to register in naming directory
245 8
        if (($nameAttribute = $annotationInstance->getName()) || $nameAttribute === '') {
246 6
            $this->setName($nameAttribute);
247 6
        } else {
248
            // if @Annotation(name=****) is NOT SET, we use the method name by default
249 5
            $this->setName('/' . lcfirst(str_replace('Action', '', $reflectionMethod->getMethodName())));
250
        }
251
252
        // initialize the array for the annotated request methods
253 8
        $annotatedRequestMethods = array();
254
255
        // parse the method for annotated request methods
256 8
        foreach ($this->getRequestMethods() as $requestMethod) {
257
            // prepare the annotation name, e. g. POST -> Post
258 8
            $annotationName = ucfirst(strtolower($requestMethod));
259
260
            // query whether the reflection method has been annotated
261 8
            if ($reflectionMethod->hasAnnotation($annotationName)) {
262 3
                array_push($annotatedRequestMethods, $requestMethod);
263 3
            }
264 8
        }
265
266
        // query whether at least one annotated request method has been found
267 8
        if (sizeof($annotatedRequestMethods) > 0) {
268
            // if yes, override the default request methods
269 3
            $this->setRequestMethods($annotatedRequestMethods);
270 3
        }
271
272
        // initialize the restrictions for the route placeholders
273 8
        if (is_array($restrictions = $annotationInstance->getRestrictions())) {
274
            foreach ($restrictions as $restriction) {
275
                list($name, $value) = $restriction;
276
                $this->restrictions[$name] = $value;
277
            }
278
        }
279
280
        // initialize the defaults for the route placeholders
281 8
        if (is_array($defaults = $annotationInstance->getDefaults())) {
282
            foreach ($defaults as $default) {
283
                list($name, $value) = $default;
284
                $this->defaults[$name] = $value;
285
            }
286
        }
287
288
        // return the instance
289 8
        return $this;
290
    }
291
292
    /**
293
     * Initializes a action configuration instance from the passed deployment descriptor node.
294
     *
295
     * @param \SimpleXmlElement $node The deployment node with the action configuration
296
     *
297
     * @return \AppserverIo\Routlt\Description\ActionDescriptorInterface The initialized descriptor
298
     */
299 1
    public function fromDeploymentDescriptor(\SimpleXmlElement $node)
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
300
    {
301 1
    }
302
303
    /**
304
     * Initializes a action configuration instance from the passed configuration node.
305
     *
306
     * @param \AppserverIo\Configuration\Interfaces\NodeInterface $node The configuration node with the action configuration
307
     *
308
     * @return \AppserverIo\Routlt\Description\ActionDescriptorInterface The initialized descriptor
309
     */
310
    public function fromConfiguration(NodeInterface $node)
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
311
    {
312
    }
313
314
    /**
315
     * Merges the passed configuration into this one. Configuration values
316
     * of the passed configuration will overwrite the this one.
317
     *
318
     * @param \AppserverIo\Routlt\Description\ActionDescriptorInterface $actionDescriptor The configuration to merge
319
     *
320
     * @return void
321
     * @throws \AppserverIo\Routlt\Description\DescriptorException Is thrown if the passed descriptor has a different method name
322
     */
323 2
    public function merge(ActionDescriptorInterface $actionDescriptor)
324
    {
325
326
        // check if the classes are equal
327 2
        if ($this->getMethodName() !== $actionDescriptor->getMethodName()) {
328 1
            throw new DescriptorException(
329 1
                sprintf('You try to merge a action configuration for % with %s', $actionDescriptor->getMethodName(), $this->getMethodName())
330 1
            );
331
        }
332
333
        // merge the name
334 1
        if ($name = $actionDescriptor->getName()) {
335 1
            $this->setName($name);
336 1
        }
337 1
    }
338
}
339