This repository has been archived by the owner on Aug 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NodeFactoryImpl.php
229 lines (199 loc) · 6.84 KB
/
NodeFactoryImpl.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
<?php
/*
* This file is part of Saft.
*
* (c) Konrad Abicht <[email protected]>
* (c) Natanael Arndt <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Saft\Rdf;
class NodeFactoryImpl implements NodeFactory
{
/**
* @param CommonNamespaces $commonNamespaces if null, CommonNamespaces will used automatically
*/
public function __construct(CommonNamespaces $commonNamespaces = null)
{
if (null == $commonNamespaces) {
$this->commonNamespaces = new CommonNamespaces();
} else {
$this->commonNamespaces = $commonNamespaces;
}
}
/**
* @param string $value
* @param Node|string $datatype (optional)
* @param string $lang (optional)
*
* @return Literal
*/
public function createLiteral($value, $datatype = null, $lang = null)
{
if ($datatype !== null) {
if (!$datatype instanceof Node) {
$datatype = $this->createNamedNode($datatype);
} elseif (!$datatype->isNamed()) {
throw new \Exception('Argument datatype has to be a named node.');
}
}
return new LiteralImpl($value, $datatype, $lang);
}
/*
* @return NamedNode
*/
public function createNamedNode($uri)
{
return new NamedNodeImpl($this->commonNamespaces->extendUri($uri));
}
/*
* @return BlankNode
*/
public function createBlankNode($blankId)
{
return new BlankNodeImpl($blankId);
}
/*
* @return AnyPattern
*/
public function createAnyPattern()
{
return new AnyPatternImpl();
}
/**
* Creates an RDF Node based on a N-Triples/N-Quads node string.
*
* @param $string string the N-Triples/N-Quads node string
*
* @return Node
*
* @throws \Exception if no node could be created e.g. because of a syntax error in the node string
*/
public function createNodeFromNQuads($string)
{
$regex = '/'.$this->getRegexStringForNodeRecognition(
true, true, true, true, true, true
).'/si';
$string = trim($string);
preg_match($regex, $string, $matches);
if (0 == count($matches)) {
throw new \Exception('Invalid parameter $string given. Our regex '.$regex.' doesnt apply.');
}
$firstChar = substr($matches[0], 0, 1);
// http://...
if ('<' == $firstChar) {
return $this->createNamedNode(str_replace(['<', '>'], '', $matches[1]));
// ".."^^<
} elseif (false !== strpos($matches[0], '"^^<')) {
return $this->createLiteral($matches[9], $matches[10]);
// "foo"@en
} elseif (false !== strpos($matches[0], '"@')) {
return $this->createLiteral($matches[12], null, $matches[13]);
// "foo"
} elseif ('"' == $firstChar) {
return $this->createLiteral($matches[15]);
// _:foo
} elseif ($this->simpleCheckBlankNodeId($matches[0])) {
return $this->createBlankNode($matches[4]);
// 0-9 (simple number, multi digits)
} elseif (0 < (int) $matches[0]) {
return $this->createLiteral(
$matches[16],
$this->createNamedNode('http://www.w3.org/2001/XMLSchema#double')
);
} else {
throw new \Exception('Unknown case for: '.$matches[1]);
}
throw new \Exception("The given string (\"$string\") is not valid or doesn't represent any RDF node");
}
/**
* Helper function, which is useful, if you have all the meta information about a Node and want to create
* the according Node instance.
*
* @param string $value value of the node
* @param string $type Can be uri, bnode, var or literal
* @param string $datatype URI of the datatype (optional)
* @param string $language Language tag (optional)
*
* @return Node Node instance, which type is one of: NamedNode, BlankNode, Literal, AnyPattern
*
* @throws \Exception if an unknown type was given
* @throws \Exception if something went wrong during Node creation
*
* @api
*
* @since 0.8
*/
public function createNodeInstanceFromNodeParameter($value, $type, $datatype = null, $language = null)
{
switch ($type) {
case 'uri':
return $this->createNamedNode($value);
case 'bnode':
return $this->createBlankNode($value);
case 'literal':
return $this->createLiteral($value, $datatype, $language);
case 'typed-literal':
return $this->createLiteral($value, $datatype, $language);
case 'var':
return $this->createAnyPattern();
default:
throw new \Exception('Unknown $type given: '.$type);
}
}
/**
* Returns the regex string to get a node from a triple/quad.
*
* @param bool $useVariables optional, default is false
* @param bool $useNamespacedUri optional, default is false
*
* @return string
*/
protected function getRegexStringForNodeRecognition(
$useBlankNode = false,
$useNamespacedUri = false,
$useTypedString = false,
$useLanguagedString = false,
$useSimpleString = false,
$useSimpleNumber = false,
$useVariables = false
) {
$regex = '(<([a-z]{2,}:[^\s]*)>)'; // e.g. <http://foobar/a>
if (true == $useBlankNode) {
$regex .= '|(_:([a-z0-9A-Z_]+))'; // e.g. _:foobar
}
if (true == $useNamespacedUri) {
$regex .= '|(([a-z0-9]+)\:([a-z0-9]+))'; // e.g. rdfs:label
}
if (true == $useTypedString) {
// e.g. "Foo"^^<http://www.w3.org/2001/XMLSchema#string>
$regex .= '|(\"(.*?)\"\^\^\<([^\s]+)\>)';
}
if (true == $useLanguagedString) {
$regex .= '|(\"(.*?)\"\@([a-z\-]{2,}))'; // e.g. "Foo"@en
}
if (true == $useSimpleString) {
$regex .= '|(\"(.*?)\")'; // e.g. "Foo"
}
if (true == $useSimpleNumber) {
$regex .= '|([0-9]{1,})'; // e.g. 42
}
if (true == $useVariables) {
$regex .= '|(\?[a-z0-9\_]+)'; // e.g. ?s
}
return $regex;
}
/**
* Checks if a given string is a blank node ID. Blank nodes are usually structured like
* _:foo, whereas _: comes first always.
*
* @param string $string string to check if its a blank node ID or not
*
* @return bool true if given string is a valid blank node ID, false otherwise
*/
protected function simpleCheckBlankNodeId($string)
{
return '_:' == substr($string, 0, 2);
}
}