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

PathDescriptor::newAnnotationInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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