Completed
Push — di ( eef893...256938 )
by Tim
06:01
created

PathDescriptor::merge()   C

Complexity

Conditions 7
Paths 33

Size

Total Lines 35
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
c 0
b 0
f 0
rs 6.7272
cc 7
eloc 14
nc 33
nop 1
1
<?php
2
3
/**
4
 * AppserverIo\Routlt\Description\PathDescriptor
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\Routlt\Annotations\Path;
24
use AppserverIo\Routlt\Annotations\Result;
25
use AppserverIo\Routlt\Annotations\Results;
26
use AppserverIo\Lang\Reflection\ClassInterface;
27
use AppserverIo\Configuration\Interfaces\NodeInterface;
28
use AppserverIo\Description\DescriptorReferencesTrait;
29
use AppserverIo\Description\AbstractReferenceDescriptor;
30
use AppserverIo\Description\ReferenceDescriptorInterface;
31
32
/**
33
 * Annotation to map a request path info to an action method.
34
 *
35
 * @author     Tim Wagner <[email protected]>
36
 * @copyright  2015 TechDivision GmbH <[email protected]>
37
 * @license    http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
38
 * @link       http://github.com/appserver-io/routlt
39
 * @link       http://www.appserver.io
40
 */
41
class PathDescriptor extends AbstractReferenceDescriptor implements PathDescriptorInterface, ReferenceDescriptorInterface
42
{
43
44
    /**
45
     * The trait with the references descriptors.
46
     *
47
     * @var AppserverIo\Description\DescriptorReferencesTrait
48
     */
49
    use DescriptorReferencesTrait;
50
51
    /**
52
     * The beans class name.
53
     *
54
     * @var string
55
     */
56
    protected $className;
57
58
    /**
59
     * The array with the action methods.
60
     *
61
     * @var array
62
     */
63
    protected $actions = array();
64
65
    /**
66
     * The array with the action results.
67
     *
68
     * @var array
69
     */
70
    protected $results = array();
71
72
    /**
73
     * Sets the beans class name.
74
     *
75
     * @param string $className The beans class name
76
     *
77
     * @return void
78
     */
79
    public function setClassName($className)
80
    {
81
        $this->className = $className;
82
    }
83
84
    /**
85
     * Returns the beans class name.
86
     *
87
     * @return string The beans class name
88
     */
89
    public function getClassName()
90
    {
91
        return $this->className;
92
    }
93
94
    /**
95
     * Adds a action method configuration.
96
     *
97
     * @param \AppserverIo\Routlt\Description\ActionDescriptorInterface $action The action method configuration
98
     *
99
     * @return void
100
     */
101
    public function addAction(ActionDescriptorInterface $action)
102
    {
103
        $name = $action->getName();
104
        foreach ($action->getRequestMethods() as $method) {
105
            $this->actions[$name][$method] = $action;
106
        }
107
    }
108
109
    /**
110
     * Sets the array with the action methods.
111
     *
112
     * @param array $actions The action methods
113
     *
114
     * @return void
115
     */
116
    public function setActions(array $actions)
117
    {
118
        $this->actions = $actions;
119
    }
120
121
    /**
122
     * The array with the action methods.
123
     *
124
     * @return array The action methods
125
     */
126
    public function getActions()
127
    {
128
        return $this->actions;
129
    }
130
131
    /**
132
     * Adds a result action configuration.
133
     *
134
     * @param \AppserverIo\Routlt\Description\ResultDescriptorInterface $result The action result configuration
135
     *
136
     * @return void
137
     */
138
    public function addResult(ResultDescriptorInterface $result)
139
    {
140
        $this->results[$result->getName()] = $result;
141
    }
142
143
    /**
144
     * Sets the array with the action results.
145
     *
146
     * @param array $results The action results
147
     *
148
     * @return void
149
     */
150
    public function setResults(array $results)
151
    {
152
        $this->results = $results;
153
    }
154
155
    /**
156
     * The array with the action results.
157
     *
158
     * @return array The action results
159
     */
160
    public function getResults()
161
    {
162
        return $this->results;
163
    }
164
165
    /**
166
     * Returns a new descriptor instance.
167
     *
168
     * @return \AppserverIo\Routlt\Description\PathDescriptorInterface The descriptor instance
169
     */
170
    public static function newDescriptorInstance()
171
    {
172
        return new PathDescriptor();
173
    }
174
175
    /**
176
     * Returns a new annotation instance for the passed reflection class.
177
     *
178
     * @param \AppserverIo\Lang\Reflection\ClassInterface $reflectionClass The reflection class with the bean configuration
179
     *
180
     * @return \AppserverIo\Lang\Reflection\AnnotationInterface The reflection annotation
181
     */
182
    protected function newAnnotationInstance(ClassInterface $reflectionClass)
183
    {
184
        return $reflectionClass->getAnnotation(Path::ANNOTATION);
185
    }
186
187
    /**
188
     * Initializes the bean configuration instance from the passed reflection class instance.
189
     *
190
     * @param \AppserverIo\Lang\Reflection\ClassInterface $reflectionClass The reflection class with the bean configuration
191
     *
192
     * @return \AppserverIo\Routlt\Description\PathDescriptorInterface The initialized descriptor
193
     */
194
    public function fromReflectionClass(ClassInterface $reflectionClass)
195
    {
196
197
        // add the annotation alias to the reflection class
198
        $reflectionClass->addAnnotationAlias(Path::ANNOTATION, Path::__getClass());
199
        $reflectionClass->addAnnotationAlias(Result::ANNOTATION, Result::__getClass());
200
        $reflectionClass->addAnnotationAlias(Results::ANNOTATION, Results::__getClass());
201
202
        // query if we've an action
203
        if ($reflectionClass->implementsInterface('AppserverIo\Routlt\ActionInterface') === false &&
204
            $reflectionClass->toPhpReflectionClass()->isAbstract() === false) {
205
            // if not, do nothing
206
            return;
207
        }
208
209
        // query if we've a servlet with a @Path annotation
210
        if ($reflectionClass->hasAnnotation(Path::ANNOTATION) === false) {
211
            // if not, do nothing
212
            return;
213
        }
214
215
        // create a new annotation instance
216
        $reflectionAnnotation = $this->newAnnotationInstance($reflectionClass);
217
218
        // load class name
219
        $this->setClassName($reflectionClass->getName());
220
221
        // initialize the annotation instance
222
        $annotationInstance = $reflectionAnnotation->newInstance(
223
            $reflectionAnnotation->getAnnotationName(),
224
            $reflectionAnnotation->getValues()
225
        );
226
227
        // load the default name to register in naming directory
228
        if ($nameAttribute = $annotationInstance->getName()) {
229
            $name = $nameAttribute;
230
        } else {
231
            // if @Annotation(name=****) is NOT set, we use the class name by default
232
            $name = strtolower(str_replace('\\', '/', $reflectionClass->getName()));
233
        }
234
235
        // prepare and set the name
236
        $this->setName(sprintf('/%s', ltrim($name, '/')));
237
238
        // we've to check for method annotations that declare the action methods
239
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
240
            if ($action = ActionDescriptor::newDescriptorInstance()->fromReflectionMethod($reflectionMethod)) {
241
                $this->addAction($action);
242
            }
243
        }
244
245
        // we've to check for result annotations
246
        if ($reflectionClass->hasAnnotation(Results::ANNOTATION)) {
247
            // create the reflection annotation instance
248
            $resultsAnnotation = $reflectionClass->getAnnotation(Results::ANNOTATION);
249
250
            // initialize the @Results annotation instance
251
            $resultsAnnotationInstance = $resultsAnnotation->newInstance(
252
                $resultsAnnotation->getAnnotationName(),
253
                $resultsAnnotation->getValues()
254
            );
255
256
            // load the results
257
            foreach ($resultsAnnotationInstance->getResults() as $resultAnnotation) {
258
                $this->addResult(ResultDescriptor::newDescriptorInstance()->fromReflectionAnnotation($resultAnnotation));
259
            }
260
        }
261
262
        // initialize references from the passed reflection class
263
        $this->referencesFromReflectionClass($reflectionClass);
264
265
        // return the instance
266
        return $this;
267
    }
268
269
    /**
270
     * Initializes a bean configuration instance from the passed deployment descriptor node.
271
     *
272
     * @param \SimpleXmlElement $node The deployment node with the bean configuration
273
     *
274
     * @return \AppserverIo\Routlt\Description\PathDescriptorInterface The initialized descriptor
275
     */
276
    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...
277
    {
278
    }
279
280
    /**
281
     * Initializes a bean configuration instance from the passed configuration node.
282
     *
283
     * @param \AppserverIo\Configuration\Interfaces\NodeInterface $node The configuration node with the bean configuration
284
     *
285
     * @return \AppserverIo\Routlt\Description\PathDescriptorInterface The initialized descriptor
286
     */
287
    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...
288
    {
289
    }
290
291
    /**
292
     * Merges the passed configuration into this one. Configuration values
293
     * of the passed configuration will overwrite the this one.
294
     *
295
     * @param \AppserverIo\Routlt\Description\PathDescriptorInterface $pathDescriptor The configuration to merge
296
     *
297
     * @return void
298
     * @throws \AppserverIo\Routlt\Description\DescriptorException Is thrown if the passed descriptor has a different class name
299
     */
300
    public function merge(PathDescriptorInterface $pathDescriptor)
301
    {
302
303
        // check if the classes are equal
304
        if ($this->getClassName() !== $pathDescriptor->getClassName()) {
305
            throw new DescriptorException(
306
                sprintf('You try to merge a path configuration for % with %s', $pathDescriptor->getClassName(), $this->getClassName())
307
            );
308
        }
309
310
        // merge the name
311
        if ($name = $pathDescriptor->getName()) {
312
            $this->setName($name);
313
        }
314
315
        // merge the action method descriptors
316
        foreach ($pathDescriptor->getActions() as $action) {
317
            $this->addAction($action);
318
        }
319
320
        // merge the result descriptors
321
        foreach ($pathDescriptor->getResults() as $result) {
322
            $this->addResult($result);
323
        }
324
325
        // merge the EPB references
326
        foreach ($pathDescriptor->getEpbReferences() as $epbReference) {
327
            $this->addEpbReference($epbReference);
328
        }
329
330
        // merge the EPB references
331
        foreach ($pathDescriptor->getResReferences() as $resReference) {
332
            $this->addResReference($resReference);
333
        }
334
    }
335
}
336