Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
namespace Aws\Api\Serializer;
3
 
4
use Aws\Api\MapShape;
5
use Aws\Api\Service;
6
use Aws\Api\Shape;
7
use Aws\Api\StructureShape;
8
use Aws\Api\ListShape;
9
use Aws\Api\TimestampShape;
10
use XMLWriter;
11
 
12
/**
13
 * @internal Formats the XML body of a REST-XML services.
14
 */
15
class XmlBody
16
{
17
    /** @var \Aws\Api\Service */
18
    private $api;
19
 
20
    /**
21
     * @param Service $api API being used to create the XML body.
22
     */
23
    public function __construct(Service $api)
24
    {
25
        $this->api = $api;
26
    }
27
 
28
    /**
29
     * Builds the XML body based on an array of arguments.
30
     *
31
     * @param Shape $shape Operation being constructed
32
     * @param array $args  Associative array of arguments
33
     *
34
     * @return string
35
     */
36
    public function build(Shape $shape, array $args)
37
    {
38
        $xml = new XMLWriter();
39
        $xml->openMemory();
40
        $xml->startDocument('1.0', 'UTF-8');
41
        $this->format($shape, $shape['locationName'] ?: $shape['name'], $args, $xml);
42
        $xml->endDocument();
43
 
44
        return $xml->outputMemory();
45
    }
46
 
47
    private function startElement(Shape $shape, $name, XMLWriter $xml)
48
    {
49
        $xml->startElement($name);
50
 
51
        if ($ns = $shape['xmlNamespace']) {
52
            $xml->writeAttribute(
53
                isset($ns['prefix']) ? "xmlns:{$ns['prefix']}" : 'xmlns',
54
                $shape['xmlNamespace']['uri']
55
            );
56
        }
57
    }
58
 
59
    private function format(Shape $shape, $name, $value, XMLWriter $xml)
60
    {
61
        // Any method mentioned here has a custom serialization handler.
62
        static $methods = [
63
            'add_structure' => true,
64
            'add_list'      => true,
65
            'add_blob'      => true,
66
            'add_timestamp' => true,
67
            'add_boolean'   => true,
68
            'add_map'       => true,
69
            'add_string'    => true
70
        ];
71
 
72
        $type = 'add_' . $shape['type'];
73
        if (isset($methods[$type])) {
74
            $this->{$type}($shape, $name, $value, $xml);
75
        } else {
76
            $this->defaultShape($shape, $name, $value, $xml);
77
        }
78
    }
79
 
80
    private function defaultShape(Shape $shape, $name, $value, XMLWriter $xml)
81
    {
82
        $this->startElement($shape, $name, $xml);
83
        $xml->text($value);
84
        $xml->endElement();
85
    }
86
 
87
    private function add_structure(
88
        StructureShape $shape,
89
        $name,
90
        array $value,
91
        \XMLWriter $xml
92
    ) {
93
        $this->startElement($shape, $name, $xml);
94
 
95
        foreach ($this->getStructureMembers($shape, $value) as $k => $definition) {
96
            $this->format(
97
                $definition['member'],
98
                $definition['member']['locationName'] ?: $k,
99
                $definition['value'],
100
                $xml
101
            );
102
        }
103
 
104
        $xml->endElement();
105
    }
106
 
107
    private function getStructureMembers(StructureShape $shape, array $value)
108
    {
109
        $members = [];
110
 
111
        foreach ($value as $k => $v) {
112
            if ($v !== null && $shape->hasMember($k)) {
113
                $definition = [
114
                    'member' => $shape->getMember($k),
115
                    'value'  => $v,
116
                ];
117
 
118
                if ($definition['member']['xmlAttribute']) {
119
                    // array_unshift_associative
120
                    $members = [$k => $definition] + $members;
121
                } else {
122
                    $members[$k] = $definition;
123
                }
124
            }
125
        }
126
 
127
        return $members;
128
    }
129
 
130
    private function add_list(
131
        ListShape $shape,
132
        $name,
133
        array $value,
134
        XMLWriter $xml
135
    ) {
136
        $items = $shape->getMember();
137
 
138
        if ($shape['flattened']) {
139
            $elementName = $name;
140
        } else {
141
            $this->startElement($shape, $name, $xml);
142
            $elementName = $items['locationName'] ?: 'member';
143
        }
144
 
145
        foreach ($value as $v) {
146
            $this->format($items, $elementName, $v, $xml);
147
        }
148
 
149
        if (!$shape['flattened']) {
150
            $xml->endElement();
151
        }
152
    }
153
 
154
    private function add_map(
155
        MapShape $shape,
156
        $name,
157
        array $value,
158
        XMLWriter $xml
159
    ) {
160
        $xmlEntry = $shape['flattened'] ? $shape['locationName'] : 'entry';
161
        $xmlKey = $shape->getKey()['locationName'] ?: 'key';
162
        $xmlValue = $shape->getValue()['locationName'] ?: 'value';
163
 
164
        $this->startElement($shape, $name, $xml);
165
 
166
        foreach ($value as $key => $v) {
167
            $this->startElement($shape, $xmlEntry, $xml);
168
            $this->format($shape->getKey(), $xmlKey, $key, $xml);
169
            $this->format($shape->getValue(), $xmlValue, $v, $xml);
170
            $xml->endElement();
171
        }
172
 
173
        $xml->endElement();
174
    }
175
 
176
    private function add_blob(Shape $shape, $name, $value, XMLWriter $xml)
177
    {
178
        $this->startElement($shape, $name, $xml);
179
        $xml->writeRaw(base64_encode($value));
180
        $xml->endElement();
181
    }
182
 
183
    private function add_timestamp(
184
        TimestampShape $shape,
185
        $name,
186
        $value,
187
        XMLWriter $xml
188
    ) {
189
        $this->startElement($shape, $name, $xml);
190
        $timestampFormat = !empty($shape['timestampFormat'])
191
            ? $shape['timestampFormat']
192
            : 'iso8601';
193
        $xml->writeRaw(TimestampShape::format($value, $timestampFormat));
194
        $xml->endElement();
195
    }
196
 
197
    private function add_boolean(
198
        Shape $shape,
199
        $name,
200
        $value,
201
        XMLWriter $xml
202
    ) {
203
        $this->startElement($shape, $name, $xml);
204
        $xml->writeRaw($value ? 'true' : 'false');
205
        $xml->endElement();
206
    }
207
 
208
    private function add_string(
209
        Shape $shape,
210
        $name,
211
        $value,
212
        XMLWriter $xml
213
    ) {
214
        if ($shape['xmlAttribute']) {
215
            $xml->writeAttribute($shape['locationName'] ?: $name, $value);
216
        } else {
217
            $this->defaultShape($shape, $name, $value, $xml);
218
        }
219
    }
220
}