Completed
Push — master ( a4bc63...b7b6c7 )
by Alex
01:00
created

MetadataWriter::_getSchemaNamespaceUri()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 6
eloc 14
nc 6
nop 1
1
<?php
2
3
namespace POData\Writers\Metadata;
4
5
use POData\Providers\Metadata\ResourceAssociationSet;
6
use POData\Providers\Metadata\ResourceAssociationTypeEnd;
7
use POData\Providers\Metadata\ResourcePropertyKind;
8
use POData\Providers\Metadata\ResourceProperty;
9
use POData\Providers\Metadata\ResourceType;
10
use POData\Providers\Metadata\ResourceTypeKind;
11
use POData\Providers\ProvidersWrapper;
12
use POData\Common\Version;
13
use POData\Common\ODataConstants;
14
use POData\Common\Messages;
15
use POData\Common\ODataException;
16
use POData\Common\InvalidOperationException;
17
use POData\Providers\Metadata\ResourceAssociationType;
18
use POData\Providers\Metadata\EdmSchemaVersion;
19
20
/**
21
 * Class MetadataWriter.
22
 */
23
class MetadataWriter
24
{
25
    /**
26
     * Writer to which output (CSDL Document) is sent.
27
     *
28
     * @var \XMLWriter
29
     */
30
    private $_xmlWriter;
31
32
    /**                                     `
33
     * Hold reference to the MetadataManager instance,
34
     * which can be used for retrieving details about all ResourceType,
35
     * ResourceSet, AssociationType and AssociationSet defined in the service.
36
     *
37
     * @var MetadataManager
38
     */
39
    private $_metadataManager;
40
41
    /**
42
     * Holds reference to the wrapper over service metadata and query provider implementations
43
     * In this context this provider will be used for gathering metadata information only.
44
     *
45
     * @var ProvidersWrapper
46
     */
47
    private $providersWrapper;
48
49
    /**
50
     * Data service base uri from which resources should be resolved.
51
     *
52
     * @var string
53
     */
54
    private $_baseUri;
0 ignored issues
show
Unused Code introduced by
The property $_baseUri is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
55
56
    /**
57
     * Encoding used for the output (CSDL document).
58
     *
59
     * @var string
60
     */
61
    private $_encoding;
0 ignored issues
show
Unused Code introduced by
The property $_encoding is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
62
63
    /**
64
     * The DataServiceVersion for this metadata.
65
     *
66
     * @var Version
67
     */
68
    private $_dataServiceVersion;
69
70
    /**
71
     * Creates new instance of MetadataWriter.
72
     *
73
     * @param ProvidersWrapper $provider Reference to the
74
     *                                   service metadata and query provider wrapper
75
     */
76
    public function __construct(ProvidersWrapper $provider)
77
    {
78
        $this->providersWrapper = $provider;
79
    }
80
81
    /**
82
     * Write the metadata in CSDL format.
83
     *
84
     * @return string
85
     */
86
    public function writeMetadata()
87
    {
88
        $this->_metadataManager = MetadataManager::create($this->providersWrapper);
89
        $conf = $this->providersWrapper->getConfiguration();
90
91
        $this->_dataServiceVersion = $conf->getMaxDataServiceVersion();
92
        $edmSchemaVersion = $this->providersWrapper->getEdmSchemaVersion();
93
        $this->_metadataManager->getDataServiceAndEdmSchemaVersions($this->_dataServiceVersion, $edmSchemaVersion);
94
        $this->_xmlWriter = new \XMLWriter();
95
        $this->_xmlWriter->openMemory();
96
        $this->_xmlWriter->setIndent(4);
97
        $this->_writeTopLevelElements($this->_dataServiceVersion->toString());
0 ignored issues
show
Documentation introduced by
$this->_dataServiceVersion->toString() is of type string, but the function expects a object<POData\Common\Version>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
        $resourceTypesInContainerNamespace = array();
99
        $containerNamespace = $this->providersWrapper->getContainerNamespace();
100
        foreach ($this->_metadataManager->getResourceTypesAlongWithNamespace()
101
                 as $resourceTypeNamespace => $resourceTypesWithName) {
102
            if ($resourceTypeNamespace == $containerNamespace) {
103
                foreach ($resourceTypesWithName as $resourceTypeName => $resourceType) {
104
                    $resourceTypesInContainerNamespace[] = $resourceType;
105
                }
106 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
                $associationsInThisNamespace =
108
                    $this->_metadataManager->getResourceAssociationTypesForNamespace($resourceTypeNamespace);
109
                $this->_writeSchemaElement($resourceTypeNamespace, $edmSchemaVersion);
110
                $uniqueAssociationsInThisNamespace =
111
                    $this->_metadataManager->getUniqueResourceAssociationTypesForNamespace($resourceTypeNamespace);
112
                $this->_writeResourceTypes(array_values($resourceTypesWithName), $associationsInThisNamespace);
113
                $this->_writeAssociationTypes($uniqueAssociationsInThisNamespace);
114
            }
115
        }
116
117
        //write Container schema node and define required namespaces
118
        $this->_writeSchemaElement($resourceTypeNamespace, $edmSchemaVersion);
0 ignored issues
show
Bug introduced by
The variable $resourceTypeNamespace seems to be defined by a foreach iteration on line 101. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
119 View Code Duplication
        if (!empty($resourceTypesInContainerNamespace)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
            //Get assocation types in container namespace as array of
121
            //key-value pairs (with key as association type
122
            //lookup key i.e. ResourceType::Name_NavigationProperty::Name.
123
            //Same association will appear twice for di-directional relationship
124
            //(duplicate value will be there in this case)
125
            $associationsInThisNamespace =
126
                $this->_metadataManager->getResourceAssociationTypesForNamespace($containerNamespace);
127
            //Get association type in container namespace as array of unique values
128
            $uniqueAssociationsInThisNamespace =
129
                $this->_metadataManager->getUniqueResourceAssociationTypesForNamespace($containerNamespace);
130
            $this->_writeResourceTypes($resourceTypesInContainerNamespace, $associationsInThisNamespace);
131
            $this->_writeAssociationTypes($uniqueAssociationsInThisNamespace);
132
        }
133
134
        $this->_writeEntityContainer();
135
        //End container Schema node
136
        $this->_xmlWriter->endElement();
137
138
        //End edmx:Edmx and edmx:DataServices nodes
139
        $this->_xmlWriter->endElement();
140
        $this->_xmlWriter->endElement();
141
        $metadataInCsdl = $this->_xmlWriter->outputMemory(true);
142
143
        return $metadataInCsdl;
144
    }
145
146
    /**
147
     * Gets data service version for this metadata.
148
     *
149
     * @return Version
150
     */
151
    public function getDataServiceVersion()
152
    {
153
        return $this->_dataServiceVersion;
154
    }
155
156
    /**
157
     * Write top level 'Edmx' and 'DataServices' nodes with associated attributes.
158
     *
159
     * @param Version $dataServiceVersion version of the data service
160
     */
161
    private function _writeTopLevelElements($dataServiceVersion)
162
    {
163
        $this->_xmlWriter->startElementNs(ODataConstants::EDMX_NAMESPACE_PREFIX, ODataConstants::EDMX_ELEMENT, ODataConstants::EDMX_NAMESPACE_1_0);
164
        $this->_xmlWriter->writeAttribute(ODataConstants::EDMX_VERSION, ODataConstants::EDMX_VERSION_VALUE);
165
        $this->_xmlWriter->startElementNs(ODataConstants::EDMX_NAMESPACE_PREFIX, ODataConstants::EDMX_DATASERVICES_ELEMENT, ODataConstants::EDMX_NAMESPACE_1_0);
166
        $this->_xmlWriter->writeAttributeNs(ODataConstants::XMLNS_NAMESPACE_PREFIX, ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, null, ODataConstants::ODATA_METADATA_NAMESPACE);
167
        $this->_xmlWriter->writeAttributeNs(ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, ODataConstants::ODATAVERSIONHEADER, null, $dataServiceVersion);
168
    }
169
170
    /**
171
     * Write 'Schema' node with associated attributes.
172
     *
173
     * @param string           $schemaNamespace  schema namespace
174
     * @param EdmSchemaVersion $edmSchemaVersion edm schema version
175
     */
176
    private function _writeSchemaElement($schemaNamespace, $edmSchemaVersion)
177
    {
178
        $this->_xmlWriter->startElementNs(null, ODataConstants::SCHEMA, $this->_getSchemaNamespaceUri($edmSchemaVersion));
179
        $this->_xmlWriter->writeAttribute(ODataConstants::NAMESPACE1, $schemaNamespace);
180
        $this->_xmlWriter->writeAttributeNs(ODataConstants::XMLNS_NAMESPACE_PREFIX, ODataConstants::ODATA_NAMESPACE_PREFIX, null, ODataConstants::ODATA_NAMESPACE);
181
        $this->_xmlWriter->writeAttributeNs(ODataConstants::XMLNS_NAMESPACE_PREFIX, ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, null, ODataConstants::ODATA_METADATA_NAMESPACE);
182
    }
183
184
    /**
185
     * Write all resource types (entity and complex types).
186
     *
187
     * @param ResourceType[]            $resourceTypes                            resource types array
188
     * @param ResourceAssociationType[] $associationTypesInResourceTypesNamespace collection of
189
     *                                                                            association types for the given resource types
190
     *                                                                            array(string, AssociationType)
191
     */
192
    private function _writeResourceTypes($resourceTypes, $associationTypesInResourceTypesNamespace)
193
    {
194
        foreach ($resourceTypes as $resourceType) {
195
            if ($resourceType->getResourceTypeKind() == ResourceTypeKind::ENTITY) {
196
                $this->_writeEntityType($resourceType, $associationTypesInResourceTypesNamespace);
197
            } elseif ($resourceType->getResourceTypeKind() == ResourceTypeKind::COMPLEX) {
198
                $this->_writeComplexType($resourceType);
199
            } else {
200
                throw ODataException::createInternalServerError(
201
                    Messages::metadataWriterExpectingEntityOrComplexResourceType()
202
                );
203
            }
204
        }
205
    }
206
207
    /**
208
     * Write an entity type and associated attributes.
209
     *
210
     * @param ResourceType $resourceType                            Resource type
211
     * @param ResourceAssociationType[]        $associationTypesInResourceTypeNamespace Collection of
212
     *                                                              association types for the given resource types
213
     *                                                              array(string, AssociationType)
214
     */
215
    private function _writeEntityType(ResourceType $resourceType, $associationTypesInResourceTypeNamespace)
216
    {
217
        $this->_xmlWriter->startElement(ODataConstants::ENTITY_TYPE);
218
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceType->getName());
219
        if ($resourceType->isAbstract()) {
220
            $this->_xmlWriter->writeAttribute(ODataConstants::ABSTRACT1, 'true');
221
        }
222
223
        if ($resourceType->isMediaLinkEntry()
224
            && (!$resourceType->hasBaseType()
225
                || ($resourceType->hasBaseType()
226
                    && $resourceType->getBaseType()->isMediaLinkEntry()))) {
227
            $this->_xmlWriter->writeAttributeNs(
228
                ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX,
229
                ODataConstants::DATAWEB_ACCESS_HASSTREAM_ATTRIBUTE,
230
                null,
231
                'true'
232
            );
233
        }
234
235
        if ($resourceType->hasBaseType()) {
236
            $this->_xmlWriter->writeAttribute(ODataConstants::BASE_TYPE, $resourceType->getBaseType()->getFullName());
237
        } else {
238
            $this->_xmlWriter->startElement(ODataConstants::KEY);
239
            foreach ($resourceType->getKeyProperties() as $resourceProperty) {
240
                $this->_xmlWriter->startElement(ODataConstants::PROPERTY_REF);
241
                $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceProperty->getName());
242
                $this->_xmlWriter->endElement();
243
            }
244
245
            $this->_xmlWriter->endElement();
246
        }
247
248
        $this->_writeProperties($resourceType, $associationTypesInResourceTypeNamespace);
249
        $this->_writeNamedStreams($resourceType);
250
        $this->_xmlWriter->endElement();
251
    }
252
253
    /**
254
     * Write a complex type and associated attributes.
255
     *
256
     * @param ResourceType $complexType resource type
257
     */
258
    private function _writeComplexType(ResourceType $complexType)
259
    {
260
        $this->_xmlWriter->startElement(ODataConstants::COMPLEX_TYPE);
261
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $complexType->getName());
262
        $this->_writeProperties($complexType, null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
263
        $this->_xmlWriter->endElement();
264
    }
265
266
    /**
267
     * Write properties of a resource type (entity or complex type).
268
     *
269
     * @param ResourceType $resourceType                            The Entity
270
     *                                                              or Complex resource type
271
     * @param array        $associationTypesInResourceTypeNamespace When the
272
     *                                                              resource type represents an entity, This will be an array of AssociationType
273
     *                                                              in the namespace same as resource type namespace, array will be
274
     *                                                              key-value pair with key as association type lookup name and value as
275
     *                                                              association type, this parameter will be null if the resource type
276
     *                                                              represents a complex type
277
     *                                                              array(string, AssociationType)
278
     */
279
    private function _writeProperties(ResourceType $resourceType, $associationTypesInResourceTypeNamespace)
280
    {
281
        foreach ($this->_metadataManager->getAllVisiblePropertiesDeclaredOnThisType($resourceType)
282
                 as $resourceProperty) {
283
            if ($resourceProperty->isKindOf(ResourcePropertyKind::BAG)) {
284
                $this->_writeBagProperty($resourceProperty);
285
            } elseif ($resourceProperty->isKindOf(ResourcePropertyKind::PRIMITIVE)) {
286
                $this->_writePrimitiveProperty($resourceProperty);
287
            } elseif ($resourceProperty->isKindOf(ResourcePropertyKind::COMPLEX_TYPE)) {
288
                $this->_writeComplexProperty($resourceProperty);
289
            } elseif ($resourceProperty->isKindOf(ResourcePropertyKind::RESOURCE_REFERENCE)
290
                || $resourceProperty->isKindOf(ResourcePropertyKind::RESOURCESET_REFERENCE)
291
            ) {
292
                $this->_writeNavigationProperty(
293
                    $resourceType,
294
                    $associationTypesInResourceTypeNamespace,
295
                    $resourceProperty
296
                );
297
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
298
                //Unexpected ResourceProperty, expected
299
                    //Bag/Primitive/Complex/Navigation Property
300
            }
301
        }
302
    }
303
304
    /**
305
     * Write a bag property and associated attributes.
306
     *
307
     * @param ResourceProperty $bagProperty bag property
308
     */
309
    private function _writeBagProperty(ResourceProperty $bagProperty)
310
    {
311
        $this->_xmlWriter->startElement(ODataConstants::PROPERTY);
312
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $bagProperty->getName());
313
        $this->_xmlWriter->writeAttribute(ODataConstants::TYPE1, ODataConstants::EDM_BAG_TYPE);
314
        $this->_xmlWriter->writeAttribute(ODataConstants::NULLABLE, 'false');
315
        $this->_xmlWriter->startElement(ODataConstants::TYPE_REF);
316
        $this->_xmlWriter->writeAttribute(ODataConstants::TYPE1, $bagProperty->getResourceType()->getFullName());
317
        $this->_xmlWriter->writeAttribute(ODataConstants::NULLABLE, 'false');
318
        $this->_xmlWriter->endElement();
319
        $this->_xmlWriter->endElement();
320
    }
321
322
    /**
323
     * Write a primitive property and associated attributes.
324
     *
325
     * @param ResourceProperty $primitiveProperty primitive resource property
326
     */
327
    private function _writePrimitiveProperty(ResourceProperty $primitiveProperty)
328
    {
329
        $this->_xmlWriter->startElement(ODataConstants::PROPERTY);
330
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $primitiveProperty->getName());
331
        $this->_xmlWriter->writeAttribute(ODataConstants::TYPE1, $primitiveProperty->getResourceType()->getFullName());
332
        $this->_writePrimitivePropertyFacets($primitiveProperty);
333
        if (!is_null($primitiveProperty->getMIMEType())) {
334
            $this->_xmlWriter->writeAttributeNs(ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, ODataConstants::DATAWEB_MIMETYPE_ATTRIBUTE_NAME, null, $primitiveProperty->getMIMEType());
335
        }
336
337
        if ($primitiveProperty->isKindOf(ResourcePropertyKind::ETAG)) {
338
            $this->_xmlWriter->writeAttribute(ODataConstants::CONCURRENCY_ATTRIBUTE, ODataConstants::CONCURRENCY_FIXEDVALUE);
339
        }
340
341
        $this->_xmlWriter->endElement();
342
    }
343
344
    /**
345
     * Write a complex property and associated attributes.
346
     *
347
     * @param ResourceProperty $complexProperty complex property
348
     */
349 View Code Duplication
    private function _writeComplexProperty(ResourceProperty $complexProperty)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350
    {
351
        $this->_xmlWriter->startElement(ODataConstants::PROPERTY);
352
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $complexProperty->getName());
353
        $this->_xmlWriter->writeAttribute(ODataConstants::TYPE1, $complexProperty->getResourceType()->getFullName());
354
        $this->_xmlWriter->writeAttribute(ODataConstants::NULLABLE, 'false');
355
        $this->_xmlWriter->endElement();
356
    }
357
358
    /**
359
     * Write a navigation property.
360
     *
361
     * @param ResourceType              $resourceType                            Resource type
362
     * @param ResourceAssociationType[] $associationTypesInResourceTypeNamespace Collection of association types for the given resource types
363
     * @param ResourceProperty          $navigationProperty                      Navigation property
364
     *
365
     * @throws InvalidOperationException
366
     */
367
    private function _writeNavigationProperty(ResourceType $resourceType, $associationTypesInResourceTypeNamespace, ResourceProperty $navigationProperty)
368
    {
369
        $associationTypeLookupName = $resourceType->getName() . '_' . $navigationProperty->getName();
370
        if (!array_key_exists($associationTypeLookupName, $associationTypesInResourceTypeNamespace)) {
371
            throw new InvalidOperationException(Messages::metadataWriterNoResourceAssociationSetForNavigationProperty($navigationProperty->getName(), $resourceType->getName()));
372
        }
373
374
        $associationType = $associationTypesInResourceTypeNamespace[$associationTypeLookupName];
375
        $thisEnd = $associationType->getResourceAssociationTypeEnd($resourceType, $navigationProperty);
376
        $relatedEnd = $associationType->getRelatedResourceAssociationSetEnd($resourceType, $navigationProperty);
377
378
        $this->_xmlWriter->startElement(ODataConstants::NAVIGATION_PROPERTY);
379
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $navigationProperty->getName());
380
        $this->_xmlWriter->writeAttribute(ODataConstants::RELATIONSHIP, $associationType->getFullName());
381
        $this->_xmlWriter->writeAttribute(ODataConstants::FROM_ROLE, $thisEnd->getName());
382
        $this->_xmlWriter->writeAttribute(ODataConstants::TO_ROLE, $relatedEnd->getName());
383
        $this->_xmlWriter->endElement();
384
    }
385
386
    /**
387
     * Write primitive property facets.
388
     *
389
     * @param ResourceProperty $primitveProperty primitive property
390
     */
391
    private function _writePrimitivePropertyFacets(ResourceProperty $primitveProperty)
392
    {
393
        $nullable = true;
394
        if ($primitveProperty->isKindOf(ResourcePropertyKind::KEY)) {
395
            $nullable = false;
396
        }
397
398
        $this->_xmlWriter->writeAttribute(ODataConstants::NULLABLE, $nullable ? 'true' : 'false');
399
    }
400
401
    /**
402
     * Write all named streams in the given entity type.
403
     *
404
     * @param ResourceType $resourceType resource type
405
     */
406
    private function _writeNamedStreams(ResourceType $resourceType)
407
    {
408
        $namedStreams = $resourceType->getNamedStreamsDeclaredOnThisType();
409
        if (!empty($namedStreams)) {
410
            $this->_xmlWriter->startElementNs(null, ODataConstants::DATAWEB_NAMEDSTREAMS_ELEMENT, ODataConstants::ODATA_METADATA_NAMESPACE);
411
            foreach ($namedStreams as $namedStreamName => $resourceStreamInfo) {
412
                $this->_xmlWriter->startElementNs(null, ODataConstants::DATAWEB_NAMEDSTREAM_ELEMENT, ODataConstants::ODATA_METADATA_NAMESPACE);
413
                $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceStreamInfo->getName());
414
                $this->_xmlWriter->endElement();
415
            }
416
417
            $this->_xmlWriter->endElement();
418
        }
419
    }
420
421
    /**
422
     * Write all association type.
423
     *
424
     * @param ResourceAssociationType[] $resourceAssociationTypes collection of resource association types
425
     */
426
    private function _writeAssociationTypes($resourceAssociationTypes)
427
    {
428
        foreach ($resourceAssociationTypes as $resourceAssociationType) {
429
            $this->_xmlWriter->startElement(ODataConstants::ASSOCIATION);
430
            $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceAssociationType->getName());
431
            $this->_writeAssociationTypeEnd($resourceAssociationType->getEnd1());
432
            $this->_writeAssociationTypeEnd($resourceAssociationType->getEnd2());
433
            $this->_xmlWriter->endElement();
434
        }
435
    }
436
437
    /**
438
     * Write an association type end.
439
     *
440
     * @param ResourceAssociationTypeEnd $resourceAssociationTypeEnd Resource
441
     *                                                               association type end
442
     */
443 View Code Duplication
    private function _writeAssociationTypeEnd(ResourceAssociationTypeEnd $resourceAssociationTypeEnd)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
444
    {
445
        $this->_xmlWriter->startElement(ODataConstants::END);
446
        $this->_xmlWriter->writeAttribute(ODataConstants::ROLE, $resourceAssociationTypeEnd->getName());
447
        $this->_xmlWriter->writeAttribute(ODataConstants::TYPE1, $resourceAssociationTypeEnd->getResourceType()->getFullName());
448
        $this->_xmlWriter->writeAttribute(ODataConstants::MULTIPLICITY, $resourceAssociationTypeEnd->getMultiplicity());
449
        $this->_xmlWriter->endElement();
450
    }
451
452
    /**
453
     * Write entity container.
454
     */
455
    private function _writeEntityContainer()
456
    {
457
        $this->_xmlWriter->startElement(ODataConstants::ENTITY_CONTAINER);
458
        $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $this->providersWrapper->getContainerName());
459
        $this->_xmlWriter->writeAttributeNs(ODataConstants::ODATA_METADATA_NAMESPACE_PREFIX, ODataConstants::ISDEFAULT_ENTITY_CONTAINER_ATTRIBUTE, null, 'true');
460 View Code Duplication
        foreach ($this->_metadataManager->getResourceSets() as $resourceSet) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
461
            $this->_xmlWriter->startElement(ODataConstants::ENTITY_SET);
462
            $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $resourceSet->getName());
463
            $this->_xmlWriter->writeAttribute(ODataConstants::ENTITY_TYPE, $resourceSet->getResourceType()->getFullName());
464
            $this->_xmlWriter->endElement();
465
        }
466
467
        $this->_writeAssociationSets();
468
        $this->_xmlWriter->endElement();
469
    }
470
471
    /**
472
     * Write all association sets.
473
     */
474
    private function _writeAssociationSets()
475
    {
476 View Code Duplication
        foreach ($this->_metadataManager->getAssociationSets() as $associationSetName => $associationSet) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
477
            $this->_xmlWriter->startElement(ODataConstants::ASSOCIATION_SET);
478
            $this->_xmlWriter->writeAttribute(ODataConstants::NAME, $associationSetName);
479
            $this->_xmlWriter->writeAttribute(ODataConstants::ASSOCIATION, $associationSet->resourceAssociationType->getFullName());
480
            $this->_writeAssocationSetEnds($associationSet);
481
            $this->_xmlWriter->endElement();
482
        }
483
    }
484
485
    /**
486
     * Write both ends of the given association set.
487
     *
488
     * @param ResourceAssociationSet $associationSet resource association set
489
     */
490
    private function _writeAssocationSetEnds(ResourceAssociationSet $associationSet)
491
    {
492
        $associationTypeEnd1 = $associationSet->resourceAssociationType->getResourceAssociationTypeEnd($associationSet->getEnd1()->getResourceType(), $associationSet->getEnd1()->getResourceProperty());
493
        $associationTypeEnd2 = $associationSet->resourceAssociationType->getResourceAssociationTypeEnd($associationSet->getEnd2()->getResourceType(), $associationSet->getEnd2()->getResourceProperty());
494
        $this->_xmlWriter->startElement(ODataConstants::END);
495
        $this->_xmlWriter->writeAttribute(ODataConstants::ROLE, $associationTypeEnd1->getName());
496
        $this->_xmlWriter->writeAttribute(ODataConstants::ENTITY_SET, $associationSet->getEnd1()->getResourceSet()->getName());
497
        $this->_xmlWriter->endElement();
498
        $this->_xmlWriter->startElement(ODataConstants::END);
499
        $this->_xmlWriter->writeAttribute(ODataConstants::ROLE, $associationTypeEnd2->getName());
500
        $this->_xmlWriter->writeAttribute(ODataConstants::ENTITY_SET, $associationSet->getEnd2()->getResourceSet()->getName());
501
        $this->_xmlWriter->endElement();
502
    }
503
504
    /**
505
     * Gets the edmx schema namespace uri for the given schema version.
506
     *
507
     * @param EdmSchemaVersion $edmSchemaVersion metadata edm
508
     *                                           schema version
509
     *
510
     * @return string The schema namespace uri
511
     */
512
    private function _getSchemaNamespaceUri($edmSchemaVersion)
513
    {
514
        switch ($edmSchemaVersion) {
515
            case EdmSchemaVersion::VERSION_1_DOT_0:
516
                return ODataConstants::CSDL_VERSION_1_0;
517
518
            case EdmSchemaVersion::VERSION_1_DOT_1:
519
                return ODataConstants::CSDL_VERSION_1_1;
520
521
            case EdmSchemaVersion::VERSION_1_DOT_2:
522
                return ODataConstants::CSDL_VERSION_1_2;
523
524
            case EdmSchemaVersion::VERSION_2_DOT_0:
525
                return ODataConstants::CSDL_VERSION_2_0;
526
527
            case EdmSchemaVersion::VERSION_2_DOT_2:
528
                return ODataConstants::CSDL_VERSION_2_2;
529
530
            default:
531
                return ODataConstants::CSDL_VERSION_2_2;
532
        }
533
    }
534
}
535