Completed
Pull Request — master (#49)
by Alex
04:02
created

ProvidersWrapper::validateResourceType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
namespace POData\Providers;
4
5
use POData\Providers\Metadata\ResourceTypeKind;
6
use POData\Providers\Metadata\ResourceSetWrapper;
7
use POData\Providers\Metadata\ResourceType;
8
use POData\Providers\Metadata\ResourceProperty;
9
use POData\Providers\Metadata\ResourceSet;
10
use POData\Providers\Metadata\ResourceAssociationSet;
11
use POData\Configuration\ServiceConfiguration;
12
use POData\UriProcessor\QueryProcessor\SkipTokenParser\InternalSkipTokenInfo;
13
use POData\UriProcessor\ResourcePathProcessor\SegmentParser\KeyDescriptor;
14
use POData\Common\ODataException;
15
use POData\Common\Messages;
16
use POData\Providers\Metadata\EdmSchemaVersion;
17
use POData\Providers\Query\IQueryProvider;
18
use POData\Providers\Metadata\IMetadataProvider;
19
use POData\Providers\Expression\IExpressionProvider;
20
use POData\Common\InvalidOperationException;
21
use POData\UriProcessor\QueryProcessor\ExpressionParser\FilterInfo;
22
use POData\UriProcessor\QueryProcessor\OrderByParser\InternalOrderByInfo;
23
use POData\Providers\Query\QueryResult;
24
use POData\Providers\Query\QueryType;
25
26
/**
27
 * Class ProvidersWrapper.
28
 *
29
 * A wrapper class over IMetadataProvider and IQueryProvider implementations, All calls to implementation of methods
30
 * of these interfaces should go through this wrapper class so that wrapper methods of this class can perform validation
31
 */
32
class ProvidersWrapper
33
{
34
    /**
35
     * Holds reference to IMetadataProvider implementation.
36
     *
37
     * @var IMetadataProvider
38
     */
39
    private $metaProvider;
40
41
    /**
42
     * Holds reference to IServiceConfiguration implementation.
43
     *
44
     * @var ServiceConfiguration
45
     */
46
    private $config;
47
48
    /*
49
     * Holds reference to ProvidersQueryWrapper implementation
50
     *
51
     * @var ProvidersQueryWrapper
52
     */
53
    private $providerWrapper;
54
55
    /**
56
     * Cache for ResourceProperties of a resource type that belongs to a
57
     * resource set. An entry (ResourceProperty collection) in this cache
58
     * contains only the visible properties of ResourceType.
59
     *
60
     * @var array(string, array(string, ResourceProperty))
61
     */
62
    private $propertyCache;
63
64
    /**
65
     * Cache for ResourceSetWrappers. If ResourceSet is invisible value will
66
     * be null.
67
     *
68
     * @var ResourceSetWrapper[] indexed by resource set name
69
     */
70
    private $setWrapperCache;
71
72
    /**
73
     * Cache for ResourceTypes.
74
     *
75
     * @var ResourceType[] indexed by resource type name
76
     */
77
    private $typeCache;
78
79
    /**
80
     * Cache for ResourceAssociationSet. If ResourceAssociationSet is invisible
81
     * value will be null.
82
     *
83
     * @var ResourceAssociationSet[] indexed by name
84
     */
85
    private $associationSetCache;
86
87
    /**
88
     * Creates a new instance of ProvidersWrapper.
89
     *
90
     * @param IMetadataProvider     $meta   Reference to IMetadataProvider implementation
91
     * @param IQueryProvider        $query  Reference to IQueryProvider implementation
92
     * @param ServiceConfiguration  $config Reference to IServiceConfiguration implementation
93
     */
94
    public function __construct(IMetadataProvider $meta, IQueryProvider $query, ServiceConfiguration $config)
95
    {
96
        $this->metaProvider = $meta;
97
        $this->config = $config;
98
        $this->providerWrapper = new ProvidersQueryWrapper($query);
99
        $this->setWrapperCache = array();
100
        $this->typeCache = array();
101
        $this->associationSetCache = array();
102
        $this->propertyCache = array();
103
    }
104
105
    //Wrappers for IMetadataProvider methods
106
107
    /**
108
     * To get the Container name for the data source,
109
     * Note: Wrapper for IMetadataProvider::getContainerName method
110
     * implementation.
111
     *
112
     * @return string that contains the name of the container
113
     *
114
     * @throws ODataException Exception if implementation returns empty container name
115
     */
116
    public function getContainerName()
117
    {
118
        $containerName = $this->metaProvider->getContainerName();
119
        if (empty($containerName)) {
120
            throw new ODataException(
121
                Messages::providersWrapperContainerNameMustNotBeNullOrEmpty(),
122
                500
123
            );
124
        }
125
126
        return $containerName;
127
    }
128
129
    /**
130
     * To get Namespace name for the data source,
131
     * Note: Wrapper for IMetadataProvider::getContainerNamespace method implementation.
132
     *
133
     * @return string that contains the namespace name
134
     *
135
     * @throws ODataException Exception if implementation returns empty container namespace
136
     */
137
    public function getContainerNamespace()
138
    {
139
        $containerNamespace = $this->metaProvider->getContainerNamespace();
140
        if (empty($containerNamespace)) {
141
            throw new ODataException(
142
                Messages::providersWrapperContainerNamespaceMustNotBeNullOrEmpty(),
143
                500
144
            );
145
        }
146
147
        return $containerNamespace;
148
    }
149
150
    /**
151
     * To get the data service configuration.
152
     *
153
     * @return ServiceConfiguration
154
     */
155
    public function getConfiguration()
156
    {
157
        return $this->config;
158
    }
159
160
    /**
161
     *  To get all entity set information,
162
     *  Note: Wrapper for IMetadataProvider::getResourceSets method implementation,
163
     *  This method returns array of ResourceSetWrapper instances but the corresponding IDSMP method
164
     *  returns array of ResourceSet instances.
165
     *
166
     *  @return ResourceSetWrapper[] The ResourceSetWrappers for the visible ResourceSets
167
     *
168
     *  @throws ODataException when two resource sets with the same name are encountered
169
     */
170
    public function getResourceSets()
171
    {
172
        $resourceSets = $this->metaProvider->getResourceSets();
173
        $resourceSetWrappers = array();
174
        $resourceSetNames = array();
175
        foreach ($resourceSets as $resourceSet) {
176
            $name = $resourceSet->getName();
177
            if (in_array($name, $resourceSetNames)) {
178
                throw new ODataException(Messages::providersWrapperEntitySetNameShouldBeUnique($name), 500);
179
            }
180
181
            $resourceSetNames[] = $name;
182
            $resourceSetWrapper = $this->_validateResourceSetAndGetWrapper($resourceSet);
183
            if (!is_null($resourceSetWrapper)) {
184
                $resourceSetWrappers[] = $resourceSetWrapper;
185
            }
186
        }
187
188
        return $resourceSetWrappers;
189
    }
190
191
    /**
192
     * To get all resource types in the data source,
193
     * Note: Wrapper for IMetadataProvider::getTypes method implementation.
194
     *
195
     * @return ResourceType[]
196
     */
197
    public function getTypes()
198
    {
199
        $resourceTypes = $this->metaProvider->getTypes();
200
        $resourceTypeNames = array();
201
        foreach ($resourceTypes as $resourceType) {
202
            if (in_array($resourceType->getName(), $resourceTypeNames)) {
203
                throw new ODataException(
204
                    Messages::providersWrapperEntityTypeNameShouldBeUnique($resourceType->getName()),
205
                    500
206
                );
207
            }
208
209
            $resourceTypeNames[] = $resourceType->getName();
210
            $this->validateResourceType($resourceType);
211
        }
212
213
        return $resourceTypes;
214
    }
215
216
    /**
217
     * To get a resource set based on the specified resource set name which is
218
     * visible,
219
     * Note: Wrapper for IMetadataProvider::resolveResourceSet method
220
     * implementation.
221
     *
222
     * @param string $name Name of the resource set
223
     *
224
     * @return ResourceSetWrapper|null Returns resource set with the given name if found,
225
     *                                 NULL if resource set is set to invisible or not found
226
     */
227
    public function resolveResourceSet($name)
228
    {
229
        if (array_key_exists($name, $this->setWrapperCache)) {
230
            return $this->setWrapperCache[$name];
231
        }
232
233
        $resourceSet = $this->metaProvider->resolveResourceSet($name);
234
        if (is_null($resourceSet)) {
235
            return null;
236
        }
237
238
        return $this->_validateResourceSetAndGetWrapper($resourceSet);
239
    }
240
241
    /**
242
     * To get a resource type based on the resource set name,
243
     * Note: Wrapper for IMetadataProvider::resolveResourceType
244
     * method implementation.
245
     *
246
     * @param string $name Name of the resource set
247
     *
248
     * @return ResourceType|null resource type with the given resource set name if found else NULL
249
     *
250
     * @throws ODataException If the ResourceType is invalid
251
     */
252
    public function resolveResourceType($name)
253
    {
254
        $resourceType = $this->metaProvider->resolveResourceType($name);
255
        if (is_null($resourceType)) {
256
            return null;
257
        }
258
259
        return $this->validateResourceType($resourceType);
260
    }
261
262
    /**
263
     * The method must return a collection of all the types derived from
264
     * $resourceType The collection returned should NOT include the type
265
     * passed in as a parameter
266
     * Note: Wrapper for IMetadataProvider::getDerivedTypes
267
     * method implementation.
268
     *
269
     * @param ResourceType $resourceType Resource to get derived resource types from
270
     *
271
     * @return ResourceType[]
272
     *
273
     * @throws InvalidOperationException when the meat provider doesn't return an array
274
     */
275
    public function getDerivedTypes(ResourceType $resourceType)
276
    {
277
        $derivedTypes = $this->metaProvider->getDerivedTypes($resourceType);
278
        if (!is_array($derivedTypes)) {
279
            throw new InvalidOperationException(
280
                Messages::metadataAssociationTypeSetInvalidGetDerivedTypesReturnType($resourceType->getName())
281
            );
282
        }
283
284
        foreach ($derivedTypes as $derivedType) {
285
            $this->validateResourceType($derivedType);
286
        }
287
288
        return $derivedTypes;
289
    }
290
291
    /**
292
     * Returns true if $resourceType represents an Entity Type which has derived
293
     * Entity Types, else false.
294
     * Note: Wrapper for IMetadataProvider::hasDerivedTypes method
295
     * implementation.
296
     *
297
     * @param ResourceType $resourceType Resource to check for derived resource
298
     *                                   types
299
     *
300
     * @return bool
301
     *
302
     * @throws ODataException If the ResourceType is invalid
303
     */
304
    public function hasDerivedTypes(ResourceType $resourceType)
305
    {
306
        $this->validateResourceType($resourceType);
307
308
        return $this->metaProvider->hasDerivedTypes($resourceType);
309
    }
310
311
    /**
312
     * Gets the ResourceAssociationSet instance for the given source association end,
313
     * Note: Wrapper for IMetadataProvider::getResourceAssociationSet
314
     * method implementation.
315
     *
316
     * @param ResourceSet      $set      Resource set of the source association end
317
     * @param ResourceType     $type     Resource type of the source association end
318
     * @param ResourceProperty $property Resource property of the source association end
319
     *
320
     * @return ResourceAssociationSet|null Returns ResourceAssociationSet for the source
321
     *                                     association end, NULL if no such
322
     *                                     association end or resource set in the
323
     *                                     other end of the association is invisible
324
     */
325
    public function getResourceAssociationSet(
326
        ResourceSet $set,
327
        ResourceType $type,
328
        ResourceProperty $property
329
    ) {
330
        $type = $this->getResourceTypeWherePropertyIsDeclared($type, $property);
331
        // usage below requires $type to not be null - so kaboom as early as possible
332
        assert(null != $type, "Resource type obtained from property must not be null.");
333
        $cacheKey = $set->getName() . '_' . $type->getName() . '_' . $property->getName();
334
335
        if (array_key_exists($cacheKey, $this->associationSetCache)) {
336
            return $this->associationSetCache[$cacheKey];
337
        }
338
339
        $associationSet = $this->metaProvider->getResourceAssociationSet(
340
            $set,
341
            $type,
342
            $property
343
        );
344
345
        if (!is_null($associationSet)) {
346
            $thisAssociationSetEnd = $associationSet->getResourceAssociationSetEnd(
347
                $set,
348
                $type,
349
                $property
350
            );
351
352
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
353
                $set,
354
                $type,
355
                $property
356
            );
357
358
            //If either $thisAssociationSetEnd and/or $relatedAssociationSetEnd
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
359
            //is null means the associationset we got from the IDSMP::getResourceAssociationSet is invalid.
360
361
            //Return null, if either AssociationSet's End1 or End2's resourceset name
362
            //doesn't match the name of resource set wrapper (param1) and resource type is not assignable
363
            //from given resource type (param2)
364
            if (is_null($thisAssociationSetEnd) || is_null($relatedAssociationSetEnd)) {
365
                throw new ODataException(
366
                    Messages::providersWrapperIDSMPGetResourceSetReturnsInvalidResourceSet(
367
                        $set->getName(),
368
                        $type->getFullName(),
369
                        $property->getName()
370
                    ),
371
                    500
372
                );
373
            }
374
375
            $relatedResourceSetWrapper = $this->_validateResourceSetAndGetWrapper(
376
                $relatedAssociationSetEnd->getResourceSet()
377
            );
378
            if ($relatedResourceSetWrapper === null) {
379
                $associationSet = null;
380
            } else {
381
                $this->validateResourceType($thisAssociationSetEnd->getResourceType());
382
                $this->validateResourceType($relatedAssociationSetEnd->getResourceType());
383
            }
384
        }
385
386
        $this->associationSetCache[$cacheKey] = $associationSet;
387
388
        return $associationSet;
389
    }
390
391
    /**
392
     * Gets the target resource set wrapper for the given navigation property,
393
     * source resource set wrapper and the source resource type.
394
     *
395
     * @param ResourceSetWrapper $resourceSetWrapper         Source resource set
396
     * @param ResourceType       $resourceType               Source resource type
397
     * @param ResourceProperty   $navigationResourceProperty Navigation property
398
     *
399
     * @return ResourceSetWrapper|null Returns instance of ResourceSetWrapper
400
     *                                 (describes the entity set and associated configuration) for the
401
     *                                 given navigation property. returns NULL if resourceset for the
402
     *                                 navigation property is invisible or if metadata provider returns
403
     *                                 null resource association set
404
     */
405
    public function getResourceSetWrapperForNavigationProperty(
406
        ResourceSetWrapper $resourceSetWrapper,
407
        ResourceType $resourceType,
408
        ResourceProperty $navigationResourceProperty
409
    ) {
410
        $associationSet = $this->getResourceAssociationSet(
411
            $resourceSetWrapper,
412
            $resourceType,
413
            $navigationResourceProperty
414
        );
415
416
        if (!is_null($associationSet)) {
417
            $relatedAssociationSetEnd = $associationSet->getRelatedResourceAssociationSetEnd(
418
                $resourceSetWrapper->getResourceSet(),
419
                $resourceType,
420
                $navigationResourceProperty
421
            );
422
423
            return $this->_validateResourceSetAndGetWrapper(
424
                $relatedAssociationSetEnd->getResourceSet()
425
            );
426
        }
427
428
        return null;
429
    }
430
431
    /**
432
     * Gets the visible resource properties for the given resource type from the given resource set wrapper.
433
     *
434
     * @param ResourceSetWrapper $setWrapper   Resource set wrapper in question
435
     * @param ResourceType       $resourceType Resource type in question
436
     *
437
     * @return ResourceProperty[] Collection of visible resource properties from the given resource set wrapper
438
     *                            and resource type
439
     */
440
    public function getResourceProperties(ResourceSetWrapper $setWrapper, ResourceType $resourceType)
441
    {
442
        if ($resourceType->getResourceTypeKind() != ResourceTypeKind::ENTITY) {
443
            //Complex resource type
444
            return $resourceType->getAllProperties();
445
        }
446
        //TODO: move this to doctrine annotations
447
        $cacheKey = $setWrapper->getName() . '_' . $resourceType->getFullName();
448
        if (!array_key_exists($cacheKey, $this->propertyCache)) {
449
            //Fill the cache
450
            $this->propertyCache[$cacheKey] = array();
451
            foreach ($resourceType->getAllProperties() as $resourceProperty) {
452
                //Check whether this is a visible navigation property
453
                //TODO: is this broken?? see #87
454
                if ($resourceProperty->getTypeKind() == ResourceTypeKind::ENTITY
455
                    && !is_null($this->getResourceSetWrapperForNavigationProperty(
456
                        $setWrapper,
457
                        $resourceType,
458
                        $resourceProperty
459
                    ))
460
                ) {
461
                    $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
462
                } else {
463
                    //primitive, bag or complex property
464
                    $this->propertyCache[$cacheKey][$resourceProperty->getName()] = $resourceProperty;
465
                }
466
            }
467
        }
468
469
        return $this->propertyCache[$cacheKey];
470
    }
471
472
    /**
473
     * Wrapper function over _validateResourceSetAndGetWrapper function.
474
     *
475
     * @param ResourceSet $resourceSet see the comments of _validateResourceSetAndGetWrapper
476
     *
477
     * @return ResourceSetWrapper|null see the comments of _validateResourceSetAndGetWrapper
478
     */
479
    public function validateResourceSetAndGetWrapper(ResourceSet $resourceSet)
480
    {
481
        return $this->_validateResourceSetAndGetWrapper($resourceSet);
482
    }
483
484
    /**
485
     * Gets the Edm Schema version compliance to the metadata.
486
     *
487
     * @return EdmSchemaVersion
488
     */
489
    public function getEdmSchemaVersion()
490
    {
491
        //The minimal schema version for custom provider is 1.1
492
        return EdmSchemaVersion::VERSION_1_DOT_1;
493
    }
494
495
    /**
496
     * This function perform the following operations
497
     *  (1) If the cache contain an entry [key, value] for the resourceset then
498
     *      return the entry-value
499
     *  (2) If the cache not contain an entry for the resourceset then validate
500
     *      the resourceset
501
     *            (a) If valid add entry as [resouceset_name, resourceSetWrapper]
502
     *            (b) if not valid add entry as [resouceset_name, null]
503
     *  Note: validating a resourceset means checking the resourceset is visible
504
     *  or not using configuration.
505
     *
506
     * @param ResourceSet $resourceSet The resourceset to validate and get the
507
     *                                 wrapper for
508
     *
509
     * @return ResourceSetWrapper|null Returns an instance if a resource set with the given name is visible
510
     */
511
    private function _validateResourceSetAndGetWrapper(ResourceSet $resourceSet)
512
    {
513
        $cacheKey = $resourceSet->getName();
514
        if (array_key_exists($cacheKey, $this->setWrapperCache)) {
515
            return $this->setWrapperCache[$cacheKey];
516
        }
517
518
        $this->validateResourceType($resourceSet->getResourceType());
519
        $wrapper = new ResourceSetWrapper($resourceSet, $this->config);
520
        $nuVal = $wrapper->isVisible() ? $wrapper : null;
521
        $this->setWrapperCache[$cacheKey] = $nuVal;
522
523
        return $this->setWrapperCache[$cacheKey];
524
    }
525
526
    /**
527
     * Validates the given instance of ResourceType.
528
     *
529
     * @param ResourceType $resourceType The ResourceType to validate
530
     *
531
     * @return ResourceType
532
     *
533
     * @throws ODataException Exception if $resourceType is invalid
534
     */
535
    private function validateResourceType(ResourceType $resourceType)
536
    {
537
        $cacheKey = $resourceType->getName();
538
        if (array_key_exists($cacheKey, $this->typeCache)) {
539
            return $this->typeCache[$cacheKey];
540
        }
541
542
        //TODO: Do validation if any for the ResourceType
543
        $this->typeCache[$cacheKey] = $resourceType;
544
545
        return $resourceType;
546
    }
547
548
    /**
549
     * Gets the resource type on which the resource property is declared on,
550
     * If property is not declared in the given resource type, then this
551
     * function drill down to the inheritance hierarchy of the given resource
552
     * type to find out the base class in which the property is declared.
553
     *
554
     * @param ResourceType     $type     The resource type to start looking
555
     * @param ResourceProperty $property The resource property in question
556
     *
557
     * @return ResourceType|null Returns reference to the ResourceType on which
558
     *                           the $property is declared, NULL if
559
     *                           $property is not declared anywhere
560
     *                           in the inheritance hierarchy
561
     */
562
    private function getResourceTypeWherePropertyIsDeclared(ResourceType $type, ResourceProperty $property)
563
    {
564
        while (null !== $type) {
565
            if (null !== $type->resolvePropertyDeclaredOnThisType($property->getName())) {
566
                break;
567
            }
568
569
            $type = $type->getBaseType();
570
        }
571
572
        return $type;
573
    }
574
575
    /**
576
     * Gets the underlying custom expression provider, the end developer is
577
     * responsible for implementing IExpressionProvider if he choose for.
578
     *
579
     * @return IExpressionProvider Instance of IExpressionProvider implementation
580
     */
581
    public function getExpressionProvider()
582
    {
583
        return $this->providerWrapper->getExpressionProvider();
584
    }
585
586
    /**
587
     * Indicates if the QueryProvider can handle ordered paging, this means respecting order, skip, and top parameters
588
     * If the query provider can not handle ordered paging, it must return the entire result set and POData will
589
     * perform the ordering and paging.
590
     *
591
     * @return bool True if the query provider can handle ordered paging, false if POData should perform the paging
592
     */
593
    public function handlesOrderedPaging()
594
    {
595
        return $this->providerWrapper->handlesOrderedPaging();
596
    }
597
598
    /**
599
     * Gets collection of entities belongs to an entity set.
600
     *
601
     * @param QueryType             $queryType   Indicates if this is a query for a count, entities, or entities with a
602
     *                                           count
603
     * @param ResourceSet           $resourceSet The entity set containing the entities that need to be fetched
604
     * @param FilterInfo            $filterInfo  Represents the $filter parameter of the OData query.
605
     *                                           NULL if no $filter specified
606
     * @param InternalOrderByInfo   $orderBy     The orderBy information
607
     * @param int                   $top         The top count
608
     * @param int                   $skip        The skip count
609
     * @param InternalSkipTokenInfo $skipToken   The skip token
610
     *
611
     * @return QueryResult
612
     */
613
    public function getResourceSet(
614
        QueryType $queryType,
615
        ResourceSet $resourceSet,
616
        FilterInfo $filterInfo = null,
617
        InternalOrderByInfo $orderBy = null,
618
        $top = null,
619
        $skip = null,
620
        InternalSkipTokenInfo $skipToken = null
621
    ) {
622
        return $this->providerWrapper->getResourceSet(
623
            $queryType,
624
            $resourceSet,
625
            $filterInfo,
626
            $orderBy,
627
            $top,
628
            $skip,
629
            $skipToken
630
        );
631
    }
632
633
    /**
634
     * Gets an entity instance from an entity set identified by a key.
635
     *
636
     * @param ResourceSet   $resourceSet   The entity set containing the entity to fetch
637
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to fetch
638
     *
639
     * @return object|null Returns entity instance if found else null
640
     */
641
    public function getResourceFromResourceSet(ResourceSet $resourceSet, KeyDescriptor $keyDescriptor)
642
    {
643
        return $this->providerWrapper->getResourceFromResourceSet($resourceSet, $keyDescriptor);
644
    }
645
646
    /**
647
     * Puts an entity instance to entity set identified by a key.
648
     *
649
     * @param ResourceSet   $resourceSet   The entity set containing the entity to update
650
     * @param KeyDescriptor $keyDescriptor The key identifying the entity to update
651
     *
652
     * @return bool|null Returns result of executiong query
653
     */
654
    public function putResource(
655
        ResourceSet $resourceSet,
656
        KeyDescriptor $keyDescriptor,
657
        $data
658
    ) {
659
        return $this->providerWrapper->putResource(
660
            $resourceSet,
661
            $keyDescriptor,
662
            $data
663
        );
664
    }
665
666
    /**
667
     * Get related resource set for a resource.
668
     *
669
     * @param QueryType        $queryType         Indicates if this is a query for a count, entities, or entities
670
     *                                            with a count
671
     * @param ResourceSet      $sourceResourceSet The entity set containing the source entity
672
     * @param object           $sourceEntity      The source entity instance
673
     * @param ResourceSet      $targetResourceSet The resource set of containing the target of the navigation property
674
     * @param ResourceProperty $targetProperty    The navigation property to retrieve
675
     * @param FilterInfo       $filterInfo        Represents the $filter parameter of the OData query.
676
     *                                            NULL if no $filter specified
677
     * @param mixed            $orderBy           sorted order if we want to get the data in some specific order
678
     * @param int              $top               number of records which  need to be skip
679
     * @param string           $skip              value indicating what records to skip
680
     *
681
     * @return QueryResult
682
     *
683
     * @throws ODataException
684
     */
685
    public function getRelatedResourceSet(
686
        QueryType $queryType,
687
        ResourceSet $sourceResourceSet,
688
        $sourceEntity,
689
        ResourceSet $targetResourceSet,
690
        ResourceProperty $targetProperty,
691
        $filterInfo,
692
        $orderBy,
693
        $top,
694
        $skip
695
    ) {
696
        return $this->providerWrapper->getRelatedResourceSet(
697
            $queryType,
698
            $sourceResourceSet,
699
            $sourceEntity,
700
            $targetResourceSet,
701
            $targetProperty,
702
            $filterInfo,
703
            $orderBy,
704
            $top,
705
            $skip
706
        );
707
    }
708
709
    /**
710
     * Gets a related entity instance from an entity set identified by a key.
711
     *
712
     * @param ResourceSet      $sourceResourceSet The entity set related to the entity to be fetched
713
     * @param object           $sourceEntity      The related entity instance
714
     * @param ResourceSet      $targetResourceSet The entity set from which entity needs to be fetched
715
     * @param ResourceProperty $targetProperty    The metadata of the target property
716
     * @param KeyDescriptor    $keyDescriptor     The key to identify the entity to be fetched
717
     *
718
     * @return object|null Returns entity instance if found else null
719
     */
720
    public function getResourceFromRelatedResourceSet(
721
        ResourceSet $sourceResourceSet,
722
        $sourceEntity,
723
        ResourceSet $targetResourceSet,
724
        ResourceProperty $targetProperty,
725
        KeyDescriptor $keyDescriptor
726
    ) {
727
        return $this->providerWrapper->getResourceFromRelatedResourceSet(
728
            $sourceResourceSet,
729
            $sourceEntity,
730
            $targetResourceSet,
731
            $targetProperty,
732
            $keyDescriptor
733
        );
734
    }
735
736
    /**
737
     * Get related resource for a resource.
738
     *
739
     * @param ResourceSet      $sourceResourceSet The source resource set
740
     * @param object           $sourceEntity      The source resource
741
     * @param ResourceSet      $targetResourceSet The resource set of the navigation
742
     *                                            property
743
     * @param ResourceProperty $targetProperty    The navigation property to be
744
     *                                            retrieved
745
     *
746
     * @return object|null The related resource if exists else null
747
     */
748
    public function getRelatedResourceReference(
749
        ResourceSet $sourceResourceSet,
750
        $sourceEntity,
751
        ResourceSet $targetResourceSet,
752
        ResourceProperty $targetProperty
753
    ) {
754
        return $this->providerWrapper->getRelatedResourceReference(
755
            $sourceResourceSet,
756
            $sourceEntity,
757
            $targetResourceSet,
758
            $targetProperty
759
        );
760
    }
761
762
    /**
763
     * Updates a resource
764
     *
765
     * @param ResourceSet      $sourceResourceSet    The entity set containing the source entity
766
     * @param object           $sourceEntityInstance The source entity instance
767
     * @param KeyDescriptor    $keyDescriptor        The key identifying the entity to fetch
768
     * @param object           $data                 The New data for the entity instance.
769
     * @param bool             $shouldUpdate        Should undefined values be updated or reset to default
770
     *
771
     * @return object|null The new resource value if it is assignable or throw exception for null.
772
     */
773
    public function updateResource(
774
        ResourceSet $sourceResourceSet,
775
        $sourceEntityInstance,
776
        KeyDescriptor $keyDescriptor,
777
        $data,
778
        $shouldUpdate = false
779
    ) {
780
        return $this->providerWrapper->updateResource(
781
            $sourceResourceSet,
782
            $sourceEntityInstance,
783
            $keyDescriptor,
784
            $data,
785
            $shouldUpdate
786
        );
787
    }
788
    /**
789
     * Delete resource from a resource set.
790
     * @param ResourceSet $sourceResourceSet
791
     * @param object           $sourceEntityInstance
792
     *
793
     * return bool true if resources sucessfully deteled, otherwise false.
794
     */
795
    public function deleteResource(
796
        ResourceSet $sourceResourceSet,
797
        $sourceEntityInstance
798
    ) {
799
        return $this->providerWrapper->deleteResource(
800
            $sourceResourceSet,
801
            $sourceEntityInstance
802
        );
803
    }
804
    /**
805
     * @param ResourceSet      $resourceSet   The entity set containing the entity to fetch
806
     * @param object           $sourceEntityInstance The source entity instance
807
     * @param object           $data                 The New data for the entity instance.
808
     *
809
     * returns object|null returns the newly created model if sucessful or null if model creation failed.
810
     */
811
    public function createResourceforResourceSet(
812
        ResourceSet $resourceSet,
813
        $sourceEntityInstance,
814
        $data
815
    ) {
816
        return $this->providerWrapper->createResourceforResourceSet(
817
            $resourceSet,
818
            $sourceEntityInstance,
819
            $data
820
        );
821
    }
822
}
823