5 * RDF Parser for ARC2 to OSLC Core RDF JSON format
7 * Copyright (c) 2010 Olivier Berger, Institut Telecom
9 * homepage: See http://oslc-tools.svn.sourceforge.net/viewvc/oslc-tools/language-libs/php/arc2-plugin/
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
16 * http://www.apache.org/licenses/LICENSE-2.0 or in the acompanying COPYING file
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 * class: ARC2_OSLCCoreRDFJSONParserPlugin
25 * author: Olivier Berger
28 * This program was developped in the frame of the COCLICO project
29 * (http://www.coclico-project.org/) with financial support of the Paris
32 * It was initially developped to in order to provide a JSON parser for
33 * RDF content formatted along the OSLC (Open Services for Lifecycle
34 * Collaboration) Core specs guidelines, which could be used in the
35 * FusionForge project import plugin.
37 * The most up-to-date version is maintained in the frame of the OSLC
38 * support Open Source project at http://oslc-tools.sourceforge.net/.
46 Will parse JSON containing RDF in the format of OSLC Core [0], like :
49 "dcterms:content": "Anything dirty or dingy or dusty. \\nAnything ragged or rotten or rusty.",
51 "foaf:name": "Oscar T. Grouch"
53 "dcterms:modified": "2002-10-10T12:00:00-05:00",
54 "dcterms:title": "I love trash",
56 "dcterms": "http://purl.org/dc/terms/",
57 "foaf": "http://http://xmlns.com/foaf/0.1/",
58 "oslc": "http://open-services.net/ns/core#",
59 "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
61 "rdf:about": "http://example.com/blogs/entry/1",
63 "rdf:resource": "http://open-services.net/ns/bogus/blogs#Entry"
67 [0] http://open-services.net/bin/view/Main/OSLCCoreSpecAppendixRepresentations#Guidelines_for_JSON
71 # install it in arc2/plugins or include it like this
72 #include_once("./ARC2_OSLCCoreRDFJSONParserPlugin.php");
74 # then use it like this
75 $parser = ARC2::getComponent("OSLCCoreRDFJSONParserPlugin");
76 $parser->parse('example.json');
78 $triples = $parser->getTriples();
82 ARC2::inc('JSONParser');
84 function is_assoc($array) {
85 return (is_array($array) && (count($array)==0 || 0 !== count(array_diff_key($array, array_keys(array_keys($array))) )));
88 class ARC2_OSLCCoreRDFJSONParserPlugin extends ARC2_JSONParser {
90 function __construct($a, &$caller) {
91 parent::__construct($a, $caller);
94 function ARC2_OSLCCoreRDFJSONParserPlugin ($a = '', &$caller) {
95 $this->__construct($a, $caller);
98 function __init() {/* reader */
100 $this->rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
101 $this->fake_prefix = 'http://example.com/fakeprefix#';
102 $this->nsp = array($this->rdf => 'rdf',
103 $this->fake_prefix => '___');
112 // Extract from a substructure $x
113 function extractRDFFromSubStruct($subject, $predicate, $x, $parent_prefixes)
115 // if it's an array, then need new resource
117 $subcontext = $this->getContext($x);
118 // if it has no own subject (rdf:about), then create a blank node
120 $bnode = $this->createBnodeID();
121 $subcontext = $bnode;
123 // add pointer to the new resource
124 $this->addT($subject, $predicate, $subcontext, 'uri');
125 // process new resource
126 $this->extractRDFFromStruct($x, $subcontext, $parent_prefixes);
128 // else, just adding another predicate to the subject
130 $this->addT($subject, $predicate, $x);
134 // Extract from a structure, giving it an already computed subject if needed (blank nodes)
135 function extractRDFFromStruct($struct, $subject=false, $parent_prefixes=false)
139 // Extract subject from 'rdf:about' of the struct
141 $subject = $this->getContext($struct);
143 $type = $this->getType($struct);
145 if(is_array($type)) {
146 foreach ($type as $t) {
147 $this->addT($subject, $this->rdf . 'type', $t, 'uri', 'uri');
151 $this->addT($subject, $this->rdf . 'type', $type, 'uri', 'uri');
154 $prefixes = array('___' => $this->fake_prefix);
155 if (is_array($parent_prefixes)) {
156 foreach ($parent_prefixes as $k => $v) {
160 if (isset($struct['prefixes'])) {
161 foreach ($struct['prefixes'] as $k => $v) {
165 foreach ($struct as $p => $o) {
166 // in case there's no prefix, use fake '___' prefix
167 if (preg_match('/\:/', $p)) {
168 preg_match('/^([^:]*)\:(.*)$/', $p, $m);
173 if($p != 'prefixes') {
178 $predicate = $prefixes[$shortpref].$suffix;
179 // process all "regular" attributes (all but reserved ones)
180 $reserved = array('rdf:type', 'rdf:about', 'prefixes');
181 if (!in_array($p, $reserved)){
182 // treat litterals first
184 $this->addT($subject, $predicate, $o);
188 // treat only non-empty sub structs
190 // treat lists of elements for same predicate
193 $this->extractRDFFromSubStruct($subject, $predicate, $x, $prefixes);
196 // treat single element sub-struct
198 $this->extractRDFFromSubStruct($subject, $predicate, $o, $prefixes);
205 $os = $this->getURLs($this->struct);
206 foreach ($os as $o) {
207 if ($o != $subject) $this->addT($subject, 'http://www.w3.org/2000/01/rdf-schema#seeAlso', $o, 'uri', 'uri');
212 function extractRDF() {
213 $this->extractRDFFromStruct($this->struct);
216 // retrieves the subject of a triple (rdf:about)
217 function getContext($struct) {
218 if (!isset($struct['rdf:about'])) return '';
219 return $struct['rdf:about'];
222 function getType($struct) {
223 if (!isset($struct['rdf:type'])) return '';
224 $type = $struct['rdf:type'];
225 if (!is_array($type))
228 if (!isset($type['rdf:resource']))
231 return $type['rdf:resource'];
235 function getURLs($struct) {
237 if (is_array($struct)) {
238 foreach ($struct as $k => $v) {
239 if (preg_match('/^http:\/\//', $k) && !in_array($k, $r)) $r[] = $k;
240 $sub_r = $this->getURLs($v);
241 foreach ($sub_r as $sub_v) {
242 if (!in_array($sub_v, $r)) $r[] = $sub_v;
246 elseif (preg_match('/^http:\/\//', $struct) && !in_array($struct, $r)) {