Browse.php
Go to the documentation of this file.
00001 <?php 00002 00005 00027 class Browse extends WebService 00028 { 00030 private $conneg; 00031 00033 private $dtdURL; 00034 00036 private $attributes = ""; 00037 00039 private $types = ""; 00040 00042 private $datasets = ""; 00043 00045 private $items = ""; 00046 00048 private $page = ""; 00049 00051 private $inference = ""; 00052 00054 private $requester_ip = ""; 00055 00057 private $registered_ip = ""; 00058 00060 private $namespaces = 00061 array ("http://www.w3.org/2002/07/owl#" => "owl", "http://www.w3.org/1999/02/22-rdf-syntax-ns#" => "rdf", 00062 "http://www.w3.org/2000/01/rdf-schema#" => "rdfs", "http://purl.org/ontology/wsf#" => "wsf"); 00063 00064 00066 public $subjectTriples = array(); // 00067 00069 public $objectTriples = array(); 00070 00072 public $resultset = array(); 00073 00075 public $resultsetObjectProperties = array(); 00076 00078 public $resultsetObjectPropertiesUris = array(); 00079 00081 public $aggregates = array(); 00082 00084 public $include_aggregates = array(); 00085 00087 public static $supportedSerializations = 00088 array ("application/json", "application/rdf+xml", "application/rdf+n3", "application/*", "text/xml", "text/*", 00089 "*/*"); 00090 00092 private $errorMessenger = 00093 '{ 00094 "ws": "/ws/browse/", 00095 "_200": { 00096 "id": "WS-BROWSE-200", 00097 "level": "Warning", 00098 "name": "Invalid number of items requested", 00099 "description": "The number of items returned per request has to be greater than 0 and lesser than 128" 00100 }, 00101 "_300": { 00102 "id": "WS-BROWSE-300", 00103 "level": "Warning", 00104 "name": "No datasets accessible by that user", 00105 "description": "No datasets are accessible to that user" 00106 } 00107 }'; 00108 00109 00131 function __construct($attributes, $types, $datasets, $items, $page, $inference, $include_aggregates, $registered_ip, 00132 $requester_ip) 00133 { 00134 parent::__construct(); 00135 00136 $this->attributes = $attributes; 00137 $this->items = $items; 00138 $this->page = $page; 00139 $this->inference = $inference; 00140 $this->includeAggregates = $include_aggregates; 00141 00142 $this->types = $types; 00143 $this->datasets = $datasets; 00144 00145 $this->requester_ip = $requester_ip; 00146 00147 if($registered_ip == "") 00148 { 00149 $this->registered_ip = $requester_ip; 00150 } 00151 else 00152 { 00153 $this->registered_ip = $registered_ip; 00154 } 00155 00156 if(strtolower(substr($this->registered_ip, 0, 4)) == "self") 00157 { 00158 $pos = strpos($this->registered_ip, "::"); 00159 00160 if($pos !== FALSE) 00161 { 00162 $account = substr($this->registered_ip, $pos + 2, strlen($this->registered_ip) - ($pos + 2)); 00163 00164 $this->registered_ip = $requester_ip . "::" . $account; 00165 } 00166 else 00167 { 00168 $this->registered_ip = $requester_ip; 00169 } 00170 } 00171 00172 $this->uri = $this->wsf_base_url . "/wsf/ws/browse/"; 00173 $this->title = "Browse Web Service"; 00174 $this->crud_usage = new CrudUsage(FALSE, TRUE, FALSE, FALSE); 00175 $this->endpoint = $this->wsf_base_url . "/ws/browse/"; 00176 00177 $this->dtdURL = "browse/browse.dtd"; 00178 00179 $this->errorMessenger = json_decode($this->errorMessenger); 00180 } 00181 00182 function __destruct() { parent::__destruct(); } 00183 00196 protected function validateQuery() { 00197 // Here we can have a performance problem when "dataset = all" if we perform the authentication using AuthValidator. 00198 // Since AuthValidator doesn't support multiple datasets at the same time, we will use the AuthLister web service 00199 // in the process() function and check if the user has the permissions to "read" these datasets. 00200 // 00201 // This means that the validation of these queries doesn't happen at this level. 00202 } 00203 00214 public function pipeline_getError() { return ($this->conneg->error); } 00215 00216 00227 public function pipeline_getResultset() 00228 { 00229 $xml = new ProcessorXML(); 00230 00231 // Creation of the RESULTSET 00232 $resultset = $xml->createResultset(); 00233 00234 // Creation of the prefixes elements. 00235 $void = $xml->createPrefix("owl", "http://www.w3.org/2002/07/owl#"); 00236 $resultset->appendChild($void); 00237 $rdf = $xml->createPrefix("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); 00238 $resultset->appendChild($rdf); 00239 $dcterms = $xml->createPrefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#"); 00240 $resultset->appendChild($dcterms); 00241 $dcterms = $xml->createPrefix("wsf", "http://purl.org/ontology/wsf#"); 00242 $resultset->appendChild($dcterms); 00243 00244 $subject; 00245 00246 foreach($this->resultset as $uri => $result) 00247 { 00248 // Assigning types 00249 if(isset($result["type"])) 00250 { 00251 foreach($result["type"] as $key => $type) 00252 { 00253 if($key > 0) 00254 { 00255 if(array_search($type, $this->resultsetObjectPropertiesUris[$uri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"]) === FALSE) 00256 { 00257 $pred = $xml->createPredicate("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); 00258 $object = $xml->createObject("", $type); 00259 $pred->appendChild($object); 00260 $subject->appendChild($pred); 00261 } 00262 } 00263 else 00264 { 00265 $subject = $xml->createSubject($type, $uri); 00266 } 00267 } 00268 } 00269 else 00270 { 00271 $subject = $xml->createSubject("http://www.w3.org/2002/07/owl#Thing", $this->resourceUri); 00272 } 00273 00274 // Assigning the Dataset relationship 00275 if(isset($result["dataset"])) 00276 { 00277 $pred = $xml->createPredicate("http://purl.org/dc/terms/isPartOf"); 00278 $object = $xml->createObject("http://rdfs.org/ns/void#Dataset", $result["dataset"]); 00279 $pred->appendChild($object); 00280 $subject->appendChild($pred); 00281 } 00282 00283 // Assigning the preferred label relationship 00284 if(isset($result["prefLabel"])) 00285 { 00286 $pred = $xml->createPredicate(Namespaces::$iron . "prefLabel"); 00287 $object = $xml->createObjectContent($result["prefLabel"]); 00288 $pred->appendChild($object); 00289 $subject->appendChild($pred); 00290 } 00291 00292 // Assigning the alternative label relationship 00293 if(isset($result["altLabel"])) 00294 { 00295 foreach($result["altLabel"] as $altLabel) 00296 { 00297 $pred = $xml->createPredicate(Namespaces::$iron . "altLabel"); 00298 $object = $xml->createObjectContent($altLabel); 00299 $pred->appendChild($object); 00300 $subject->appendChild($pred); 00301 } 00302 } 00303 00304 // Assigning the description relationship 00305 if(isset($result["description"])) 00306 { 00307 $pred = $xml->createPredicate(Namespaces::$iron . "description"); 00308 $object = $xml->createObjectContent($result["description"]); 00309 $pred->appendChild($object); 00310 $subject->appendChild($pred); 00311 } 00312 00313 00314 // Assigning the Properties -> Literal relationships 00315 foreach($result as $property => $values) 00316 { 00317 if($property != "type" && $property != "dataset") 00318 { 00319 foreach($values as $value) 00320 { 00321 $pred = $xml->createPredicate($property); 00322 $object = $xml->createObjectContent($value); 00323 $pred->appendChild($object); 00324 $subject->appendChild($pred); 00325 } 00326 } 00327 } 00328 00329 // Assigning object properties 00330 if(isset($this->resultsetObjectProperties[$uri])) 00331 { 00332 foreach($this->resultsetObjectProperties[$uri] as $property => $values) 00333 { 00334 if($property != "type" && $property != "dataset") 00335 { 00336 foreach($values as $key => $value) 00337 { 00338 $pred = $xml->createPredicate($property); 00339 00340 $object = $xml->createObject("", $this->resultsetObjectPropertiesUris[$uri][$property][$key], ""); 00341 $pred->appendChild($object); 00342 00343 $reify = $xml->createReificationStatement("wsf:objectLabel", $value); 00344 $object->appendChild($reify); 00345 00346 $subject->appendChild($pred); 00347 } 00348 } 00349 } 00350 } 00351 00352 $resultset->appendChild($subject); 00353 } 00354 00355 00356 // Include facet information 00357 00358 // Type 00359 00360 if(strtolower($this->includeAggregates) == "true") 00361 { 00362 $aggregatesUri = $this->uri . "aggregate/" . md5(microtime()); 00363 00364 $typeLabelsCounts = array(); 00365 00366 foreach($this->aggregates["type"] as $ftype => $fcount) 00367 { 00368 // If we have an inferred type, we use that count instead of the normal count. 00369 if(isset($this->aggregates["inferred_type"][$ftype])) 00370 { 00371 $fcount = $this->aggregates["inferred_type"][$ftype]; 00372 } 00373 00374 $subject = 00375 $xml->createSubject("http://purl.org/ontology/aggregate#Aggregate", $aggregatesUri . "/" . md5($ftype) . "/"); 00376 00377 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#property"); 00378 $object = $xml->createObject("", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); 00379 $pred->appendChild($object); 00380 $subject->appendChild($pred); 00381 00382 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#object"); 00383 $object = $xml->createObject("", $ftype); 00384 $pred->appendChild($object); 00385 $subject->appendChild($pred); 00386 00387 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#count"); 00388 $object = $xml->createObjectContent($fcount); 00389 $pred->appendChild($object); 00390 $subject->appendChild($pred); 00391 00392 $resultset->appendChild($subject); 00393 00394 $typeLabelsCounts = array(); 00395 } 00396 00397 // For each inferred type that have been left so far, we re-introduce them in the aggregates 00398 foreach($this->aggregates["inferred_type"] as $ftype => $fcount) 00399 { 00400 // If we have an inferred type, we use that count instead of the normal count. 00401 if(!isset($this->aggregates["type"][$ftype])) 00402 { 00403 $subject = $xml->createSubject("http://purl.org/ontology/aggregate#Aggregate", 00404 $aggregatesUri . "/" . md5($ftype) . "/"); 00405 00406 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#property"); 00407 $object = $xml->createObject("", "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"); 00408 $pred->appendChild($object); 00409 $subject->appendChild($pred); 00410 00411 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#object"); 00412 $object = $xml->createObject("", $ftype); 00413 $pred->appendChild($object); 00414 $subject->appendChild($pred); 00415 00416 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#count"); 00417 $object = $xml->createObjectContent($fcount); 00418 $pred->appendChild($object); 00419 $subject->appendChild($pred); 00420 00421 $resultset->appendChild($subject); 00422 } 00423 } 00424 00425 // Dataset 00426 00427 $aggregatesUri = $this->uri . "aggregate/" . md5(microtime()); 00428 00429 foreach($this->aggregates["dataset"] as $ftype => $fcount) 00430 { 00431 $subject = 00432 $xml->createSubject("http://purl.org/ontology/aggregate#Aggregate", $aggregatesUri . "/" . md5($ftype) . "/"); 00433 00434 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#property"); 00435 $object = $xml->createObject("", "http://rdfs.org/ns/void#Dataset"); 00436 $pred->appendChild($object); 00437 $subject->appendChild($pred); 00438 00439 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#object"); 00440 $object = $xml->createObject("", $ftype); 00441 $pred->appendChild($object); 00442 $subject->appendChild($pred); 00443 00444 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#count"); 00445 $object = $xml->createObjectContent($fcount); 00446 $pred->appendChild($object); 00447 $subject->appendChild($pred); 00448 00449 $resultset->appendChild($subject); 00450 } 00451 00452 00453 // Attributes 00454 00455 $aggregatesUri = $this->uri . "aggregate/" . md5(microtime()); 00456 00457 foreach($this->aggregates["attributes"] as $ftype => $fcount) 00458 { 00459 $subject = 00460 $xml->createSubject("http://purl.org/ontology/aggregate#Aggregate", $aggregatesUri . "/" . md5($ftype) . "/"); 00461 00462 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#property"); 00463 $object = $xml->createObject("", "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property"); 00464 $pred->appendChild($object); 00465 $subject->appendChild($pred); 00466 00467 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#object"); 00468 $object = $xml->createObject("", $ftype); 00469 $pred->appendChild($object); 00470 $subject->appendChild($pred); 00471 00472 $pred = $xml->createPredicate("http://purl.org/ontology/aggregate#count"); 00473 $object = $xml->createObjectContent($fcount); 00474 $pred->appendChild($object); 00475 $subject->appendChild($pred); 00476 00477 $resultset->appendChild($subject); 00478 } 00479 } 00480 00481 return ($this->injectDoctype($xml->saveXML($resultset))); 00482 } 00483 00496 public function injectDoctype($xmlDoc) 00497 { 00498 $posHeader = strpos($xmlDoc, '"?>') + 3; 00499 $xmlDoc = substr($xmlDoc, 0, $posHeader) 00500 . "\n<!DOCTYPE resultset PUBLIC \"-//Structured Dynamics LLC//Browse DTD 0.1//EN\" \"" . $this->dtdBaseURL 00501 . $this->dtdURL . "\">" . substr($xmlDoc, $posHeader, strlen($xmlDoc) - $posHeader); 00502 00503 return ($xmlDoc); 00504 } 00505 00524 public function ws_conneg($accept, $accept_charset, $accept_encoding, $accept_language) 00525 { 00526 $this->conneg = 00527 new Conneg($accept, $accept_charset, $accept_encoding, $accept_language, Browse::$supportedSerializations); 00528 00529 // Validate query 00530 $this->validateQuery(); 00531 00532 // If the query is still valid 00533 if($this->conneg->getStatus() == 200) 00534 { 00535 if($this->items < 0 || $this->items > 128) 00536 { 00537 $this->conneg->setStatus(400); 00538 $this->conneg->setStatusMsg("Bad Request"); 00539 $this->conneg->setStatusMsgExt($this->errorMessenger->_200->name); 00540 $this->conneg->setError($this->errorMessenger->_200->id, $this->errorMessenger->ws, 00541 $this->errorMessenger->_200->name, $this->errorMessenger->_200->description, "", 00542 $this->errorMessenger->_200->level); 00543 return; 00544 } 00545 } 00546 } 00547 00566 public function pipeline_conneg($accept, $accept_charset, $accept_encoding, $accept_language) 00567 { $this->ws_conneg($accept, $accept_charset, $accept_encoding, $accept_language); } 00568 00579 public function pipeline_getResponseHeaderStatus() { return $this->conneg->getStatus(); } 00580 00591 public function pipeline_getResponseHeaderStatusMsg() { return $this->conneg->getStatusMsg(); } 00592 00605 public function pipeline_getResponseHeaderStatusMsgExt() { return $this->conneg->getStatusMsgExt(); } 00606 00617 public function pipeline_serialize() 00618 { 00619 $rdf_part = ""; 00620 00621 switch($this->conneg->getMime()) 00622 { 00623 case "application/json": 00624 $json_part = ""; 00625 $xml = new ProcessorXML(); 00626 $xml->loadXML($this->pipeline_getResultset()); 00627 00628 $subjects = $xml->getSubjects(); 00629 00630 $nsId = 0; 00631 00632 foreach($subjects as $subject) 00633 { 00634 $subjectURI = $xml->getURI($subject); 00635 $subjectType = $xml->getType($subject); 00636 00637 $ns = $this->getNamespace($subjectType); 00638 00639 if(!isset($this->namespaces[$ns[0]])) 00640 { 00641 $this->namespaces[$ns[0]] = "ns" . $nsId; 00642 $nsId++; 00643 } 00644 00645 $json_part .= " { \n"; 00646 $json_part .= " \"uri\": \"" . parent::jsonEncode($subjectURI) . "\", \n"; 00647 $json_part .= " \"type\": \"" . parent::jsonEncode($this->namespaces[$ns[0]] . ":" . $ns[1]) 00648 . "\", \n"; 00649 00650 $predicates = $xml->getPredicates($subject); 00651 00652 $nbPredicates = 0; 00653 00654 foreach($predicates as $predicate) 00655 { 00656 $objects = $xml->getObjects($predicate); 00657 00658 foreach($objects as $object) 00659 { 00660 $nbPredicates++; 00661 00662 if($nbPredicates == 1) 00663 { 00664 $json_part .= " \"predicate\": [ \n"; 00665 } 00666 00667 $objectType = $xml->getType($object); 00668 $predicateType = $xml->getType($predicate); 00669 00670 if($objectType == "rdfs:Literal") 00671 { 00672 $objectValue = $xml->getContent($object); 00673 00674 $ns = $this->getNamespace($predicateType); 00675 00676 if(!isset($this->namespaces[$ns[0]])) 00677 { 00678 $this->namespaces[$ns[0]] = "ns" . $nsId; 00679 $nsId++; 00680 } 00681 00682 $json_part .= " { \n"; 00683 $json_part .= " \"" . parent::jsonEncode($this->namespaces[$ns[0]] . ":" . $ns[1]) . "\": \"" 00684 . parent::jsonEncode($objectValue) . "\" \n"; 00685 $json_part .= " },\n"; 00686 } 00687 else 00688 { 00689 $objectURI = $xml->getURI($object); 00690 00691 $ns = $this->getNamespace($predicateType); 00692 00693 if(!isset($this->namespaces[$ns[0]])) 00694 { 00695 $this->namespaces[$ns[0]] = "ns" . $nsId; 00696 $nsId++; 00697 } 00698 00699 $json_part .= " { \n"; 00700 $json_part .= " \"" . parent::jsonEncode($this->namespaces[$ns[0]] . ":" . $ns[1]) 00701 . "\": { \n"; 00702 $json_part .= " \"uri\": \"" . parent::jsonEncode($objectURI) . "\",\n"; 00703 00704 // Check if there is a reification statement for this object. 00705 $reifies = $xml->getReificationStatements($object, "wsf:objectLabel"); 00706 00707 $nbReification = 0; 00708 00709 foreach($reifies as $reify) 00710 { 00711 $nbReification++; 00712 00713 if($nbReification > 0) 00714 { 00715 $json_part .= " \"reify\": [\n"; 00716 } 00717 00718 $json_part .= " { \n"; 00719 $json_part .= " \"type\": \"wsf:objectLabel\", \n"; 00720 $json_part .= " \"value\": \"" . parent::jsonEncode($xml->getValue($reify)) 00721 . "\" \n"; 00722 $json_part .= " },\n"; 00723 } 00724 00725 if($nbReification > 0) 00726 { 00727 $json_part = substr($json_part, 0, strlen($json_part) - 2) . "\n"; 00728 00729 $json_part .= " ]\n"; 00730 } 00731 else 00732 { 00733 $json_part = substr($json_part, 0, strlen($json_part) - 2) . "\n"; 00734 } 00735 00736 $json_part .= " } \n"; 00737 $json_part .= " },\n"; 00738 } 00739 } 00740 } 00741 00742 if(strlen($json_part) > 0) 00743 { 00744 $json_part = substr($json_part, 0, strlen($json_part) - 2) . "\n"; 00745 } 00746 00747 if($nbPredicates > 0) 00748 { 00749 $json_part .= " ]\n"; 00750 } 00751 00752 $json_part .= " },\n"; 00753 } 00754 00755 if(strlen($json_part) > 0) 00756 { 00757 $json_part = substr($json_part, 0, strlen($json_part) - 2) . "\n"; 00758 } 00759 00760 $json_header .= " \"prefixes\": [ \n"; 00761 $json_header .= " {\n"; 00762 $json_header .= " \"rdf\": \"http://www.w3.org/1999/02/22-rdf-syntax-ns#\",\n"; 00763 $json_header .= " \"wsf\": \"http://purl.org/ontology/wsf#\",\n"; 00764 00765 foreach($this->namespaces as $ns => $prefix) 00766 { 00767 $json_header .= " \"$prefix\": \"$ns\",\n"; 00768 } 00769 00770 if(strlen($json_header) > 0) 00771 { 00772 $json_header = substr($json_header, 0, strlen($json_header) - 2) . "\n"; 00773 } 00774 00775 $json_header .= " } \n"; 00776 $json_header .= " ],\n"; 00777 $json_header .= " \"resultset\": {\n"; 00778 $json_header .= " \"subject\": [\n"; 00779 $json_header .= $json_part; 00780 $json_header .= " ]\n"; 00781 $json_header .= " }\n"; 00782 00783 return ($json_header); 00784 break; 00785 00786 case "application/rdf+n3": 00787 00788 $xml = new ProcessorXML(); 00789 $xml->loadXML($this->pipeline_getResultset()); 00790 00791 $subjects = $xml->getSubjects(); 00792 00793 foreach($subjects as $subject) 00794 { 00795 $subjectURI = $xml->getURI($subject); 00796 $subjectType = $xml->getType($subject, FALSE); 00797 00798 $rdf_part .= "\n <$subjectURI> a <$subjectType> ;\n"; 00799 00800 $predicates = $xml->getPredicates($subject); 00801 00802 foreach($predicates as $predicate) 00803 { 00804 $objects = $xml->getObjects($predicate); 00805 00806 foreach($objects as $object) 00807 { 00808 $objectType = $xml->getType($object); 00809 $predicateType = $xml->getType($predicate, FALSE); 00810 $objectContent = $xml->getContent($object); 00811 00812 if($objectType == "rdfs:Literal") 00813 { 00814 $objectValue = $xml->getContent($object); 00815 $rdf_part .= " <$predicateType> \"\"\"" . str_replace(array( "\\" ), "\\\\", $objectValue) 00816 . "\"\"\" ;\n"; 00817 } 00818 else 00819 { 00820 $objectURI = $xml->getURI($object); 00821 $rdf_part .= " <$predicateType> <$objectURI> ;\n"; 00822 } 00823 } 00824 } 00825 00826 if(strlen($rdf_part) > 0) 00827 { 00828 $rdf_part = substr($rdf_part, 0, strlen($rdf_part) - 2) . ".\n"; 00829 } 00830 } 00831 00832 return ($rdf_part); 00833 break; 00834 00835 case "application/rdf+xml": 00836 $xml = new ProcessorXML(); 00837 $xml->loadXML($this->pipeline_getResultset()); 00838 00839 $subjects = $xml->getSubjects(); 00840 00841 $nsId = 0; 00842 00843 foreach($subjects as $subject) 00844 { 00845 $subjectURI = $xml->getURI($subject); 00846 $subjectType = $xml->getType($subject); 00847 00848 $ns1 = $this->getNamespace($subjectType); 00849 00850 if(!isset($this->namespaces[$ns1[0]])) 00851 { 00852 $this->namespaces[$ns1[0]] = "ns" . $nsId; 00853 $nsId++; 00854 } 00855 00856 $rdf_part .= "\n <" . $this->namespaces[$ns1[0]] . ":" . $ns1[1] . " rdf:about=\"". 00857 $this->xmlEncode($subjectURI)."\">\n"; 00858 00859 $predicates = $xml->getPredicates($subject); 00860 00861 foreach($predicates as $predicate) 00862 { 00863 $objects = $xml->getObjects($predicate); 00864 00865 foreach($objects as $object) 00866 { 00867 $objectType = $xml->getType($object); 00868 $predicateType = $xml->getType($predicate); 00869 00870 if($objectType == "rdfs:Literal") 00871 { 00872 $objectValue = $xml->getContent($object); 00873 00874 $ns = $this->getNamespace($predicateType); 00875 00876 if(!isset($this->namespaces[$ns[0]])) 00877 { 00878 $this->namespaces[$ns[0]] = "ns" . $nsId; 00879 $nsId++; 00880 } 00881 00882 $rdf_part .= " <" . $this->namespaces[$ns[0]] . ":" . $ns[1] . ">" 00883 . $this->xmlEncode($objectValue) . "</" . $this->namespaces[$ns[0]] . ":" . $ns[1] . ">\n"; 00884 } 00885 else 00886 { 00887 $objectURI = $xml->getURI($object); 00888 00889 $ns = $this->getNamespace($predicateType); 00890 00891 if(!isset($this->namespaces[$ns[0]])) 00892 { 00893 $this->namespaces[$ns[0]] = "ns" . $nsId; 00894 $nsId++; 00895 } 00896 00897 $rdf_part .= " <" . $this->namespaces[$ns[0]] . ":" . $ns[1] 00898 . " rdf:resource=\"".$this->xmlEncode($objectURI)."\" />\n"; 00899 } 00900 } 00901 } 00902 00903 $rdf_part .= " </" . $this->namespaces[$ns1[0]] . ":" . $ns1[1] . ">\n"; 00904 } 00905 00906 $rdf_header = "<rdf:RDF "; 00907 00908 foreach($this->namespaces as $ns => $prefix) 00909 { 00910 $rdf_header .= " xmlns:$prefix=\"$ns\""; 00911 } 00912 00913 $rdf_header .= ">\n\n"; 00914 00915 $rdf_part = $rdf_header . $rdf_part; 00916 00917 return ($rdf_part); 00918 break; 00919 } 00920 } 00921 00934 private function getNamespace($uri) 00935 { 00936 $pos = strrpos($uri, "#"); 00937 00938 if($pos !== FALSE) 00939 { 00940 return array (substr($uri, 0, $pos) . "#", substr($uri, $pos + 1, strlen($uri) - ($pos + 1))); 00941 } 00942 else 00943 { 00944 $pos = strrpos($uri, "/"); 00945 00946 if($pos !== FALSE) 00947 { 00948 return array (substr($uri, 0, $pos) . "/", substr($uri, $pos + 1, strlen($uri) - ($pos + 1))); 00949 } 00950 else 00951 { 00952 $pos = strpos($uri, ":"); 00953 00954 if($pos !== FALSE) 00955 { 00956 $nsUri = explode(":", $uri, 2); 00957 00958 foreach($this->namespaces as $uri2 => $prefix2) 00959 { 00960 $uri2 = urldecode($uri2); 00961 00962 if($prefix2 == $nsUri[0]) 00963 { 00964 return (array ($uri2, $nsUri[1])); 00965 } 00966 } 00967 00968 return explode(":", $uri, 2); 00969 } 00970 } 00971 } 00972 00973 return (FALSE); 00974 } 00975 00984 public function pipeline_serialize_reification() 00985 { 00986 $rdf_reification = ""; 00987 00988 switch($this->conneg->getMime()) 00989 { 00990 case "application/rdf+n3": 00991 $xml = new ProcessorXML(); 00992 $xml->loadXML($this->pipeline_getResultset()); 00993 00994 $subjects = $xml->getSubjects(); 00995 00996 $bnodeCounter = 0; 00997 00998 foreach($subjects as $subject) 00999 { 01000 $predicates = $xml->getPredicates($subject); 01001 01002 foreach($predicates as $predicate) 01003 { 01004 $predicateType = $xml->getType($predicate, FALSE); 01005 01006 $objects = $xml->getObjects($predicate); 01007 01008 foreach($objects as $object) 01009 { 01010 $reifies = $xml->getReificationStatementsByType($object, "wsf:objectLabel"); 01011 01012 foreach($reifies as $reify) 01013 { 01014 $rdf_reification .= "_:" . md5($xml->getURI($subject) . $predicateType . $xml->getURI($object)) 01015 . " a rdf:Statement ;\n"; 01016 $bnodeCounter++; 01017 $rdf_reification .= " rdf:subject <" . $xml->getURI($subject) . "> ;\n"; 01018 $rdf_reification .= " rdf:predicate <" . $predicateType . "> ;\n"; 01019 $rdf_reification .= " rdf:object <" . $xml->getURI($object) . "> ;\n"; 01020 $rdf_reification .= " wsf:objectLabel \"" . $xml->getValue($reify) . "\" .\n\n"; 01021 $bnodeCounter++; 01022 } 01023 } 01024 } 01025 } 01026 01027 return ($rdf_reification); 01028 01029 break; 01030 01031 case "application/rdf+xml": 01032 01033 $xml = new ProcessorXML(); 01034 $xml->loadXML($this->pipeline_getResultset()); 01035 01036 $subjects = $xml->getSubjects(); 01037 01038 foreach($subjects as $subject) 01039 { 01040 $predicates = $xml->getPredicates($subject); 01041 01042 foreach($predicates as $predicate) 01043 { 01044 $predicateType = $xml->getType($predicate, FALSE); 01045 01046 $objects = $xml->getObjects($predicate); 01047 01048 foreach($objects as $object) 01049 { 01050 $reifies = $xml->getReificationStatementsByType($object, "wsf:objectLabel"); 01051 01052 foreach($reifies as $reify) 01053 { 01054 $rdf_reification .= "<rdf:Statement rdf:about=\"" 01055 . md5($xml->getURI($subject) . $predicateType . $this->xmlEncode($xml->getURI($object))) . "\">\n"; 01056 $rdf_reification .= " <rdf:subject rdf:resource=\"" . $this->xmlEncode($xml->getURI($subject)) . 01057 "\" />\n"; 01058 $rdf_reification .= " <rdf:predicate rdf:resource=\"" . $this->xmlEncode($predicateType) . "\" />\n"; 01059 $rdf_reification .= " <rdf:object rdf:resource=\"" . $this->xmlEncode($xml->getURI($object)) . 01060 "\" />\n"; 01061 $rdf_reification .= " <wsf:objectLabel>" . $this->xmlEncode($xml->getValue($reify)) 01062 . "</wsf:objectLabel>\n"; 01063 $rdf_reification .= "</rdf:Statement> \n\n"; 01064 } 01065 } 01066 } 01067 } 01068 01069 return ($rdf_reification); 01070 01071 break; 01072 } 01073 } 01074 01085 public function ws_serialize() 01086 { 01087 switch($this->conneg->getMime()) 01088 { 01089 case "application/rdf+n3": 01090 $rdf_document = ""; 01091 $rdf_document .= "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n"; 01092 $rdf_document .= "@prefix wsf: <http://purl.org/ontology/wsf#> .\n"; 01093 01094 $rdf_document .= $this->pipeline_serialize(); 01095 01096 $rdf_document .= $this->pipeline_serialize_reification(); 01097 01098 return $rdf_document; 01099 break; 01100 01101 case "application/rdf+xml": 01102 $rdf_document = ""; 01103 $rdf_document .= "<?xml version=\"1.0\"?>\n"; 01104 01105 $rdf_document .= $this->pipeline_serialize(); 01106 01107 $rdf_document .= $this->pipeline_serialize_reification(); 01108 01109 $rdf_document .= "</rdf:RDF>"; 01110 01111 return $rdf_document; 01112 break; 01113 01114 case "application/json": 01115 $json_document = ""; 01116 $json_document .= "{\n"; 01117 $json_document .= $this->pipeline_serialize(); 01118 $json_document .= "}"; 01119 01120 return ($json_document); 01121 break; 01122 01123 case "text/xml": 01124 return $this->pipeline_getResultset(); 01125 break; 01126 } 01127 } 01128 01141 public function ws_respond($content) 01142 { 01143 // First send the header of the request 01144 $this->conneg->respond(); 01145 01146 // second, send the content of the request 01147 01148 // Make sure there is no error. 01149 if($this->conneg->getStatus() == 200) 01150 { 01151 echo $content; 01152 } 01153 01154 $this->__destruct(); 01155 } 01156 01157 01167 public function process() 01168 { 01169 // Make sure there was no conneg error prior to this process call 01170 if($this->conneg->getStatus() == 200) 01171 { 01172 $solr = new Solr($this->wsf_solr_core, $this->solr_host, $this->solr_port); 01173 01174 $solrQuery = ""; 01175 01176 // Get all datasets accessible to that user 01177 $accessibleDatasets = array(); 01178 01179 $ws_al = new AuthLister("access_user", "", $this->registered_ip, $this->wsf_local_ip); 01180 01181 $ws_al->pipeline_conneg($this->conneg->getAccept(), $this->conneg->getAcceptCharset(), 01182 $this->conneg->getAcceptEncoding(), $this->conneg->getAcceptLanguage()); 01183 01184 $ws_al->process(); 01185 01186 $xml = new ProcessorXML(); 01187 $xml->loadXML($ws_al->pipeline_getResultset()); 01188 01189 $accesses = $xml->getSubjectsByType("wsf:Access"); 01190 01191 foreach($accesses as $access) 01192 { 01193 $predicates = $xml->getPredicatesByType($access, "wsf:datasetAccess"); 01194 $objects = $xml->getObjects($predicates->item(0)); 01195 $datasetUri = $xml->getURI($objects->item(0)); 01196 01197 $predicates = $xml->getPredicatesByType($access, "wsf:read"); 01198 $objects = $xml->getObjects($predicates->item(0)); 01199 $read = $xml->getContent($objects->item(0)); 01200 01201 if(strtolower($read) == "true") 01202 { 01203 array_push($accessibleDatasets, $datasetUri); 01204 } 01205 } 01206 01207 unset($ws_al); 01208 01209 /* 01210 if registered_ip != requester_ip, this means that the query is sent by a registered system 01211 on the behalf of someone else. In this case, we want to make sure that that system 01212 (the one that send the actual query) has access to the same datasets. Otherwise, it means that 01213 it tries to personificate that registered_ip user. 01214 */ 01215 if($this->registered_ip != $this->requester_ip) 01216 { 01217 // Get all datasets accessible to that system 01218 $accessibleDatasetsSystem = array(); 01219 01220 $ws_al = new AuthLister("access_user", "", $this->requester_ip, $this->wsf_local_ip); 01221 01222 $ws_al->pipeline_conneg($this->conneg->getAccept(), $this->conneg->getAcceptCharset(), 01223 $this->conneg->getAcceptEncoding(), $this->conneg->getAcceptLanguage()); 01224 01225 $ws_al->process(); 01226 01227 $xml = new ProcessorXML(); 01228 $xml->loadXML($ws_al->pipeline_getResultset()); 01229 01230 $accesses = $xml->getSubjectsByType("wsf:Access"); 01231 01232 foreach($accesses as $access) 01233 { 01234 $predicates = $xml->getPredicatesByType($access, "wsf:datasetAccess"); 01235 $objects = $xml->getObjects($predicates->item(0)); 01236 $datasetUri = $xml->getURI($objects->item(0)); 01237 01238 $predicates = $xml->getPredicatesByType($access, "wsf:read"); 01239 $objects = $xml->getObjects($predicates->item(0)); 01240 $read = $xml->getContent($objects->item(0)); 01241 01242 if(strtolower($read) == "true") 01243 { 01244 array_push($accessibleDatasetsSystem, $datasetUri); 01245 } 01246 } 01247 01248 unset($ws_al); 01249 01250 /* 01251 Finally we use the intersection of the two set of dataset URIs as the list of accessible 01252 datasets to include for the query. 01253 */ 01254 $accessibleDatasets = array_intersect($accessibleDatasets, $accessibleDatasetsSystem); 01255 } 01256 01257 if(count($accessibleDatasets) <= 0) 01258 { 01259 $this->conneg->setStatus(400); 01260 $this->conneg->setStatusMsg("Bad Request"); 01261 $this->conneg->setStatusMsgExt($this->errorMessenger->_300->name); 01262 $this->conneg->setError($this->errorMessenger->_300->id, $this->errorMessenger->ws, 01263 $this->errorMessenger->_300->name, $this->errorMessenger->_300->description, "", 01264 $this->errorMessenger->_300->level); 01265 return; 01266 } 01267 01268 if(strtolower($this->datasets) == "all") 01269 { 01270 $datasetList = ""; 01271 01272 $solrQuery = "q=*:*&start=" . $this->page . "&rows=" . $this->items 01273 . (strtolower($this->includeAggregates) == "true" ? "&facet=true&facet.limit=-1&facet.field=type" . 01274 "&facet.field=attribute" . (strtolower($this->inference) == "on" ? "&facet.field=inferred_type" : "") . "&" . 01275 "facet.field=dataset&facet.mincount=1" : ""); 01276 01277 foreach($accessibleDatasets as $key => $dataset) 01278 { 01279 if($key == 0) 01280 { 01281 $solrQuery .= "&fq=dataset:%22" . urlencode($dataset) . "%22"; 01282 } 01283 else 01284 { 01285 $solrQuery .= " OR dataset:%22" . urlencode($dataset) . "%22"; 01286 } 01287 } 01288 } 01289 else 01290 { 01291 $datasets = explode(";", $this->datasets); 01292 01293 $solrQuery = "q=*:*&start=" . $this->page . "&rows=" . $this->items 01294 . (strtolower($this->includeAggregates) == "true" ? "&facet=true&facet.limit=-1&facet.field=type" . 01295 "&facet.field=attribute" . (strtolower($this->inference) == "on" ? "&facet.field=inferred_type" : "") . "&" . 01296 "facet.field=dataset&facet.mincount=1" : ""); 01297 01298 $solrQuery .= "&fq=dataset:%22%22"; 01299 01300 foreach($datasets as $dataset) 01301 { 01302 // Check if the dataset is accessible to the user 01303 if(array_search($dataset, $accessibleDatasets) !== FALSE) 01304 { 01305 // Decoding potentially encoded ";" characters 01306 $dataset = str_replace(array ("%3B", "%3b"), ";", $dataset); 01307 01308 $solrQuery .= " OR dataset:%22" . urlencode($dataset) . "%22"; 01309 } 01310 } 01311 } 01312 01313 if($this->types != "all") 01314 { 01315 // Lets include the information to facet per type. 01316 01317 $types = explode(";", $this->types); 01318 01319 $nbProcessed = 0; 01320 01321 foreach($types as $type) 01322 { 01323 // Decoding potentially encoded ";" characters 01324 $type = str_replace(array ("%3B", "%3b"), ";", $type); 01325 01326 if($nbProcessed == 0) 01327 { 01328 $solrQuery .= "&fq=type:%22" . urlencode($type) . "%22"; 01329 } 01330 else 01331 { 01332 $solrQuery .= " OR type:%22" . urlencode($type) . "%22"; 01333 } 01334 01335 $nbProcessed++; 01336 01337 if(strtolower($this->inference) == "on") 01338 { 01339 $solrQuery .= " OR inferred_type:%22" . urlencode($type) . "%22"; 01340 } 01341 } 01342 } 01343 01344 if($this->attributes != "all") 01345 { 01346 // Lets include the information to facet per type. 01347 01348 $attributes = explode(";", $this->attributes); 01349 01350 $nbProcessed = 0; 01351 01352 foreach($attributes as $attribute) 01353 { 01354 // Decoding potentially encoded ";" characters 01355 $type = str_replace(array ("%3B", "%3b"), ";", $type); 01356 01357 if($nbProcessed == 0) 01358 { 01359 $solrQuery .= "&fq=(attribute:%22" . urlencode($attribute) . "%22)"; 01360 } 01361 else 01362 { 01363 $solrQuery .= " AND (attribute:%22" . urlencode($attribute) . "%22)"; 01364 } 01365 01366 $nbProcessed++; 01367 } 01368 } 01369 01370 $resultset = $solr->select($solrQuery); 01371 01372 $domResultset = new DomDocument("1.0", "utf-8"); 01373 $domResultset->loadXML($resultset); 01374 01375 $xpath = new DOMXPath($domResultset); 01376 01377 // Get the number of results 01378 $founds = $xpath->query("*[@numFound]"); 01379 01380 foreach($founds as $found) 01381 { 01382 $nbResources = $found->attributes->getNamedItem("numFound")->nodeValue; 01383 break; 01384 } 01385 01386 // Get all the "type" facets with their counts 01387 $founds = $xpath->query("//*/lst[@name='facet_fields']//lst[@name='type']/int"); 01388 01389 // Get types counts 01390 01391 $this->aggregates["type"] = array(); 01392 01393 foreach($founds as $found) 01394 { 01395 $this->aggregates["type"][$found->attributes->getNamedItem("name")->nodeValue] = $found->nodeValue; 01396 } 01397 01398 // Get inferred types counts 01399 01400 if(strtolower($this->inference) == "on") 01401 { 01402 // Get all the "inferred_type" facets with their counts 01403 $founds = $xpath->query("//*/lst[@name='facet_fields']//lst[@name='inferred_type']/int"); 01404 01405 // Get types counts 01406 $this->aggregates["inferred_type"] = array(); 01407 01408 foreach($founds as $found) 01409 { 01410 $this->aggregates["inferred_type"][$found->attributes->getNamedItem("name")->nodeValue] = $found->nodeValue; 01411 } 01412 } 01413 01414 // Get all the "dataset" facets with their counts 01415 $founds = $xpath->query("//*/lst[@name='facet_fields']//lst[@name='dataset']/int"); 01416 01417 $this->aggregates["dataset"] = array(); 01418 01419 foreach($founds as $found) 01420 { 01421 $this->aggregates["dataset"][$found->attributes->getNamedItem("name")->nodeValue] = $found->nodeValue; 01422 } 01423 01424 01425 // Get all the "property" and "object_property" facets with their counts 01426 $founds = $xpath->query("//*/lst[@name='facet_fields']//lst[@name='attribute']/int"); 01427 01428 $this->aggregates["attributes"] = array(); 01429 01430 foreach($founds as $found) 01431 { 01432 $this->aggregates["attributes"][$found->attributes->getNamedItem("name")->nodeValue] = $found->nodeValue; 01433 } 01434 01435 01436 // Get all the results 01437 01438 $resultsDom = $xpath->query("//doc"); 01439 01440 foreach($resultsDom as $result) 01441 { 01442 // get URI 01443 $resultURI = $xpath->query("arr[@name='uri']/str", $result); 01444 // $resultURI = $xpath->query("str[@name='uri']", $result); 01445 01446 $uri = ""; 01447 01448 foreach($resultURI as $u) 01449 { 01450 $uri = $u->nodeValue; 01451 $this->resultset[$uri] = array(); 01452 break; 01453 } 01454 01455 // get Dataset URI 01456 $resultDatasetURI = $xpath->query("arr[@name='dataset']", $result); 01457 // $resultDatasetURI = $xpath->query("str[@name='dataset']", $result); 01458 01459 $datasetUri = ""; 01460 01461 foreach($resultDatasetURI as $u) 01462 { 01463 $this->resultset[$uri]["dataset"] = $u->nodeValue; 01464 break; 01465 } 01466 01467 01468 // get records preferred label 01469 $resultPrefLabelURI = $xpath->query("arr[@name='prefLabel']", $result); 01470 01471 foreach($resultPrefLabelURI as $u) 01472 { 01473 $this->resultset[$uri]["prefLabel"] = $u->nodeValue; 01474 break; 01475 } 01476 01477 // get records aternative labels 01478 $resultAltLabelURI = $xpath->query("arr[@name='altLabel']", $result); 01479 01480 foreach($resultAltLabelURI as $u) 01481 { 01482 if(!isset($this->resultset[$uri]["altLabel"])) 01483 { 01484 $this->resultset[$uri]["altLabel"] = array( $u->nodeValue ); 01485 } 01486 else 01487 { 01488 array_push($this->resultset[$uri]["altLabel"], $u->nodeValue); 01489 } 01490 } 01491 01492 // get records description 01493 $resultDescriptionURI = $xpath->query("arr[@name='description']", $result); 01494 01495 foreach($resultDescriptionURI as $u) 01496 { 01497 $this->resultset[$uri]["description"] = $u->nodeValue; 01498 } 01499 01500 01501 // Get all dynamic fields attributes. 01502 $resultProperties = $xpath->query("arr", $result); 01503 01504 $tempProperties = array(); 01505 01506 foreach($resultProperties as $property) 01507 { 01508 $attribute = $property->getAttribute("name"); 01509 01510 // Check what kind of attribute it is 01511 $attributeType = ""; 01512 01513 if(($pos = stripos($attribute, "_reify")) !== FALSE) 01514 { 01515 $attributeType = substr($attribute, $pos, strlen($attribute) - $pos); 01516 } 01517 elseif(($pos = stripos($attribute, "_attr")) !== FALSE) 01518 { 01519 $attributeType = substr($attribute, $pos, strlen($attribute) - $pos); 01520 } 01521 01522 // Get the URI of the attribute 01523 $attributeURI = urldecode(str_replace($attributeType, "", $attribute)); 01524 01525 switch($attributeType) 01526 { 01527 case "_attr": 01528 $values = $property->getElementsByTagName("str"); 01529 01530 foreach($values as $value) 01531 { 01532 if(!isset($this->resultset[$uri][$attributeURI])) 01533 { 01534 $this->resultset[$uri][$attributeURI] = array( $value->nodeValue ); 01535 } 01536 else 01537 { 01538 array_push($this->resultset[$uri][$attributeURI], $value->nodeValue); 01539 } 01540 } 01541 break; 01542 01543 case "_attr_obj": 01544 $values = $property->getElementsByTagName("str"); 01545 01546 foreach($values as $value) 01547 { 01548 if(!isset($this->resultsetObjectProperties[$uri][$attributeURI])) 01549 { 01550 $this->resultsetObjectProperties[$uri][$attributeURI] = array( $value->nodeValue ); 01551 } 01552 else 01553 { 01554 array_push($this->resultsetObjectProperties[$uri][$attributeURI], $value->nodeValue); 01555 } 01556 } 01557 break; 01558 01559 case "_attr_obj_uri": 01560 $values = $property->getElementsByTagName("str"); 01561 01562 foreach($values as $value) 01563 { 01564 if(!isset($this->resultsetObjectPropertiesUris[$uri][$attributeURI])) 01565 { 01566 $this->resultsetObjectPropertiesUris[$uri][$attributeURI] = array( $value->nodeValue ); 01567 } 01568 else 01569 { 01570 array_push($this->resultsetObjectPropertiesUris[$uri][$attributeURI], $value->nodeValue); 01571 } 01572 } 01573 break; 01574 01575 case "_reify_attr": 01576 case "_reify_attr_obj": 01577 case "_reify_obj": 01578 case "_reify_value": break; 01579 } 01580 } 01581 01582 // Get the first type of the resource. 01583 $resultTypes = $xpath->query("arr[@name='type']/str", $result); 01584 01585 foreach($resultTypes as $t) 01586 { 01587 if($t->nodeValue != "-") 01588 { 01589 if(!isset($this->resultset[$uri]["type"])) 01590 { 01591 $this->resultset[$uri]["type"] = array( $t->nodeValue ); 01592 } 01593 else 01594 { 01595 array_push($this->resultset[$uri]["type"], $t->nodeValue); 01596 } 01597 } 01598 } 01599 } 01600 } 01601 } 01602 } 01603 01604 01606 01607 ?>
