Completed
Push — master ( da3279...199ae8 )
by Joschi
02:50
created

Context::setParentThing()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 7
nc 2
nop 1
crap 2
1
<?php
2
3
/**
4
 * rdfa-lite
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Rdfalite
8
 * @subpackage Jkphl\Rdfalite\Application
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Rdfalite\Application\Parser;
38
39
use Jkphl\Rdfalite\Application\Exceptions\OutOfBoundsException;
40
use Jkphl\Rdfalite\Application\Exceptions\RuntimeException;
41
use Jkphl\Rdfalite\Domain\Thing\ThingInterface;
42
use Jkphl\Rdfalite\Domain\Vocabulary\Vocabulary;
43
use Jkphl\Rdfalite\Domain\Vocabulary\VocabularyInterface;
44
45
/**
46
 * Parsing context
47
 *
48
 * @package Jkphl\Rdfalite
49
 * @subpackage Jkphl\Rdfalite\Application
50
 */
51
class Context
52
{
53
    /**
54
     * Default vocabularies and their prefixes
55
     *
56
     * @var array
57
     * @see https://www.w3.org/2011/rdfa-context/rdfa-1.1
58
     * @link https://www.w3.org/2013/json-ld-context/rdfa11
59
     */
60
    protected static $defaultVocabularies = [
61
        'cat' => 'http://www.w3.org/ns/dcat#',
62
        'qb' => 'http://purl.org/linked-data/cube#',
63
        'grddl' => 'http://www.w3.org/2003/g/data-view#',
64
        'ma' => 'http://www.w3.org/ns/ma-ont#',
65
        'owl' => 'http://www.w3.org/2002/07/owl#',
66
        'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
67
        'rdfa' => 'http://www.w3.org/ns/rdfa#',
68
        'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
69
        'rif' => 'http://www.w3.org/2007/rif#',
70
        'rr' => 'http://www.w3.org/ns/r2rml#',
71
        'skos' => 'http://www.w3.org/2004/02/skos/core#',
72
        'skosxl' => 'http://www.w3.org/2008/05/skos-xl#',
73
        'wdr' => 'http://www.w3.org/2007/05/powder#',
74
        'void' => 'http://rdfs.org/ns/void#',
75
        'wdrs' => 'http://www.w3.org/2007/05/powder-s#',
76
        'xhv' => 'http://www.w3.org/1999/xhtml/vocab#',
77
        'xml' => 'http://www.w3.org/XML/1998/namespace',
78
        'xsd' => 'http://www.w3.org/2001/XMLSchema#',
79
        'prov' => 'http://www.w3.org/ns/prov#',
80
        'sd' => 'http://www.w3.org/ns/sparql-service-description#',
81
        'org' => 'http://www.w3.org/ns/org#',
82
        'gldp' => 'http://www.w3.org/ns/people#',
83
        'cnt' => 'http://www.w3.org/2008/content#',
84
        'dcat' => 'http://www.w3.org/ns/dcat#',
85
        'earl' => 'http://www.w3.org/ns/earl#',
86
        'ht' => 'http://www.w3.org/2006/http#',
87
        'ptr' => 'http://www.w3.org/2009/pointers#',
88
        'cc' => 'http://creativecommons.org/ns#',
89
        'ctag' => 'http://commontag.org/ns#',
90
        'dc' => 'http://purl.org/dc/terms/',
91
        'dc11' => 'http://purl.org/dc/elements/1.1/',
92
        'dcterms' => 'http://purl.org/dc/terms/',
93
        'foaf' => 'http://xmlns.com/foaf/0.1/',
94
        'gr' => 'http://purl.org/goodrelations/v1#',
95
        'ical' => 'http://www.w3.org/2002/12/cal/icaltzd#',
96
        'og' => 'http://ogp.me/ns#',
97
        'rev' => 'http://purl.org/stuff/rev#',
98
        'sioc' => 'http://rdfs.org/sioc/ns#',
99
        'v' => 'http://rdf.data-vocabulary.org/#',
100
        'vcard' => 'http://www.w3.org/2006/vcard/ns#',
101
        'schema' => 'http://schema.org/',
102
        'describedby' => 'http://www.w3.org/2007/05/powder-s#describedby',
103
        'license' => 'http://www.w3.org/1999/xhtml/vocab#license',
104
        'role' => 'http://www.w3.org/1999/xhtml/vocab#role'
105
    ];
106
107
    /**
108
     * Registered vocabularies
109
     *
110
     * @var array
111
     */
112
    protected $vocabularies;
113
114
    /**
115
     * Current default vocabulary
116
     *
117
     * @var VocabularyInterface
118
     */
119
    protected $defaultVocabulary = null;
120
121
    /**
122
     * Parent thing
123
     *
124
     * @var ThingInterface
125
     */
126
    protected $parentThing = null;
127
128
    /**
129
     * Registered child things
130
     *
131
     * @var ThingInterface[]
132
     */
133
    protected $children = [];
134
135
    /**
136
     * Context constructor
137
     */
138 9
    public function __construct()
139
    {
140 9
        $this->vocabularies = self::$defaultVocabularies;
141 9
    }
142
143
    /**
144
     * Return the registered child things
145
     *
146
     * @return ThingInterface[] Child things
147
     */
148 1
    public function getChildren()
149
    {
150 1
        return ($this->parentThing instanceof ThingInterface) ?
151 1
            $this->parentThing->getChildren() : array_values($this->children);
152
    }
153
154
    /**
155
     * Register a vocabulary and its prefix
156
     *
157
     * @param string $prefix Vocabulary prefix
158
     * @param string $uri Vocabulary URI
159
     * @return Context New context
160
     *
161
     */
162 3
    public function registerVocabulary($prefix, $uri)
163
    {
164 3
        $prefix = self::validateVocabPrefix($prefix);
165 2
        $uri = Vocabulary::validateVocabUri($uri);
166
167
        // Register the new URI
168 1
        if (empty($this->vocabularies[$prefix]) || ($this->vocabularies[$prefix] !== $uri)) {
169 1
            $context = clone $this;
170 1
            $context->vocabularies[$prefix] = $uri;
171 1
            return $context;
172
        }
173
174 1
        return $this;
175
    }
176
177
    /**
178
     * Validata a vocabulary prefix
179
     *
180
     * @param string $prefix Vocabulary prefix
181
     * @return string Valid vocabulary prefix
182
     * @throws RuntimeException If the vocabulary prefix is invalid
183
     */
184 5
    protected static function validateVocabPrefix($prefix)
185
    {
186 5
        $prefix = trim($prefix);
187
188
        // If the vocabulary prefix is invalid
189 5
        if (!strlen($prefix)) {
190 1
            throw new RuntimeException(
191 1
                sprintf(RuntimeException::INVALID_VOCABULARY_PREFIX_STR, $prefix),
192
                RuntimeException::INVALID_VOCABULARY_PREFIX
193 1
            );
194
        }
195
196 4
        return $prefix;
197
    }
198
199
    /**
200
     * Return a particular vocabulary
201
     *
202
     * @param string $prefix Vocabulary Prefix
203
     * @return VocabularyInterface Vocabulary
204
     * @throws OutOfBoundsException If the prefix has not been registered
205
     */
206 3
    public function getVocabulary($prefix)
207
    {
208 3
        $prefix = self::validateVocabPrefix($prefix);
209
210
        // If the prefix has not been registered
211 3
        if (empty($this->vocabularies[$prefix])) {
212 1
            throw new OutOfBoundsException(
213 1
                sprintf(OutOfBoundsException::UNKNOWN_VOCABULARY_PREFIX_STR, $prefix),
214
                OutOfBoundsException::UNKNOWN_VOCABULARY_PREFIX
215 1
            );
216
        }
217
218 2
        return new Vocabulary($this->vocabularies[$prefix]);
219
    }
220
221
    /**
222
     * Return whether a particular vocabulary prefix has been registered
223
     *
224
     * @param string $prefix Vocabulary prefix
225
     * @return bool Whether the prefix has been registered
226
     */
227 2
    public function hasVocabulary($prefix)
228
    {
229 2
        return !empty($this->vocabularies[self::validateVocabPrefix($prefix)]);
230
    }
231
232
    /**
233
     * Return the current default vocabulary
234
     *
235
     * @return VocabularyInterface Current default vocabulary
236
     */
237 1
    public function getDefaultVocabulary()
238
    {
239 1
        return $this->defaultVocabulary;
240
    }
241
242
    /**
243
     * Set the default vocabulary by URI
244
     *
245
     * @param VocabularyInterface $vocabulary Current default vocabulary
246
     * @return Context Self reference
247
     */
248 1
    public function setDefaultVocabulary(VocabularyInterface $vocabulary)
249
    {
250
        // If the new default vocabulary differs from the current one
251 1
        if ($this->defaultVocabulary !== $vocabulary) {
252 1
            $context = clone $this;
253 1
            $context->defaultVocabulary = $vocabulary;
254 1
            return $context;
255
        }
256
257 1
        return $this;
258
    }
259
260
    /**
261
     * Get the current parent thing
262
     *
263
     * @return ThingInterface|null Parent thing
264
     */
265 1
    public function getParentThing()
266
    {
267 1
        return $this->parentThing;
268
    }
269
270
    /**
271
     * Set the parent thing
272
     *
273
     * @param ThingInterface $parentThing Parent thing
274
     * @return Context
275
     */
276 2
    public function setParentThing(ThingInterface $parentThing)
277
    {
278
        // If the new parent thing differs from the current one
279 2
        if ($this->parentThing !== $parentThing) {
280 2
            $context = clone $this;
281 2
            $context->parentThing = $parentThing;
282 2
            $context->children = [];
283 2
            return $context;
284
        }
285
286 1
        return $this;
287
    }
288
289
    /**
290
     * Add a child thing
291
     *
292
     * @param ThingInterface $thing Child thing
293
     * @return Context Self reference
294
     */
295 1
    public function addChild(ThingInterface $thing)
296
    {
297 1
        if ($this->parentThing instanceof ThingInterface) {
298 1
            $this->parentThing->addChild($thing);
299 1
        } else {
300 1
            $this->children[spl_object_hash($thing)] = $thing;
301
        }
302
303 1
        return $this;
304
    }
305
}
306