function IndexOntologiesDirectory($dir) { global $network_ini; $count = 0; $fail = 0; if ($handler = opendir($dir)) { while (($sub = readdir($handler)) !== FALSE) { if ($sub != "." && $sub != "..") { if (is_file($dir . "/" . $sub)) { $uri = "file://localhost" . $dir . "/" . $sub; echo "Processing ontology file: {$uri}\n"; $exts = split("[/\\.]", $sub); $n = count($exts) - 1; $mimetype = $exts[$n] == "n3" || $exts[$n] == "ttl" ? "n3" : "xml"; try { $wsq = new WebServiceQuerier($network_ini["network"]["wsf_base_url"] . "/ws/ontology/create/", "post", "application/rdf+{$mimetype}", "&uri=" . urlencode($uri) . "&globalPermision=False;True;False;False" . "&advancedIndexation=True" . "®istered_ip=" . urlencode("self")); if ($wsq->getStatus() != 200) { echo "Web service error: (status: " . strip_tags($wsq->getStatus()) . ") " . strip_tags($wsq->getStatusMessage()) . " - " . strip_tags($wsq->getStatusMessageDescription()); } else { echo "Successfully loaded: {$uri}\n"; } } catch (Exception $ex) { echo $e->getMessage(); $fail++; } unset($wsq); $count++; } elseif (is_dir($dir . "/" . $sub)) { IndexOntologiesDirectory($dir . "/" . $sub); } } } closedir($handler); } echo "Processing complete.\n"; echo "Successfully uploaded " . ($count - $fail) . " of {$count} ontology files ({$fail} upload failures).\n"; }
public function processInterface() { // Make sure there was no conneg error prior to this process call if ($this->ws->conneg->getStatus() == 200) { $this->ws->validateQuery(); // If the query is still valid if ($this->ws->conneg->getStatus() == 200) { // Get triples from ARC for some offline processing. include_once "../../framework/arc2/ARC2.php"; $parser = ARC2::getRDFParser(); $parser->parse($this->ws->dataset, $this->ws->document); $rdfxmlSerializer = ARC2::getRDFXMLSerializer(); $resourceIndex = $parser->getSimpleIndex(0); if (count($parser->getErrors()) > 0) { $errorsOutput = ""; $errors = $parser->getErrors(); foreach ($errors as $key => $error) { $errorsOutput .= "[Error #{$key}] {$error}\n"; } $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_301->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_301->name, $this->ws->errorMessenger->_301->description, $errorsOutput, $this->ws->errorMessenger->_301->level); return; } // First: check for a void:Dataset description to add to the "dataset description graph" of structWSF $break = FALSE; $datasetUri = ""; foreach ($resourceIndex as $resource => $description) { foreach ($description as $predicate => $values) { if ($predicate == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") { foreach ($values as $value) { if ($value["type"] == "uri" && $value["value"] == "http://rdfs.org/ns/void#Dataset") { $datasetUri = $resource; break; } } } if ($break) { break; } } if ($break) { break; } } // Second: get all the reification statements $break = FALSE; $statementsUri = array(); foreach ($resourceIndex as $resource => $description) { foreach ($description as $predicate => $values) { if ($predicate == "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") { foreach ($values as $value) { if ($value["type"] == "uri" && $value["value"] == "http://www.w3.org/1999/02/22-rdf-syntax-ns#Statement") { array_push($statementsUri, $resource); break; } } } if ($break) { break; } } if ($break) { break; } } // Third, get all references of all instance records resources (except for the statement resources) $irsUri = array(); foreach ($resourceIndex as $resource => $description) { if ($resource != $datasetUri && array_search($resource, $statementsUri) === FALSE) { array_push($irsUri, $resource); } } // Fourth: Track the record description changes if ($this->ws->track_create === TRUE) { foreach ($irsUri as $uri) { // First check if the record is already existing for this record, within this dataset. $ws_cr = new CrudRead($uri, $this->ws->dataset, FALSE, TRUE, $this->ws->registered_ip, $this->ws->requester_ip); $ws_cr->ws_conneg("application/rdf+xml", "utf-8", "identity", "en"); $ws_cr->process(); $oldRecordDescription = $ws_cr->ws_serialize(); $ws_cr_error = $ws_cr->pipeline_getError(); if ($ws_cr->pipeline_getResponseHeaderStatus() == 400 && $ws_cr_error->id == "WS-CRUD-READ-300") { // The record is not existing within this dataset, so we simply move-on continue; } elseif ($ws_cr->pipeline_getResponseHeaderStatus() != 200) { // An error occured. Since we can't get the past state of a record, we have to send an error // for the CrudCreate call since we can't create a tracking record for this record. $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_305->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_305->name, $this->ws->errorMessenger->_305->description, "We can't create a track record for the following record: {$uri}", $this->ws->errorMessenger->_305->level); break; } $endpoint = ""; if ($this->ws->tracking_endpoint != "") { // We send the query to a remove tracking endpoint $endpoint = $this->ws->tracking_endpoint . "create/"; } else { // We send the query to a local tracking endpoint $endpoint = $this->ws->wsf_base_url . "/ws/tracker/create/"; } $wsq = new WebServiceQuerier($endpoint, "post", "text/xml", "from_dataset=" . urlencode($this->ws->dataset) . "&record=" . urlencode($uri) . "&action=create" . "&previous_state=" . urlencode($oldRecordDescription) . "&previous_state_mime=" . urlencode("application/rdf+xml") . "&performer=" . urlencode($this->ws->registered_ip) . "®istered_ip=self"); if ($wsq->getStatus() != 200) { $this->ws->conneg->setStatus($wsq->getStatus()); $this->ws->conneg->setStatusMsg($wsq->getStatusMessage()); /* $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, odbc_errormsg(), $this->ws->errorMessenger->_302->level); */ } unset($wsq); } } // If the query is still valid if ($this->ws->conneg->getStatus() == 200) { // Index all the instance records in the dataset if ($this->ws->mode == "full" || $this->ws->mode == "triplestore") { $irs = array(); foreach ($irsUri as $uri) { $irs[$uri] = $resourceIndex[$uri]; } $this->ws->db->query("DB.DBA.RDF_LOAD_RDFXML_MT('" . str_replace("'", "\\'", $rdfxmlSerializer->getSerializedIndex($irs)) . "', '" . $this->ws->dataset . "', '" . $this->ws->dataset . "')"); if (odbc_error()) { $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, odbc_errormsg(), $this->ws->errorMessenger->_302->level); return; } unset($irs); // Index all the reification statements into the statements graph $statements = array(); foreach ($statementsUri as $uri) { $statements[$uri] = $resourceIndex[$uri]; } $this->ws->db->query("DB.DBA.RDF_LOAD_RDFXML_MT('" . str_replace("'", "\\'", $rdfxmlSerializer->getSerializedIndex($statements)) . "', '" . $this->ws->dataset . "reification/', '" . $this->ws->dataset . "reification/')"); if (odbc_error()) { $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, odbc_errormsg(), $this->ws->errorMessenger->_302->level); return; } unset($statements); /* Link the dataset description of the file, by using the wsf:meta property, to its internal description (dataset graph description) */ if ($datasetUri != "") { $datasetRes[$datasetUri] = $resourceIndex[$datasetUri]; $datasetRes[$this->ws->dataset] = array("http://purl.org/ontology/wsf#meta" => array(array("value" => $datasetUri, "type" => "uri"))); $datasetDescription = $resourceIndex[$datasetRes]; /* Make the link between the dataset description and its "meta" description (all other information than its basic description) */ $this->ws->db->query("DB.DBA.RDF_LOAD_RDFXML_MT('" . str_replace("'", "\\'", $rdfxmlSerializer->getSerializedIndex($datasetRes)) . "', '" . $this->ws->wsf_graph . "datasets/', '" . $this->ws->wsf_graph . "datasets/')"); if (odbc_error()) { $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, "", $this->ws->errorMessenger->_302->level); return; } unset($datasetRes); } } // Index everything in Solr if ($this->ws->mode == "full" || $this->ws->mode == "searchindex") { $labelProperties = array(Namespaces::$iron . "prefLabel", Namespaces::$iron . "altLabel", Namespaces::$skos_2008 . "prefLabel", Namespaces::$skos_2008 . "altLabel", Namespaces::$skos_2004 . "prefLabel", Namespaces::$skos_2004 . "altLabel", Namespaces::$rdfs . "label", Namespaces::$dcterms . "title", Namespaces::$foaf . "name", Namespaces::$foaf . "givenName", Namespaces::$foaf . "family_name"); $descriptionProperties = array(Namespaces::$iron . "description", Namespaces::$dcterms . "description", Namespaces::$skos_2008 . "definition", Namespaces::$skos_2004 . "definition"); $filename = rtrim($this->ws->ontological_structure_folder, "/") . "/classHierarchySerialized.srz"; $file = fopen($filename, "r"); $classHierarchy = fread($file, filesize($filename)); $classHierarchy = unserialize($classHierarchy); fclose($file); if ($classHierarchy === FALSE) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setError($this->ws->errorMessenger->_306->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_306->name, $this->ws->errorMessenger->_306->description, "", $this->ws->errorMessenger->_306->level); return; } // Index in Solr $solr = new Solr($this->ws->wsf_solr_core, $this->ws->solr_host, $this->ws->solr_port, $this->ws->fields_index_folder); // Used to detect if we will be creating a new field. If we are, then we will // update the fields index once the new document will be indexed. $indexedFields = $solr->getFieldsIndex(); $newFields = FALSE; foreach ($irsUri as $subject) { // Skip Bnodes indexation in Solr // One of the prerequise is that each records indexed in Solr (and then available in Search and Browse) // should have a URI. Bnodes are simply skiped. if (stripos($subject, "_:arc") !== FALSE) { continue; } $add = "<add><doc><field name=\"uid\">" . md5($this->ws->dataset . $subject) . "</field>"; $add .= "<field name=\"uri\">" . $this->ws->xmlEncode($subject) . "</field>"; $add .= "<field name=\"dataset\">" . $this->ws->dataset . "</field>"; // Get types for this subject. $types = array(); foreach ($resourceIndex[$subject]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] as $value) { array_push($types, $value["value"]); $add .= "<field name=\"type\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"" . urlencode("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") . "_attr_facets\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } // Use the first defined type to add the the single-valued fiedl in the Solr schema. // This will be used to enabled sorting on (the first) type $add .= "<field name=\"type_single_valued\">" . $this->ws->xmlEncode($resourceIndex[$subject]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"][0]["value"]) . "</field>"; // get the preferred and alternative labels for this resource $prefLabelFound = array(); foreach ($this->ws->supportedLanguages as $lang) { $prefLabelFound[$lang] = FALSE; } foreach ($labelProperties as $property) { if (isset($resourceIndex[$subject][$property])) { foreach ($resourceIndex[$subject][$property] as $value) { $lang = ""; if (isset($value["lang"])) { if (array_search($value["lang"], $this->ws->supportedLanguages) !== FALSE) { // The language used for this string is supported by the system, so we index it in // the good place $lang = $value["lang"]; } else { // The language used for this string is not supported by the system, so we // index it in the default language $lang = $this->ws->supportedLanguages[0]; } } else { // The language is not defined for this string, so we simply consider that it uses // the default language supported by the structWSF instance $lang = $this->ws->supportedLanguages[0]; } if (!$prefLabelFound[$lang]) { $prefLabelFound[$lang] = TRUE; $add .= "<field name=\"prefLabel_" . $lang . "\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"prefLabelAutocompletion_" . $lang . "\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "prefLabel") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "prefLabel")) . "_attr_facets\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } else { $add .= "<field name=\"altLabel_" . $lang . "\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "altLabel") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "altLabel")) . "_attr_facets\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } } } } // If no labels are found for this resource, we use the ending of the URI as the label if (!$prefLabelFound) { $lang = $this->ws->supportedLanguages[0]; if (strrpos($subject, "#")) { $add .= "<field name=\"prefLabel_" . $lang . "\">" . substr($subject, strrpos($subject, "#") + 1) . "</field>"; $add .= "<field name=\"prefLabelAutocompletion_" . $lang . "\">" . substr($subject, strrpos($subject, "#") + 1) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "prefLabel") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "prefLabel")) . "_attr_facets\">" . $this->ws->xmlEncode(substr($subject, strrpos($subject, "#") + 1)) . "</field>"; } elseif (strrpos($subject, "/")) { $add .= "<field name=\"prefLabel_" . $lang . "\">" . substr($subject, strrpos($subject, "/") + 1) . "</field>"; $add .= "<field name=\"prefLabelAutocompletion_" . $lang . "\">" . substr($subject, strrpos($subject, "/") + 1) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "prefLabel") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "prefLabel")) . "_attr_facets\">" . $this->ws->xmlEncode(substr($subject, strrpos($subject, "/") + 1)) . "</field>"; } } // get the description of the resource foreach ($descriptionProperties as $property) { if (isset($resourceIndex[$subject][$property])) { $lang = ""; foreach ($resourceIndex[$subject][$property] as $value) { if (isset($value["lang"])) { if (array_search($value["lang"], $this->ws->supportedLanguages) !== FALSE) { // The language used for this string is supported by the system, so we index it in // the good place $lang = $value["lang"]; } else { // The language used for this string is not supported by the system, so we // index it in the default language $lang = $this->ws->supportedLanguages[0]; } } else { // The language is not defined for this string, so we simply consider that it uses // the default language supported by the structWSF instance $lang = $this->ws->supportedLanguages[0]; } $add .= "<field name=\"description_" . $lang . "\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "description") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "description")) . "_attr_facets\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } } } // Add the prefURL if available if (isset($resourceIndex[$subject][Namespaces::$iron . "prefURL"])) { $add .= "<field name=\"prefURL\">" . $this->ws->xmlEncode($resourceIndex[$subject][Namespaces::$iron . "prefURL"][0]["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$iron . "prefURL") . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$iron . "prefURL")) . "_attr_facets\">" . $this->ws->xmlEncode($resourceIndex[$subject][Namespaces::$iron . "prefURL"][0]["value"]) . "</field>"; } // If enabled, and supported by the structWSF setting, let's add any lat/long positionning to the index. if ($this->ws->geoEnabled) { // Check if there exists a lat-long coordinate for that resource. if (isset($resourceIndex[$subject][Namespaces::$geo . "lat"]) && isset($resourceIndex[$subject][Namespaces::$geo . "long"])) { $lat = str_replace(",", ".", $resourceIndex[$subject][Namespaces::$geo . "lat"][0]["value"]); $long = str_replace(",", ".", $resourceIndex[$subject][Namespaces::$geo . "long"][0]["value"]); // Add Lat/Long $add .= "<field name=\"lat\">" . $this->ws->xmlEncode($lat) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "lat") . "</field>"; $add .= "<field name=\"long\">" . $this->ws->xmlEncode($long) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "long") . "</field>"; // Add hashcode $add .= "<field name=\"geohash\">" . "{$lat},{$long}" . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$sco . "geohash") . "</field>"; // Add cartesian tiers // Note: Cartesian tiers are not currently supported. The Lucene Java API // for this should be ported to PHP to enable this feature. } $coordinates = array(); // Check if there is a polygonCoordinates property if (isset($resourceIndex[$subject][Namespaces::$sco . "polygonCoordinates"])) { foreach ($resourceIndex[$subject][Namespaces::$sco . "polygonCoordinates"] as $polygonCoordinates) { $coordinates = explode(" ", $polygonCoordinates["value"]); $add .= "<field name=\"polygonCoordinates\">" . $this->ws->xmlEncode($polygonCoordinates["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$sco . "polygonCoordinates") . "</field>"; } } // Check if there is a polylineCoordinates property if (isset($resourceIndex[$subject][Namespaces::$sco . "polylineCoordinates"])) { foreach ($resourceIndex[$subject][Namespaces::$sco . "polylineCoordinates"] as $polylineCoordinates) { $coordinates = array_merge($coordinates, explode(" ", $polylineCoordinates["value"])); $add .= "<field name=\"polylineCoordinates\">" . $this->ws->xmlEncode($polylineCoordinates["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$sco . "polylineCoordinates") . "</field>"; } } if (count($coordinates) > 0) { $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "lat") . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "long") . "</field>"; foreach ($coordinates as $key => $coordinate) { $points = explode(",", $coordinate); if ($points[0] != "" && $points[1] != "") { // Add Lat/Long $add .= "<field name=\"lat\">" . $this->ws->xmlEncode($points[1]) . "</field>"; $add .= "<field name=\"long\">" . $this->ws->xmlEncode($points[0]) . "</field>"; // Add altitude if (isset($points[2]) && $points[2] != "") { $add .= "<field name=\"alt\">" . $this->ws->xmlEncode($points[2]) . "</field>"; if ($key == 0) { $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "alt") . "</field>"; } } // Add hashcode $add .= "<field name=\"geohash\">" . $points[1] . "," . $points[0] . "</field>"; if ($key == 0) { $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$sco . "geohash") . "</field>"; } // Add cartesian tiers // Note: Cartesian tiers are not currently supported. The Lucene Java API // for this should be ported to PHP to enable this feature. } } } // Check if there is any geonames:locatedIn assertion for that resource. if (isset($resourceIndex[$subject][Namespaces::$geoname . "locatedIn"])) { $add .= "<field name=\"located_in\">" . $this->ws->xmlEncode($resourceIndex[$subject][Namespaces::$geoname . "locatedIn"][0]["value"]) . "</field>"; $add .= "<field name=\"" . urlencode($this->ws->xmlEncode(Namespaces::$geoname . "locatedIn")) . "_attr_facets\">" . $this->ws->xmlEncode($resourceIndex[$subject][Namespaces::$geoname . "locatedIn"][0]["value"]) . "</field>"; } // Check if there is any wgs84_pos:alt assertion for that resource. if (isset($resourceIndex[$subject][Namespaces::$geo . "alt"])) { $add .= "<field name=\"alt\">" . $this->ws->xmlEncode($resourceIndex[$subject][Namespaces::$geo . "alt"][0]["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode(Namespaces::$geo . "alt") . "</field>"; } } $filename = rtrim($this->ws->ontological_structure_folder, "/") . "/propertyHierarchySerialized.srz"; $file = fopen($filename, "r"); $propertyHierarchy = fread($file, filesize($filename)); $propertyHierarchy = unserialize($propertyHierarchy); fclose($file); if ($propertyHierarchy === FALSE) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setError($this->ws->errorMessenger->_310->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_310->name, $this->ws->errorMessenger->_310->description, "", $this->ws->errorMessenger->_310->level); return; } // When a property appears in this array, it means that it is already // used in the Solr document we are creating $usedSingleValuedProperties = array(); // Get properties with the type of the object foreach ($resourceIndex[$subject] as $predicate => $values) { if (array_search($predicate, $labelProperties) === FALSE && array_search($predicate, $descriptionProperties) === FALSE && $predicate != Namespaces::$iron . "prefURL" && $predicate != Namespaces::$geo . "long" && $predicate != Namespaces::$geo . "lat" && $predicate != Namespaces::$geo . "alt" && $predicate != Namespaces::$sco . "polygonCoordinates" && $predicate != Namespaces::$sco . "polylineCoordinates") { foreach ($values as $value) { if ($value["type"] == "literal") { $lang = ""; if (isset($value["lang"])) { if (array_search($value["lang"], $this->ws->supportedLanguages) !== FALSE) { // The language used for this string is supported by the system, so we index it in // the good place $lang = $value["lang"]; } else { // The language used for this string is not supported by the system, so we // index it in the default language $lang = $this->ws->supportedLanguages[0]; } } else { // The language is not defined for this string, so we simply consider that it uses // the default language supported by the structWSF instance $lang = $this->ws->supportedLanguages[0]; } // Detect if the field currently exists in the fields index if (!$newFields && array_search(urlencode($predicate) . "_attr_" . $lang, $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_date", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_int", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_float", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_" . $lang . "_single_valued", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_date_single_valued", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_int_single_valued", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_float_single_valued", $indexedFields) === FALSE) { $newFields = TRUE; } // Check the datatype of the datatype property $property = $propertyHierarchy->getProperty($predicate); if (is_array($property->range) && array_search("http://www.w3.org/2001/XMLSchema#dateTime", $property->range) !== FALSE && $this->safeDate($value["value"]) != "") { // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_date_single_valued\">" . $this->ws->xmlEncode($this->safeDate($value["value"])) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_date\">" . $this->ws->xmlEncode($this->safeDate($value["value"])) . "</field>"; } } elseif (is_array($property->range) && array_search("http://www.w3.org/2001/XMLSchema#int", $property->range) !== FALSE || is_array($property->range) && array_search("http://www.w3.org/2001/XMLSchema#integer", $property->range) !== FALSE) { // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_int_single_valued\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_int\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } } elseif (is_array($property->range) && array_search("http://www.w3.org/2001/XMLSchema#float", $property->range) !== FALSE) { // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_float_single_valued\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_float\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } } else { // By default, the datatype used is a literal/string // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_" . $lang . "_single_valued\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_" . $lang . "\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; } } $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode($predicate) . "</field>"; $add .= "<field name=\"" . urlencode($predicate) . "_attr_facets\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; /* Check if there is a reification statement for that triple. If there is one, we index it in the index as: <property> <text> Note: Eventually we could want to update the Solr index to include a new "reifiedText" field. */ foreach ($statementsUri as $statementUri) { if ($resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#subject"][0]["value"] == $subject && $resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate"][0]["value"] == $predicate && $resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#object"][0]["value"] == $value["value"]) { foreach ($resourceIndex[$statementUri] as $reiPredicate => $reiValues) { if ($reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#subject" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#object") { foreach ($reiValues as $reiValue) { $reiLang = ""; if (isset($reiValue["lang"])) { if (array_search($reiValue["lang"], $this->ws->supportedLanguages) !== FALSE) { // The language used for this string is supported by the system, so we index it in // the good place $reiLang = $reiValue["lang"]; } else { // The language used for this string is not supported by the system, so we // index it in the default language $reiLang = $this->ws->supportedLanguages[0]; } } else { // The language is not defined for this string, so we simply consider that it uses // the default language supported by the structWSF instance $reiLang = $this->ws->supportedLanguages[0]; } if ($reiValue["type"] == "literal") { // Attribute used to reify information to a statement. $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_attr\">" . $this->ws->xmlEncode($predicate) . "</field>"; $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_obj\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_value_" . $reiLang . "\">" . $this->ws->xmlEncode($reiValue["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode($reiPredicate) . "</field>"; } } } } } } } elseif ($value["type"] == "uri") { // Set default language $lang = $this->ws->supportedLanguages[0]; // Detect if the field currently exists in the fields index if (!$newFields && array_search(urlencode($predicate) . "_attr_obj_uri", $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_obj_" . $lang, $indexedFields) === FALSE && array_search(urlencode($predicate) . "_attr_obj_" . $lang . "_single_valued", $indexedFields) === FALSE) { $newFields = TRUE; } // If it is an object property, we want to bind labels of the resource referenced by that // object property to the current resource. That way, if we have "paul" -- know --> "bob", and the // user send a seach query for "bob", then "paul" will be returned as well. $query = $this->ws->db->build_sparql_query("select ?p ?o where {<" . $value["value"] . "> ?p ?o.}", array('p', 'o'), FALSE); $resultset3 = $this->ws->db->query($query); $subjectTriples = array(); while (odbc_fetch_row($resultset3)) { $p = odbc_result($resultset3, 1); $o = $this->ws->db->odbc_getPossibleLongResult($resultset3, 2); if (!isset($subjectTriples[$p])) { $subjectTriples[$p] = array(); } array_push($subjectTriples[$p], $o); } unset($resultset3); // We allign all label properties values in a single string so that we can search over all of them. $labels = ""; foreach ($labelProperties as $property) { if (isset($subjectTriples[$property])) { $labels .= $subjectTriples[$property][0] . " "; } } $property = $propertyHierarchy->getProperty($predicate); if ($labels != "") { $labels = trim($labels); // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_" . $lang . "_single_valued\">" . $this->ws->xmlEncode($labels) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_" . $lang . "\">" . $this->ws->xmlEncode($labels) . "</field>"; } $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_uri\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode($predicate) . "</field>"; $add .= "<field name=\"" . urlencode($predicate) . "_attr_facets\">" . $this->ws->xmlEncode($labels) . "</field>"; $add .= "<field name=\"" . urlencode($predicate) . "_attr_uri_label_facets\">" . $this->ws->xmlEncode($value["value"]) . '::' . $this->ws->xmlEncode($labels) . "</field>"; } else { // If no label is found, we may want to manipulate the ending of the URI to create // a "temporary" pref label for that object, and then to index it as a search string. $pos = strripos($value["value"], "#"); if ($pos !== FALSE) { $temporaryLabel = substr($value["value"], $pos + 1); } else { $pos = strripos($value["value"], "/"); if ($pos !== FALSE) { $temporaryLabel = substr($value["value"], $pos + 1); } } // Check if the property is defined as a cardinality of maximum 1 // If it doesn't we consider it a multi-valued field, otherwise // we use the single-valued version of the field. if ($property->cardinality == 1 || $property->maxCardinality == 1) { if (array_search($predicate, $usedSingleValuedProperties) === FALSE) { $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_" . $lang . "_single_valued\">" . $this->ws->xmlEncode($temporaryLabel) . "</field>"; $usedSingleValuedProperties[] = $predicate; } } else { $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_" . $lang . "\">" . $this->ws->xmlEncode($temporaryLabel) . "</field>"; } $add .= "<field name=\"" . urlencode($predicate) . "_attr_obj_uri\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode($predicate) . "</field>"; $add .= "<field name=\"" . urlencode($predicate) . "_attr_facets\">" . $this->ws->xmlEncode($temporaryLabel) . "</field>"; $add .= "<field name=\"" . urlencode($predicate) . "_attr_uri_label_facets\">" . $this->ws->xmlEncode($value["value"]) . '::' . $this->ws->xmlEncode($temporaryLabel) . "</field>"; } /* Check if there is a reification statement for that triple. If there is one, we index it in the index as: <property> <text> Note: Eventually we could want to update the Solr index to include a new "reifiedText" field. */ $statementAdded = FALSE; foreach ($statementsUri as $statementUri) { if ($resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#subject"][0]["value"] == $subject && $resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate"][0]["value"] == $predicate && $resourceIndex[$statementUri]["http://www.w3.org/1999/02/22-rdf-syntax-ns#object"][0]["value"] == $value["value"]) { foreach ($resourceIndex[$statementUri] as $reiPredicate => $reiValues) { if ($reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#subject" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#predicate" && $reiPredicate != "http://www.w3.org/1999/02/22-rdf-syntax-ns#object") { foreach ($reiValues as $reiValue) { if ($reiValue["type"] == "literal") { $reiLang = ""; if (isset($reiValue["lang"])) { if (array_search($reiValue["lang"], $this->ws->supportedLanguages) !== FALSE) { // The language used for this string is supported by the system, so we index it in // the good place $reiLang = $reiValue["lang"]; } else { // The language used for this string is not supported by the system, so we // index it in the default language $reiLang = $this->ws->supportedLanguages[0]; } } else { // The language is not defined for this string, so we simply consider that it uses // the default language supported by the structWSF instance $reiLang = $this->ws->supportedLanguages[0]; } // Attribute used to reify information to a statement. $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_attr\">" . $this->ws->xmlEncode($predicate) . "</field>"; $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_obj\">" . $this->ws->xmlEncode($value["value"]) . "</field>"; $add .= "<field name=\"" . urlencode($reiPredicate) . "_reify_value_" . $reiLang . "\">" . $this->ws->xmlEncode($reiValue["value"]) . "</field>"; $add .= "<field name=\"attribute\">" . $this->ws->xmlEncode($reiPredicate) . "</field>"; $statementAdded = TRUE; break; } } } if ($statementAdded) { break; } } } } } } } } // Get all types by inference $inferredTypes = array(); foreach ($types as $type) { $superClasses = $classHierarchy->getSuperClasses($type); // Add the type to make the closure of the set of inferred types array_push($inferredTypes, $type); foreach ($superClasses as $sc) { if (array_search($sc->name, $inferredTypes) === FALSE) { array_push($inferredTypes, $sc->name); } } } foreach ($inferredTypes as $sc) { $add .= "<field name=\"inferred_type\">" . $this->ws->xmlEncode($sc) . "</field>"; } $add .= "</doc></add>"; if (!$solr->update($add)) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setError($this->ws->errorMessenger->_303->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_303->name, $this->ws->errorMessenger->_303->description, $solr->errorMessage . '[Debugging information: ]' . $solr->errorMessageDebug, $this->ws->errorMessenger->_303->level); return; } } if ($this->ws->solr_auto_commit === FALSE) { if (!$solr->commit()) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setError($this->ws->errorMessenger->_304->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_304->name, $this->ws->errorMessenger->_304->description, $solr->errorMessage . '[Debugging information: ]' . $solr->errorMessageDebug, $this->ws->errorMessenger->_304->level); return; } } // Update the fields index if a new field as been detected. if ($newFields) { $solr->updateFieldsIndex(); } } /* // Optimisation can be time consuming "on-the-fly" (which decrease user's experience) if(!$solr->optimize()) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setStatusMsgExt("Error #crud-create-106"); return; } */ } } } }
public function processInterface() { // Make sure there was no conneg error prior to this process call if ($this->ws->conneg->getStatus() == 200) { $this->ws->validateQuery(); // If the query is still valid if ($this->ws->conneg->getStatus() == 200) { // Track the record description changes if ($this->ws->track_delete === TRUE) { // First check if the record is already existing for this record, within this dataset. $ws_cr = new CrudRead($this->ws->resourceUri, $this->ws->dataset, FALSE, TRUE, $this->ws->registered_ip, $this->ws->requester_ip); $ws_cr->ws_conneg("application/rdf+xml", "utf-8", "identity", "en"); $ws_cr->process(); $oldRecordDescription = $ws_cr->ws_serialize(); $ws_cr_error = $ws_cr->pipeline_getError(); if ($ws_cr->pipeline_getResponseHeaderStatus() != 200) { // An error occured. Since we can't get the past state of a record, we have to send an error // for the CrudUpdate call since we can't create a tracking record for this record. $this->ws->conneg->setStatus(400); $this->ws->conneg->setStatusMsg("Bad Request"); $this->ws->conneg->setError($this->ws->errorMessenger->_303->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_303->name, $this->ws->errorMessenger->_303->description, "We can't create a track record for the following record: " . $this->ws->resourceUri, $this->ws->errorMessenger->_303->level); break; } $endpoint = ""; if ($this->ws->tracking_endpoint != "") { // We send the query to a remove tracking endpoint $endpoint = $this->ws->tracking_endpoint . "create/"; } else { // We send the query to a local tracking endpoint $endpoint = $this->ws->wsf_base_url . "/ws/tracker/create/"; } $wsq = new WebServiceQuerier($endpoint, "post", "text/xml", "from_dataset=" . urlencode($this->ws->dataset) . "&record=" . urlencode($this->ws->resourceUri) . "&action=delete" . "&previous_state=" . urlencode($oldRecordDescription) . "&previous_state_mime=" . urlencode("application/rdf+xml") . "&performer=" . urlencode($this->ws->registered_ip) . "®istered_ip=self"); if ($wsq->getStatus() != 200) { $this->ws->conneg->setStatus($wsq->getStatus()); $this->ws->conneg->setStatusMsg($wsq->getStatusMessage()); /* $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, odbc_errormsg(), $this->ws->errorMessenger->_302->level); */ } unset($wsq); } // Delete all triples for this URI in that dataset $query = "delete from <" . $this->ws->dataset . ">\n { \n <" . $this->ws->resourceUri . "> ?p ?o. \n }\n where\n {\n <" . $this->ws->resourceUri . "> ?p ?o. \n }"; @$this->ws->db->query($this->ws->db->build_sparql_query(str_replace(array("\n", "\r", "\t"), " ", $query), array(), FALSE)); if (odbc_error()) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setStatusMsgExt($this->ws->errorMessenger->_300->name); $this->ws->conneg->setError($this->ws->errorMessenger->_300->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_300->name, $this->ws->errorMessenger->_300->description, odbc_errormsg(), $this->ws->errorMessenger->_300->level); return; } // Delete the Solr document in the Solr index $solr = new Solr($this->ws->wsf_solr_core, $this->ws->solr_host, $this->ws->solr_port, $this->ws->fields_index_folder); if (!$solr->deleteInstanceRecord($this->ws->resourceUri, $this->ws->dataset)) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setStatusMsgExt($this->ws->errorMessenger->_301->name); $this->ws->conneg->setError($this->ws->errorMessenger->_301->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_301->name, $this->ws->errorMessenger->_301->description, $solr->errorMessage . '[Debugging information: ]' . $solr->errorMessageDebug, $this->ws->errorMessenger->_301->level); return; } if ($this->ws->solr_auto_commit === FALSE) { if (!$solr->commit()) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setStatusMsgExt($this->ws->errorMessenger->_302->name); $this->ws->conneg->setError($this->ws->errorMessenger->_302->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_302->name, $this->ws->errorMessenger->_302->description, $solr->errorMessage . '[Debugging information: ]' . $solr->errorMessageDebug, $this->ws->errorMessenger->_302->level); return; } } } } }
/** * Send the HTTP query to the endpoint. This function should be called * once all the settings/parameters of the query have been previously * configured. * * @param $query_extension - an optional QueryExtension * object * * @author Frederick Giasson, Structured Dynamics LLC. */ public function send($query_extension = NULL) { $parameters = ""; if ($query_extension !== NULL) { $query_extension->alterParams($this, $this->params); } foreach ($this->params as $param => $value) { $parameters .= $param . "=" . $value . "&"; } $parameters = trim($parameters, "&"); $wsq = new WebServiceQuerier(rtrim($this->network, "/") . "/" . $this->endpoint, $this->method, $this->mime == "resultset" ? "text/xml" : $this->mime, $parameters, $this->timeout, $query_extension); $this->httpStatus = $wsq->getStatus(); $this->httpStatusMessage = $wsq->getStatusMessage(); $this->httpStatusMessageDescription = $wsq->getStatusMessageDescription(); $this->error = $wsq->error; if ($wsq->getStatus() == 200) { if ($this->mime != "resultset") { $this->resultset = $wsq->getResultset(); } else { $data = $wsq->getResultset(); if ($data != "") { $resultset = new Resultset(); $resultset->importStructXMLResultset($data); $this->resultset = $resultset; } } } unset($wsq); return $this; }
/** Update all ontological structures used by the WSF @author Frederick Giasson, Structured Dynamics LLC. */ public function createOntology() { // Make sure there was no conneg error prior to this process call if ($this->ws->conneg->getStatus() == 200) { $this->ws->validateQuery(); // If the query is still valid if ($this->ws->conneg->getStatus() == 200) { // Starts the OWLAPI process/bridge require_once $this->ws->owlapiBridgeURI; // Create the OWLAPI session object that could have been persisted on the OWLAPI instance. // Second param "false" => we re-use the pre-created session without destroying the previous one // third param "0" => it nevers timeout. $OwlApiSession = java_session("OWLAPI", false, 0); $register = java_values($OwlApiSession->get("ontologiesRegister")); // Check if the ontology is already existing if (!is_null(java_values($OwlApiSession->get($this->getOntologySessionID($this->ws->ontologyUri)))) || $register != NULL && array_search($this->getOntologySessionID($this->ws->ontologyUri), $register) !== FALSE) { $this->ws->returnError(400, "Bad Request", "_302", ""); return; } try { $ontology = new OWLOntology($this->ws->ontologyUri, $OwlApiSession, FALSE); if (strtolower($this->ws->owlapiReasoner) == "pellet") { $ontology->usePelletReasoner(); } elseif (strtolower($this->ws->owlapiReasoner) == "hermit") { $ontology->useHermitReasoner(); } elseif (strtolower($this->ws->owlapiReasoner) == "factpp") { $ontology->useFactppReasoner(); } } catch (Exception $e) { $this->ws->returnError(400, "Bad Request", "_300", (string) java_values($e)); return; } // Get the description of the ontology $ontologyDescription = $ontology->getOntologyDescription(); $ontologyName = $this->getLabel($this->ws->ontologyUri, $ontologyDescription); $ontologyDescription = $this->getDescription($ontologyDescription); // Get the list of webservices that will be accessible for this ontology dataset. $authLister = new AuthLister("ws", $this->ws->ontologyUri, $this->ws->requester_ip, $this->ws->wsf_local_ip); $authLister->pipeline_conneg($this->ws->conneg->getAccept(), $this->ws->conneg->getAcceptCharset(), $this->ws->conneg->getAcceptEncoding(), $this->ws->conneg->getAcceptLanguage()); $authLister->process(); if ($authLister->pipeline_getResponseHeaderStatus() != 200) { $this->ws->conneg->setStatus($authLister->pipeline_getResponseHeaderStatus()); $this->ws->conneg->setStatusMsg($authLister->pipeline_getResponseHeaderStatusMsg()); $this->ws->conneg->setStatusMsgExt($authLister->pipeline_getResponseHeaderStatusMsgExt()); $this->ws->conneg->setError($authLister->pipeline_getError()->id, $authLister->pipeline_getError()->webservice, $authLister->pipeline_getError()->name, $authLister->pipeline_getError()->description, $authLister->pipeline_getError()->debugInfo, $authLister->pipeline_getError()->level); return; } /* Get all web services */ $webservices = ""; $xml = new ProcessorXML(); $xml->loadXML($authLister->pipeline_getResultset()); $webServiceElements = $xml->getXPath('//predicate/object[attribute::type="wsf:WebService"]'); foreach ($webServiceElements as $element) { if (stristr($xml->getURI($element), "/wsf/ws/search/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/browse/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/sparql/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/crud/create/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/crud/update/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/crud/delete/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/crud/read/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/ontology/create/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/ontology/read/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/ontology/update/") !== FALSE || stristr($xml->getURI($element), "/wsf/ws/ontology/delete/") !== FALSE) { $webservices .= $xml->getURI($element) . ";"; } } $webservices = rtrim($webservices, ";"); unset($xml); unset($authLister); // Create a new dataset for this ontology $globalPermissions = ""; if ($this->ws->globalPermissionCreate === FALSE) { $globalPermissions .= "False;"; } else { $globalPermissions .= "True;"; } if ($this->ws->globalPermissionRead === FALSE) { $globalPermissions .= "False;"; } else { $globalPermissions .= "True;"; } if ($this->ws->globalPermissionUpdate === FALSE) { $globalPermissions .= "False;"; } else { $globalPermissions .= "True;"; } if ($this->ws->globalPermissionDelete === FALSE) { $globalPermissions .= "False"; } else { $globalPermissions .= "True"; } $datasetCreate = new DatasetCreate($this->ws->ontologyUri, $ontologyName, $ontologyDescription, "", $this->ws->registered_ip, $this->ws->requester_ip, $webservices, $globalPermissions); $datasetCreate->ws_conneg($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); $datasetCreate->process(); if ($datasetCreate->pipeline_getResponseHeaderStatus() != 200) { if ($datasetCreate->pipeline_getError()->id != "WS-DATASET-CREATE-202") { $this->ws->conneg->setStatus($datasetCreate->pipeline_getResponseHeaderStatus()); $this->ws->conneg->setStatusMsg($datasetCreate->pipeline_getResponseHeaderStatusMsg()); $this->ws->conneg->setStatusMsgExt($datasetCreate->pipeline_getResponseHeaderStatusMsgExt()); $this->ws->conneg->setError($datasetCreate->pipeline_getError()->id, $datasetCreate->pipeline_getError()->webservice, $datasetCreate->pipeline_getError()->name, $datasetCreate->pipeline_getError()->description, $datasetCreate->pipeline_getError()->debugInfo, $datasetCreate->pipeline_getError()->level); } // If the dataset already exists, then we simply stop the processing of the advancedIndexation // mode. This means that the tomcat instance has been rebooted, and that the datasets // have been leaved there, and that a procedure, normally using the advancedIndexation mode // is currently being re-processed. return; } unset($datasetCreate); // Tag the new dataset as being a dataset that host an ontology description $query = "insert into <" . $this->ws->wsf_graph . "datasets/>\n {\n <" . $this->ws->ontologyUri . "> <http://purl.org/ontology/wsf#holdOntology> \"true\" .\n }"; @$this->ws->db->query($this->ws->db->build_sparql_query(str_replace(array("\n", "\r", "\t"), " ", $query), array(), FALSE)); if (odbc_error()) { $this->ws->conneg->setStatus(500); $this->ws->conneg->setStatusMsg("Internal Error"); $this->ws->conneg->setStatusMsgExt($this->ws->errorMessenger->_301->name); $this->ws->conneg->setError($this->ws->errorMessenger->_301->id, $this->ws->errorMessenger->ws, $this->ws->errorMessenger->_301->name, $this->ws->errorMessenger->_301->description, odbc_errormsg(), $this->ws->errorMessenger->_301->level); return; } // Check if we want to enable the advanced indexation: so, if we want to import all the ontologies // description into the other structWSF data stores to enable search and filtering using the other // endpoints such as search, sparql, read, etc. if ($this->ws->advancedIndexation) { // Once we start the ontology creation process, we have to make sure that even if the server // loose the connection with the user the process will still finish. ignore_user_abort(true); // However, maybe there is an issue with the server handling that file tht lead to some kind of infinite // or near infinite loop; so we have to limit the execution time of this procedure to 45 mins. set_time_limit(86400); // Get the description of the classes, properties and named individuals of this ontology. // Check the size of the Ontology file to import. If the size is bigger than 8MB, then we will // use another method that incurs some Virtuoso indexing. If it is the case, you have to make sure // that Virtuoso is properly configured so that it can access (DirsAllowed Virtuoso config option) // the folder where the ontology file has been saved. if (filesize($this->ws->ontologyUri) > 8000000) { $sliceSize = 100; // Import the big file into Virtuoso $sqlQuery = "DB.DBA.RDF_LOAD_RDFXML_MT(file_to_string_output('" . str_replace("file://localhost", "", $this->ws->ontologyUri) . "'),'" . $this->ws->ontologyUri . "/import','" . $this->ws->ontologyUri . "/import')"; $resultset = $this->ws->db->query($sqlQuery); if (odbc_error()) { // If there is an error, try to load it using the Turtle parser $sqlQuery = "DB.DBA.TTLP_MT(file_to_string_output('" . str_replace("file://localhost", "", $this->ws->ontologyUri) . "'),'" . $this->ws->ontologyUri . "/import','" . $this->ws->ontologyUri . "/import')"; $resultset = $this->ws->db->query($sqlQuery); if (odbc_error()) { // echo "Error: can't import the file: $file, into the triple store.\n"; // return; } } unset($resultset); // count the number of records $sparqlQuery = "\n \n select count(distinct ?s) as ?nb from <" . $this->ws->ontologyUri . "/import>\n where\n {\n ?s a ?o .\n }\n \n "; $resultset = $this->ws->db->query($this->ws->db->build_sparql_query($sparqlQuery, array('nb'), FALSE)); $nb = odbc_result($resultset, 1); unset($resultset); $nbRecordsDone = 0; while ($nbRecordsDone < $nb && $nb > 0) { // Create slices of 100 records. $sparqlQuery = "\n \n select ?s ?p ?o (DATATYPE(?o)) as ?otype (LANG(?o)) as ?olang\n where \n {\n {\n select distinct ?s from <" . $this->ws->ontologyUri . "/import> \n where \n {\n ?s a ?type.\n } \n limit " . $sliceSize . " \n offset " . $nbRecordsDone . "\n } \n \n ?s ?p ?o\n }\n \n "; $resultset = $this->ws->db->query($this->ws->db->build_sparql_query($sparqlQuery, array('s', 'p', 'o', 'otype', 'olang'), FALSE)); if (odbc_error()) { // echo "Error: can't get records slices.\n"; // return; } $crudCreates = ""; $crudUpdates = ""; $crudDeletes = array(); $rdfDocumentN3 = ""; $currentSubject = ""; $subjectDescription = "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n"; while (odbc_fetch_row($resultset)) { $s = odbc_result($resultset, 1); $p = odbc_result($resultset, 2); $o = $this->ws->db->odbc_getPossibleLongResult($resultset, 3); $otype = odbc_result($resultset, 4); $olang = odbc_result($resultset, 5); if ($otype != "" || $olang != "") { $subjectDescription .= "<{$s}> <{$p}> \"\"\"" . $this->n3Encode($o) . "\"\"\" .\n"; } else { $subjectDescription .= "<{$s}> <{$p}> <{$o}> .\n"; } } unset($resultset); $wsq = new WebServiceQuerier(rtrim($this->ws->wsf_base_url, "/") . "/ws/crud/create/", "post", "application/rdf+xml", "document=" . urlencode($subjectDescription) . "&dataset=" . urlencode($this->ws->ontologyUri) . "&mime=" . urlencode("application/rdf+n3") . "&mode=full" . "®istered_ip=" . urlencode($this->ws->registered_ip)); if ($wsq->getStatus() != 200) { $this->ws->conneg->setStatus($wsq->getStatus()); $this->ws->conneg->setStatusMsg($wsq->getStatusMessage()); $this->ws->conneg->setStatusMsgExt($wsq->getStatusMessageDescription()); /* $this->ws->conneg->setError($wsq->pipeline_getError()->id, $crudCreate->pipeline_getError()->webservice, $crudCreate->pipeline_getError()->name, $crudCreate->pipeline_getError()->description, $crudCreate->pipeline_getError()->debugInfo, $crudCreate->pipeline_getError()->level); */ // In case of error, we delete the dataset we previously created. $ontologyDelete = new OntologyDelete($this->ws->ontologyUri, $this->ws->registered_ip, $this->ws->requester_ip); $ontologyDelete->ws_conneg($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); $ontologyDelete->deleteOntology(); if ($ontologyDelete->pipeline_getResponseHeaderStatus() != 200) { $this->ws->conneg->setStatus($ontologyDelete->pipeline_getResponseHeaderStatus()); $this->ws->conneg->setStatusMsg($ontologyDelete->pipeline_getResponseHeaderStatusMsg()); $this->ws->conneg->setStatusMsgExt($ontologyDelete->pipeline_getResponseHeaderStatusMsgExt()); $this->ws->conneg->setError($ontologyDelete->pipeline_getError()->id, $ontologyDelete->pipeline_getError()->webservice, $ontologyDelete->pipeline_getError()->name, $ontologyDelete->pipeline_getError()->description, $ontologyDelete->pipeline_getError()->debugInfo, $ontologyDelete->pipeline_getError()->level); //return; } //return; } $nbRecordsDone += $sliceSize; } // Now delete the graph we used to import the file $sqlQuery = "sparql clear graph <" . $this->ws->ontologyUri . "/import>"; $resultset = $this->ws->db->query($sqlQuery); if (odbc_error()) { // echo "Error: can't delete the graph sued for importing the file\n"; // return; } unset($resultset); } else { $nbClasses = $ontology->getNbClasses(); $sliceSize = 200; // Note: in OntologyCreate, we have to merge all the classes, properties and named individuals // together. This is needed to properly handle possible punning used in imported ontologies. // If we don't do this, and that a resource is both a class and an individual, then only // the individual will be in the Solr index because it would overwrite the Class // record document with the same URI. include_once "../../framework/arc2/ARC2.php"; $rdfxmlParser = ARC2::getRDFParser(); $rdfxmlSerializer = ARC2::getRDFXMLSerializer(); $resourcesIndex = $rdfxmlParser->getSimpleIndex(0); for ($i = 0; $i < $nbClasses; $i += $sliceSize) { $ontologyRead = new OntologyRead($this->ws->ontologyUri, "getClasses", "mode=descriptions;limit={$sliceSize};offset={$i}", $this->ws->registered_ip, $this->ws->requester_ip); // Since we are in pipeline mode, we have to set the owlapisession using the current one. // otherwise the java bridge will return an error $ontologyRead->setOwlApiSession($OwlApiSession); $ontologyRead->ws_conneg("application/rdf+xml", $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); if ($this->ws->reasoner) { $ontologyRead->useReasoner(); } else { $ontologyRead->stopUsingReasoner(); } $ontologyRead->process(); $classesRDF = $ontologyRead->ws_serialize(); $rdfxmlParser->parse($this->ws->ontologyUri, $classesRDF); $resourceIndex = $rdfxmlParser->getSimpleIndex(0); $resourcesIndex = ARC2::getMergedIndex($resourcesIndex, $resourceIndex); unset($ontologyRead); } $nbProperties = 0; $nbProperties += $ontology->getNbObjectProperties(); $nbProperties += $ontology->getNbDataProperties(); $nbProperties += $ontology->getNbAnnotationProperties(); $sliceSize = 200; for ($i = 0; $i < $nbProperties; $i += $sliceSize) { $ontologyRead = new OntologyRead($this->ws->ontologyUri, "getProperties", "mode=descriptions;limit={$sliceSize};offset={$i};type=all", $this->ws->registered_ip, $this->ws->requester_ip); // Since we are in pipeline mode, we have to set the owlapisession using the current one. // otherwise the java bridge will return an error $ontologyRead->setOwlApiSession($OwlApiSession); $ontologyRead->ws_conneg("application/rdf+xml", $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); if ($this->ws->reasoner) { $ontologyRead->useReasoner(); } else { $ontologyRead->stopUsingReasoner(); } $ontologyRead->process(); $propertiesRDF = $ontologyRead->ws_serialize(); $rdfxmlParser->parse($this->ws->ontologyUri, $propertiesRDF); $resourceIndex = $rdfxmlParser->getSimpleIndex(0); $resourcesIndex = ARC2::getMergedIndex($resourcesIndex, $resourceIndex); unset($ontologyRead); } $nbNamedIndividuals = $ontology->getNbNamedIndividuals(); $sliceSize = 200; for ($i = 0; $i < $nbNamedIndividuals; $i += $sliceSize) { $ontologyRead = new OntologyRead($this->ws->ontologyUri, "getNamedIndividuals", "classuri=all;mode=descriptions;limit={$sliceSize};offset={$i}", $this->ws->registered_ip, $this->ws->requester_ip); // Since we are in pipeline mode, we have to set the owlapisession using the current one. // otherwise the java bridge will return an error $ontologyRead->setOwlApiSession($OwlApiSession); $ontologyRead->ws_conneg("application/rdf+xml", $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); if ($this->ws->reasoner) { $ontologyRead->useReasoner(); } else { $ontologyRead->stopUsingReasoner(); } $ontologyRead->process(); $namedIndividualsRDF = $ontologyRead->ws_serialize(); $rdfxmlParser->parse($this->ws->ontologyUri, $namedIndividualsRDF); $resourceIndex = $rdfxmlParser->getSimpleIndex(0); $resourcesIndex = ARC2::getMergedIndex($resourcesIndex, $resourceIndex); unset($ontologyRead); } // Now, let's index the resources of this ontology within structWSF (for the usage of browse, search // and sparql) // Split the aggregated resources in multiple slices $nbResources = count($resourcesIndex); $sliceSize = 200; for ($i = 0; $i < $nbResources; $i += $sliceSize) { $slicedResourcesIndex = array_slice($resourcesIndex, $i, $sliceSize); $resourcesRDF = $rdfxmlSerializer->getSerializedIndex($slicedResourcesIndex); $crudCreate = new CrudCreate($resourcesRDF, "application/rdf+xml", "full", $this->ws->ontologyUri, $this->ws->registered_ip, $this->ws->requester_ip); $crudCreate->ws_conneg($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); $crudCreate->process(); if ($crudCreate->pipeline_getResponseHeaderStatus() != 200) { $this->ws->conneg->setStatus($crudCreate->pipeline_getResponseHeaderStatus()); $this->ws->conneg->setStatusMsg($crudCreate->pipeline_getResponseHeaderStatusMsg()); $this->ws->conneg->setStatusMsgExt($crudCreate->pipeline_getResponseHeaderStatusMsgExt()); $this->ws->conneg->setError($crudCreate->pipeline_getError()->id, $crudCreate->pipeline_getError()->webservice, $crudCreate->pipeline_getError()->name, $crudCreate->pipeline_getError()->description, $crudCreate->pipeline_getError()->debugInfo, $crudCreate->pipeline_getError()->level); // In case of error, we delete the dataset we previously created. $ontologyDelete = new OntologyDelete($this->ws->ontologyUri, $this->ws->registered_ip, $this->ws->requester_ip); $ontologyDelete->ws_conneg($_SERVER['HTTP_ACCEPT'], $_SERVER['HTTP_ACCEPT_CHARSET'], $_SERVER['HTTP_ACCEPT_ENCODING'], $_SERVER['HTTP_ACCEPT_LANGUAGE']); $ontologyDelete->deleteOntology(); if ($ontologyDelete->pipeline_getResponseHeaderStatus() != 200) { $this->ws->conneg->setStatus($ontologyDelete->pipeline_getResponseHeaderStatus()); $this->ws->conneg->setStatusMsg($ontologyDelete->pipeline_getResponseHeaderStatusMsg()); $this->ws->conneg->setStatusMsgExt($ontologyDelete->pipeline_getResponseHeaderStatusMsgExt()); $this->ws->conneg->setError($ontologyDelete->pipeline_getError()->id, $ontologyDelete->pipeline_getError()->webservice, $ontologyDelete->pipeline_getError()->name, $ontologyDelete->pipeline_getError()->description, $ontologyDelete->pipeline_getError()->debugInfo, $ontologyDelete->pipeline_getError()->level); return; } return; } unset($crudCreate); } } } } } }