ConverterCommON.php
Go to the documentation of this file.
00001 <?php 00002 00005 00027 class ConverterCommON extends WebService 00028 { 00030 private $db; 00031 00033 private $conneg; 00034 00036 private $dtdURL; 00037 00039 private $text; 00040 00042 private $docmime; 00043 00045 private $type; 00046 00048 private $errorMessages = ""; 00049 00051 private $requester_ip = ""; 00052 00054 private $registered_ip = ""; 00055 00057 private $parser; 00058 00060 private $namespaces = array(); 00061 00065 private $customLinkageSchema; 00066 00068 public static $supportedSerializations = 00069 array ("application/iron+csv", "application/rdf+n3", "application/*", "text/xml", "text/*", "*/*"); 00070 00072 private $errorMessenger = 00073 '{ 00074 "ws": "/ws/converter/common/", 00075 "_200": { 00076 "id": "WS-CONVERTER-COMMON-200", 00077 "level": "Warning", 00078 "name": "No linkage file specified", 00079 "description": "No linkage file of type \'RDF\' has been defined for this Instance Record Vocabulary file." 00080 }, 00081 "_201": { 00082 "id": "WS-CONVERTER-COMMON-201", 00083 "level": "Warning", 00084 "name": "No data to convert", 00085 "description": "No data is available for conversion" 00086 }, 00087 "_300": { 00088 "id": "WS-CONVERTER-COMMON-300", 00089 "level": "Warning", 00090 "name": "CSV parsing error(s)", 00091 "description": "CSV parsing error(s)" 00092 }, 00093 "_301": { 00094 "id": "WS-CONVERTER-COMMON-301", 00095 "level": "Warning", 00096 "name": "commON validation error(s)", 00097 "description": "commON validation error(s)" 00098 }, 00099 "_302": { 00100 "id": "WS-CONVERTER-COMMON-302", 00101 "level": "Warning", 00102 "name": "Unsupported Document Mime", 00103 "description": "The MIME type of the document you sent to this commON conversion web service is not supported." 00104 } 00105 }'; 00106 00107 00124 function __construct($document = "", $docmime = "application/iron+csv", $registered_ip, $requester_ip) 00125 { 00126 parent::__construct(); 00127 00128 $this->text = $document; 00129 $this->docmime = $docmime; 00130 00131 $this->requester_ip = $requester_ip; 00132 00133 if($registered_ip == "") 00134 { 00135 $this->registered_ip = $requester_ip; 00136 } 00137 else 00138 { 00139 $this->registered_ip = $registered_ip; 00140 } 00141 00142 if(strtolower(substr($this->registered_ip, 0, 4)) == "self") 00143 { 00144 $pos = strpos($this->registered_ip, "::"); 00145 00146 if($pos !== FALSE) 00147 { 00148 $account = substr($this->registered_ip, $pos + 2, strlen($this->registered_ip) - ($pos + 2)); 00149 00150 $this->registered_ip = $requester_ip . "::" . $account; 00151 } 00152 else 00153 { 00154 $this->registered_ip = $requester_ip; 00155 } 00156 } 00157 00158 $this->irJSONResources = array(); 00159 00160 $this->uri = $this->wsf_base_url . "/wsf/ws/converter/common/"; 00161 $this->title = "CommON Converter Web Service"; 00162 $this->crud_usage = new CrudUsage(FALSE, TRUE, FALSE, FALSE); 00163 $this->endpoint = $this->wsf_base_url . "/ws/converter/common/"; 00164 00165 $this->dtdURL = "converter/common.dtd"; 00166 00167 $this->errorMessenger = json_decode($this->errorMessenger); 00168 } 00169 00170 function __destruct() 00171 { 00172 parent::__destruct(); 00173 00174 if(isset($this->db)) 00175 { 00176 $this->db->close(); 00177 } 00178 } 00179 00190 protected function validateQuery() { return; } 00191 00192 protected function splitUri($str, &$base, &$ext) 00193 { 00194 $pos = FALSE; 00195 00196 $base = ""; 00197 $ext = ""; 00198 00199 if(($pos = strrpos($str, "#")) === FALSE) 00200 { 00201 $pos = strrpos($str, "/"); 00202 } 00203 00204 if($pos !== FALSE) 00205 { 00206 $base = substr($str, 0, $pos); 00207 $ext = substr($str, $pos + 1, strlen($str) - $pos - 1); 00208 } 00209 else 00210 { 00211 $base = ""; 00212 $ext = $str; 00213 } 00214 } 00215 00226 public function pipeline_getError() { return ($this->conneg->error); } 00227 00238 public function pipeline_getResultset() 00239 { 00240 if($this->docmime == "application/iron+csv") 00241 { 00242 // Get the ID of the dataset has the base ID of the records 00243 $dataset = $this->parser->getDataset(); 00244 $datasetID = ""; 00245 00246 if(isset($dataset["&id"][0]["value"])) 00247 { 00248 $datasetID = $dataset["&id"][0]["value"]; 00249 } 00250 00251 $commonLinkageSchema = $this->parser->getLinkageSchema(); 00252 00253 // Check if a linkage file of kind RDF has been defined for this irJSON file. 00254 if(isset($commonLinkageSchema["description"]["&linkedType"]) && 00255 $commonLinkageSchema["description"]["&linkedType"][0] == "application/rdf+xml") 00256 { 00257 $structXML = ' 00258 <resultset> 00259 <prefix entity="owl" uri="http://www.w3.org/2002/07/owl#"/> 00260 <prefix entity="rdf" uri="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/> 00261 <prefix entity="rdfs" uri="http://www.w3.org/2000/01/rdf-schema#"/> 00262 00263 '; 00264 00265 // Convert each record that have been converted 00266 foreach($this->parser->getCommonRecords() as $record) 00267 { 00268 // Map ID & type 00269 $type = array(); 00270 00271 if(count($record["&type"]) == 0) 00272 { 00273 array_push($type, "http://www.w3.org/2002/07/owl#Thing"); 00274 } 00275 elseif(count($record["&type"]) >= 1) 00276 { 00277 foreach($record["&type"] as $rt) 00278 { 00279 // check in the linkage file for the type 00280 $t = $this->parser->getLinkedType($rt["value"]); 00281 00282 if($t == "") 00283 { 00284 // If the type doesn't exist, we simply use the generic owl:Thing type 00285 array_push($type, "http://www.w3.org/2002/07/owl#Thing"); 00286 } 00287 else 00288 { 00289 // Otherwise we use the linked type 00290 array_push($type, $t); 00291 } 00292 } 00293 } 00294 00295 // Get the ID of the record 00296 $recordId = $datasetID . $record["&id"][0]["value"]; 00297 00298 // Serialize the type(s) used to define the record 00299 if(count($type) == 1) 00300 { 00301 $structXML .= "<subject type=\"" . $this->xmlEncode($type[0]) . "\" uri=\"" . $this->xmlEncode($recordId) . 00302 "\">\n"; 00303 } 00304 else 00305 { 00306 $n3 .= "\n"; 00307 00308 $first = TRUE; 00309 00310 foreach($type as $key => $t) 00311 { 00312 if($first === TRUE) 00313 { 00314 $structXML .= "<subject type=\"" . $this->xmlEncode($t) . "\" uri=\"" . $this->xmlEncode($recordId) . 00315 "\">\n"; 00316 $first = FALSE; 00317 } 00318 else 00319 { 00320 // Multiple types defined for this subject. 00321 $structXML .= " 00322 <predicate type=\"rdf:type\"> 00323 <object uri=\"" . $this->xmlEncode($t) . "\">1282</object> 00324 </predicate> 00325 "; 00326 } 00327 } 00328 } 00329 00330 // Map properties / values of the record 00331 foreach($record as $property => $values) 00332 { 00333 // Make sure we don't process twice the ID and the TYPE 00334 if($property != "&id" && $property != "&type") 00335 { 00336 foreach($values as $value) 00337 { 00338 if($value != "") 00339 { 00340 // Check for possible reification statements 00341 $reifications = ""; 00342 00343 if(is_array($value["reify"])) 00344 { 00345 foreach($value["reify"] as $reifiedAttribute => $reiValues) 00346 { 00347 $rp = $this->parser->getLinkedProperty($reifiedAttribute); 00348 00349 // Reification re-use RDF's reification vocabulary: http://www.w3.org/TR/REC-rdf-syntax/#reification 00350 00351 if($rp == "") 00352 { 00353 $reiProperty = $datasetID . substr($reifiedAttribute, 1, strlen($reifiedAttribute) - 1); 00354 } 00355 // @TODO: Check if "@" or "@@" 00356 $reifications .= "<reify type=\"" . $this->xmlEncode($reiProperty) . "\" value=\"" . 00357 $this->xmlEncode($reiValue) . "\" />\n"; 00358 } 00359 } 00360 00361 // Check if this attribute is part of the linkage schema 00362 $p = $this->parser->getLinkedProperty($property); 00363 00364 if($p == "") 00365 { 00366 // If the attribute to be converted is not part of the linakge schema, then we 00367 // simply create a "on-the-fly" attribute by using the $baseOntology URI. 00368 $p = $datasetID . substr($property, 1, strlen($property) - 1); 00369 } 00370 00371 // Check if the value is a local record reference 00372 if(substr($value["value"], 0, 1) == "@") 00373 { 00374 if($reifications != "") 00375 { 00376 $structXML .= " 00377 <predicate type=\"" . $this->xmlEncode($p) . "\"> 00378 <object uri=\"" . $this->xmlEncode($datasetID . $value["value"]) . "\"> 00379 " . $this->xmlEncode($reifications) . " 00380 </object> 00381 </predicate> 00382 "; 00383 } 00384 else 00385 { 00386 $structXML .= " 00387 <predicate type=\"" . $this->xmlEncode($p) . "\"> 00388 <object uri=\"" . $this->xmlEncode($datasetID . $value["value"]) . "\" /> 00389 </predicate> 00390 "; 00391 } 00392 } 00393 // Check if the value is an external record reference 00394 elseif(substr($value["value"], 0, 2) == "@@") 00395 { 00396 if($reifications != "") 00397 { 00398 $structXML .= " 00399 <predicate type=\"" . $this->xmlEncode($p) . "\"> 00400 <object uri=\"" . $this->xmlEncode($value["value"]) . "\"> 00401 " . $this->xmlEncode($reifications) . " 00402 </object> 00403 </predicate> 00404 "; 00405 } 00406 else 00407 { 00408 $structXML .= " 00409 <predicate type=\"" . $this->xmlEncode($p) . "\"> 00410 <object uri=\"" . $this->xmlEncode($value["value"]) . "\" /> 00411 </predicate> 00412 "; 00413 } 00414 } 00415 else 00416 { 00417 // @TODO adding reification statements here once the @ @@ are handled. 00418 // See task: http://community.openstructs.org/content/updating-reification-structxml 00419 00420 // The value is a literal 00421 $structXML .= " 00422 <predicate type=\"" . $this->xmlEncode($p) . "\"> 00423 <object type=\"rdfs:Literal\">".$this->xmlEncode($value["value"])."</object> 00424 </predicate> 00425 "; 00426 } 00427 } 00428 } 00429 } 00430 } 00431 00432 $structXML .= "</subject>\n"; 00433 } 00434 00435 00436 $structXML .= ' 00437 </resultset> 00438 '; 00439 00440 return($structXML); 00441 } 00442 00443 // No RDF linkage file exists for this irJSON file, then we throw an error 00444 $this->conneg->setStatus(400); 00445 $this->conneg->setStatusMsg("Bad Request"); 00446 $this->conneg->setStatusMsgExt($this->errorMessenger->_200->name); 00447 $this->conneg->setError($this->errorMessenger->_200->id, $this->errorMessenger->ws, 00448 $this->errorMessenger->_200->name, $this->errorMessenger->_200->description, 00449 "No linkage file of type 'RDF' has been defined for this commON file. Cant convert this file in '" 00450 . $this->conneg->getMime() . "'", $this->errorMessenger->_200->level); 00451 return; 00452 } 00453 00454 // Unsupported docmime type 00455 00456 $this->conneg->setStatus(400); 00457 $this->conneg->setStatusMsg("Bad Request"); 00458 $this->conneg->setStatusMsgExt($this->errorMessenger->_302->name); 00459 $this->conneg->setError($this->errorMessenger->_302->id, $this->errorMessenger->ws, 00460 $this->errorMessenger->_302->name, $this->errorMessenger->_302->description, 00461 "Mime type you requested: " . $this->docmime, $this->errorMessenger->_302->level); 00462 } 00463 00476 private function get_domain($url) 00477 { 00478 if(strlen($url) > 8) 00479 { 00480 $pos = strpos($url, "/", 8); 00481 00482 if($pos === FALSE) 00483 { 00484 return $url; 00485 } 00486 else 00487 { 00488 return substr($url, 0, $pos); 00489 } 00490 } 00491 else 00492 { 00493 return $url; 00494 } 00495 } 00496 00509 public function injectDoctype($xmlDoc) 00510 { 00511 $posHeader = strpos($xmlDoc, '"?>') + 3; 00512 $xmlDoc = substr($xmlDoc, 0, $posHeader) 00513 . "\n<!DOCTYPE resultset PUBLIC \"-//Structured Dynamics LLC//Converter commON DTD 0.1//EN\" \"" 00514 . $this->dtdBaseURL . $this->dtdURL . "\">" . substr($xmlDoc, $posHeader, strlen($xmlDoc) - $posHeader); 00515 00516 return ($xmlDoc); 00517 } 00518 00519 00538 public function ws_conneg($accept, $accept_charset, $accept_encoding, $accept_language) 00539 { 00540 $this->conneg = new Conneg($accept, $accept_charset, $accept_encoding, $accept_language, 00541 ConverterCommON::$supportedSerializations); 00542 00543 // No text to process? Throw an error. 00544 if($this->text == "") 00545 { 00546 $this->conneg->setStatus(400); 00547 $this->conneg->setStatusMsg("Bad Request"); 00548 $this->conneg->setStatusMsgExt($this->errorMessenger->_201->name); 00549 $this->conneg->setError($this->errorMessenger->_201->id, $this->errorMessenger->ws, 00550 $this->errorMessenger->_201->name, $this->errorMessenger->_201->description, "", 00551 $this->errorMessenger->_201->level); 00552 } 00553 } 00554 00573 public function pipeline_conneg($accept, $accept_charset, $accept_encoding, $accept_language) 00574 { $this->ws_conneg($accept, $accept_charset, $accept_encoding, $accept_language); } 00575 00586 public function pipeline_getResponseHeaderStatus() { return $this->conneg->getStatus(); } 00587 00598 public function pipeline_getResponseHeaderStatusMsg() { return $this->conneg->getStatusMsg(); } 00599 00612 public function pipeline_getResponseHeaderStatusMsgExt() { return $this->conneg->getStatusMsgExt(); } 00613 00624 public function pipeline_serialize() 00625 { 00626 $rdf_part = ""; 00627 00628 switch($this->conneg->getMime()) 00629 { 00630 case "text/xml": 00631 { 00632 return($this->pipeline_getResultset()); 00633 } 00634 break; 00635 00636 case "application/rdf+n3": 00637 { 00638 $dataset = $this->parser->getDataset(); 00639 00640 $datasetID = ""; 00641 00642 if(isset($dataset["&id"][0]["value"])) 00643 { 00644 $datasetID = $dataset["&id"][0]["value"]; 00645 } 00646 00647 return($this->parser->getRdfN3($datasetID, $datasetID)); 00648 } 00649 break; 00650 } 00651 } 00652 00661 public function pipeline_serialize_reification() 00662 { 00663 $rdf_reification = ""; 00664 00665 switch($this->conneg->getMime()) 00666 { 00667 00668 } 00669 } 00670 00681 public function ws_serialize() 00682 { 00683 // Check for parsing errors 00684 if($this->conneg->getStatus() != 200) 00685 { 00686 return; 00687 } 00688 else 00689 { 00690 switch($this->conneg->getMime()) 00691 { 00692 case "text/xml": 00693 case "application/rdf+n3": 00694 return ($this->pipeline_serialize()); 00695 break; 00696 } 00697 } 00698 } 00699 00712 private function getNamespace($uri) 00713 { 00714 $pos = strpos($uri, "#"); 00715 00716 if($pos !== FALSE) 00717 { 00718 return array (substr($uri, 0, $pos) . "#", substr($uri, $pos + 1, strlen($uri) - ($pos + 1))); 00719 } 00720 else 00721 { 00722 $pos = strrpos($uri, "/"); 00723 00724 if($pos !== FALSE) 00725 { 00726 return array (substr($uri, 0, $pos) . "/", substr($uri, $pos + 1, strlen($uri) - ($pos + 1))); 00727 } 00728 } 00729 00730 return (FALSE); 00731 } 00732 00733 00746 private function uriEncode($uri) 00747 { 00748 $uri = preg_replace("|[^a-zA-z0-9]|", " ", $uri); 00749 $uri = preg_replace("/\s+/", " ", $uri); 00750 $uri = str_replace(" ", "_", $uri); 00751 00752 return ($uri); 00753 } 00754 00755 00768 public function ws_respond($content) 00769 { 00770 // First send the header of the request 00771 $this->conneg->respond(); 00772 00773 // second, send the content of the request 00774 00775 // Make sure there is no error. 00776 if($this->conneg->getStatus() == 200) 00777 { 00778 echo $content; 00779 } 00780 00781 $this->__destruct(); 00782 } 00783 00792 public function process() 00793 { 00794 if($this->conneg->getStatus() == 200) 00795 { 00796 switch($this->docmime) 00797 { 00798 case "application/iron+csv": 00799 $this->parser = new CommonParser($this->text); 00800 00801 // var_dump($this->parser);die; 00802 00803 $csvErrors = $this->parser->getCsvErrors(); 00804 $commonErrors = $this->parser->getCommonErrors(); 00805 00806 if($csvErrors && count($csvErrors) > 0) 00807 { 00808 $errorMsg = ""; 00809 00810 foreach($csvErrors as $key => $error) 00811 { 00812 $errorMsg .= "\n(" . ($key + 1) . ") $error \n"; 00813 } 00814 00815 $this->conneg->setStatus(400); 00816 $this->conneg->setStatusMsg("Bad Request"); 00817 $this->conneg->setStatusMsgExt($this->errorMessenger->_300->name); 00818 $this->conneg->setError($this->errorMessenger->_300->id, $this->errorMessenger->ws, 00819 $this->errorMessenger->_300->name, $this->errorMessenger->_300->description, $errorMsg, 00820 $this->errorMessenger->_300->level); 00821 } 00822 elseif($commonErrors && count($commonErrors) > 0) 00823 { 00824 $errorMsg = ""; 00825 00826 foreach($commonErrors as $key => $error) 00827 { 00828 $errorMsg .= "\n(" . ($key + 1) . ") $error \n"; 00829 } 00830 00831 $this->conneg->setStatus(400); 00832 $this->conneg->setStatusMsg("Bad Request"); 00833 $this->conneg->setStatusMsgExt($this->errorMessenger->_301->name); 00834 $this->conneg->setError($this->errorMessenger->_301->id, $this->errorMessenger->ws, 00835 $this->errorMessenger->_301->name, $this->errorMessenger->_301->description, $errorMsg, 00836 $this->errorMessenger->_301->level); 00837 } 00838 break; 00839 00840 case "text/xml": break; 00841 } 00842 } 00843 } 00844 } 00845 00847 00848 ?>
