Passed
Pull Request — master (#44)
by Alex
02:47
created

findTarget()   C

Complexity

Conditions 15
Paths 13

Size

Total Lines 86
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 15
eloc 62
c 1
b 0
f 0
nc 13
nop 2
dl 0
loc 86
rs 5.9166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
6
namespace AlgoWeb\ODataMetadata\Edm\Validation\ValidationRules\IVocabularyAnnotation;
7
8
use AlgoWeb\ODataMetadata\Edm\Validation\EdmErrorCode;
9
use AlgoWeb\ODataMetadata\Edm\Validation\ValidationContext;
10
use AlgoWeb\ODataMetadata\EdmUtil;
11
use AlgoWeb\ODataMetadata\Interfaces\Annotations\IVocabularyAnnotation;
12
use AlgoWeb\ODataMetadata\Interfaces\IEdmElement;
13
use AlgoWeb\ODataMetadata\Interfaces\IEntityContainer;
14
use AlgoWeb\ODataMetadata\Interfaces\IEntitySet;
15
use AlgoWeb\ODataMetadata\Interfaces\IFunction;
16
use AlgoWeb\ODataMetadata\Interfaces\IFunctionBase;
17
use AlgoWeb\ODataMetadata\Interfaces\IFunctionImport;
18
use AlgoWeb\ODataMetadata\Interfaces\IFunctionParameter;
19
use AlgoWeb\ODataMetadata\Interfaces\IProperty;
20
use AlgoWeb\ODataMetadata\Interfaces\ISchemaType;
21
use AlgoWeb\ODataMetadata\Interfaces\IStructuredType;
22
use AlgoWeb\ODataMetadata\Interfaces\ITerm;
23
use AlgoWeb\ODataMetadata\StringConst;
24
25
/**
26
 * Validates that a vocabulary annotations target can be found through the model containing the annotation.
27
 *
28
 * @package AlgoWeb\ODataMetadata\Edm\Validation\ValidationRules\IVocabularyAnnotation
29
 */
30
class VocabularyAnnotationInaccessibleTarget extends VocabularyAnnotationRule
31
{
32
    public function __invoke(ValidationContext $context, ?IEdmElement $annotation)
33
    {
34
        assert($annotation instanceof IVocabularyAnnotation);
35
        $target      = $annotation->getTarget();
36
        $foundTarget = $this->findTarget($context, $target);
37
38
        if (!$foundTarget) {
39
            EdmUtil::checkArgumentNull($annotation->Location(), 'annotation->Location');
40
            $context->AddError(
41
                $annotation->Location(),
42
                EdmErrorCode::BadUnresolvedTarget(),
43
                StringConst::EdmModel_Validator_Semantic_InaccessibleTarget(EdmUtil::FullyQualifiedName($target))
44
            );
45
        }
46
    }
47
48
    /**
49
     * @param ValidationContext $context
50
     * @param \AlgoWeb\ODataMetadata\Interfaces\IVocabularyAnnotatable $target
51
     * @return bool
52
     */
53
    protected function findTarget(
54
        ValidationContext $context,
55
        \AlgoWeb\ODataMetadata\Interfaces\IVocabularyAnnotatable $target
56
    ): bool {
57
        $foundTarget = false;
58
        $entityContainer = $target;
59
        if ($entityContainer instanceof IEntityContainer) {
60
            $foundTarget = ($context->getModel()->findEntityContainer($entityContainer->FullName()) != null);
61
            return $foundTarget;
62
        }
63
        $entitySet = $target;
64
        if ($entitySet instanceof IEntitySet) {
65
            $container = $entitySet->getContainer();
66
            if ($container != null && $container instanceof IEntityContainer) {
67
                $foundTarget = ($container->findEntitySet($entitySet->getName()) != null);
0 ignored issues
show
Bug introduced by
It seems like $entitySet->getName() can also be of type null; however, parameter $setName of AlgoWeb\ODataMetadata\In...tainer::findEntitySet() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
                $foundTarget = ($container->findEntitySet(/** @scrutinizer ignore-type */ $entitySet->getName()) != null);
Loading history...
68
                return $foundTarget;
69
            }
70
            return false;
71
        }
72
        $schemaType = $target;
73
        if ($schemaType instanceof ISchemaType) {
74
            $foundTarget = ($context->getModel()->FindType($schemaType->FullName()) != null);
75
            return $foundTarget;
76
        }
77
        $term = $target;
78
        if ($term instanceof ITerm) {
79
            $foundTarget = ($context->getModel()->FindValueTerm($term->FullName()) != null);
80
            return $foundTarget;
81
        }
82
        $function = $target;
83
        if ($function instanceof IFunction) {
84
            $foundTarget = count($context->getModel()->FindFunctions($function->FullName())) > 0;
85
            return $foundTarget;
86
        }
87
        $functionImport = $target;
88
        EdmUtil::checkArgumentNull($functionImport->getName(), 'functionImport->getName');
0 ignored issues
show
Bug introduced by
The method getName() does not exist on AlgoWeb\ODataMetadata\In...\IVocabularyAnnotatable. It seems like you code against a sub-type of said class. However, the method does not exist in AlgoWeb\ODataMetadata\Li...Internal\Bad\BadElement or AlgoWeb\ODataMetadata\Library\Internal\Bad\BadType or AlgoWeb\ODataMetadata\Li...l\Bad\BadPrimitiveValue or AlgoWeb\ODataMetadata\Li...\BadEntityReferenceType or AlgoWeb\ODataMetadata\Li...l\Bad\BadCollectionType or AlgoWeb\ODataMetadata\Li...l\Bad\BadStructuredType or AlgoWeb\ODataMetadata\Li...Internal\Bad\BadRowType. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
        EdmUtil::checkArgumentNull($functionImport->/** @scrutinizer ignore-call */ getName(), 'functionImport->getName');
Loading history...
89
        if ($functionImport instanceof IFunctionImport) {
90
            $funcName = $functionImport->getName();
91
            $foundTarget = count($functionImport->getContainer()->findFunctionImports($funcName)) > 0;
92
            return $foundTarget;
93
        }
94
        $typeProperty = $target;
95
        if ($typeProperty instanceof IProperty) {
96
            $declaringType = $typeProperty->getDeclaringType();
97
            assert($declaringType instanceof ISchemaType);
98
            $declaringTypeFullName = EdmUtil::FullyQualifiedName($declaringType);
99
            EdmUtil::checkArgumentNull($declaringTypeFullName, 'declaringTypeFullName');
100
            EdmUtil::checkArgumentNull($typeProperty->getName(), 'typeProperty->getName');
101
            $modelType = $context->getModel()->FindType($declaringTypeFullName);
102
            if ($modelType !== null && $modelType instanceof IStructuredType) {
103
                // If we can find a structured type with this name in the model check if it
104
                // has a property with this name
105
                $foundTarget = ($modelType->findProperty($typeProperty->getName()) != null);
106
                return $foundTarget;
107
            }
108
            return false;
109
        }
110
        $functionParameter = $target;
111
        if ($functionParameter instanceof IFunctionParameter) {
112
            $paramName = $functionParameter->getName();
113
            $declaringFunction = $functionParameter->getDeclaringFunction();
114
            switch (true) {
115
                case $declaringFunction instanceof IFunction:
116
                    $functions = $context->getModel()->FindFunctions($declaringFunction->FullName());
117
                    break;
118
                case $declaringFunction instanceof IFunctionImport:
119
                    $container = $declaringFunction->getContainer();
120
                    assert($container instanceof IEntityContainer);
121
                    $functions = $container->findFunctionImports($declaringFunction->getName());
0 ignored issues
show
Bug introduced by
It seems like $declaringFunction->getName() can also be of type null; however, parameter $functionName of AlgoWeb\ODataMetadata\In...::findFunctionImports() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

121
                    $functions = $container->findFunctionImports(/** @scrutinizer ignore-type */ $declaringFunction->getName());
Loading history...
122
                    break;
123
                default:
124
                    return false;
125
            }
126
127
            // For all functions with this name declared in the model check if it has
128
            // a parameter with this name
129
            return 0 < count(array_filter($functions, function (IFunctionBase $func) use ($paramName) {
130
                return null !== $func->findParameter($paramName);
0 ignored issues
show
Bug introduced by
It seems like $paramName can also be of type null; however, parameter $name of AlgoWeb\ODataMetadata\In...onBase::findParameter() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

130
                return null !== $func->findParameter(/** @scrutinizer ignore-type */ $paramName);
Loading history...
131
            }));
132
        } else {
133
            // Only validate annotations targeting elements that can be found via the
134
            // model API.
135
            // E.g. annotations targeting annotations will not be valid without this branch.
136
            $foundTarget = true;
137
        }
138
        return $foundTarget;
139
    }
140
}
141