| 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 instanceof IEntityContainer) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |                 $foundTarget = ($container->findEntitySet($entitySet->getName()) != null); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 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 |  |  |         if ($functionImport instanceof IFunctionImport) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |             EdmUtil::checkArgumentNull($functionImport->getName(), 'functionImport->getName'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 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 |  |  |             EdmUtil::checkArgumentNull($paramName, 'functionParameter->getName'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             $declaringFunction = $functionParameter->getDeclaringFunction(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             switch (true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |                 case $declaringFunction instanceof IFunction: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |                     $functions = $context->getModel()->FindFunctions($declaringFunction->FullName()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |                 case $declaringFunction instanceof IFunctionImport: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |                     $container = $declaringFunction->getContainer(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                     assert($container instanceof IEntityContainer); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |                     $functions = $container->findFunctionImports($declaringFunction->getName()); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |                 default: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                     return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             // For all functions with this name declared in the model check if it has | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |             // a parameter with this name | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |             return 0 < count(array_filter($functions, function (IFunctionBase $func) use ($paramName) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |                 return null !== $func->findParameter($paramName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |             })); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |             // Only validate annotations targeting elements that can be found via the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |             // model API. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |             // E.g. annotations targeting annotations will not be valid without this branch. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |             $foundTarget = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |         return $foundTarget; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 141 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 142 |  |  |  |