function getLoadedOntologies($structwsf, $queryExtension = NULL) { $ontologyRead = new OntologyReadQuery($structwsf); $getLoadedOntologiesFunction = new GetLoadedOntologiesFunction(); $getLoadedOntologiesFunction->modeDescriptions(); $ontologyRead->getLoadedOntologies($getLoadedOntologiesFunction)->send($queryExtension !== NULL ? $queryExtension : NULL); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $ontologies = array('local' => array(), 'reference' => array(), 'admin' => array()); foreach ($resultset['unspecified'] as $uri => $ontology) { $onto = array('uri' => '', 'label' => '', 'modified' => false); $ontologyType = 'local'; if (isset($ontology['http://purl.org/ontology/sco#ontologyType'])) { switch ($ontology['http://purl.org/ontology/sco#ontologyType'][0]['uri']) { case "http://purl.org/ontology/sco#referenceOntology": $ontologyType = 'reference'; break; case "http://purl.org/ontology/sco#administrativeOntology": $ontologyType = 'admin'; break; case "http://purl.org/ontology/sco#localOntology": $ontologyType = 'local'; break; } } $onto['uri'] = $uri; $onto['label'] = $ontology['prefLabel']; if (isset($ontology['http://purl.org/ontology/wsf#ontologyModified'])) { $onto['modified'] = TRUE; } array_push($ontologies[$ontologyType], $onto); } return $ontologies; } else { $debugFile = md5(microtime()) . '.error'; file_put_contents('/tmp/' . $debugFile, var_export($ontologyRead, TRUE)); @cecho('Can\'t get loaded ontologies. ' . $ontologyRead->getStatusMessage() . $ontologyRead->getStatusMessageDescription() . "\nDebug file: /tmp/{$debugFile}\n", 'RED'); exit(1); } }
public function run() { cecho("\n\n"); cecho("Data validation test: " . $this->description . "...\n\n", 'LIGHT_BLUE'); // First, get the list of all the possible custom datatypes and their possible base datatype $customDatatypes = $this->getCustomDatatypes(); // Check for universal restriction on Datatype Properties $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from named <' . $ontology . '> '; } $sparql->mime("application/sparql-results+json")->query('select distinct ?restriction ?class ?onProperty ?dataRange ' . $from . ' where { ?s a ?class. graph ?g { ?class <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?restriction . ?restriction a <http://www.w3.org/2002/07/owl#Restriction> ; <http://www.w3.org/2002/07/owl#onProperty> ?onProperty ; <http://www.w3.org/2002/07/owl#allValuesFrom> ?dataRange . ?onProperty a <http://www.w3.org/2002/07/owl#DatatypeProperty> . } }')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { cecho("Here is the list of all the OWL universal restrictions defined for the classes currently used in the target datasets applied on datatype properties:\n\n", 'LIGHT_BLUE'); $universals = array(); foreach ($results['results']['bindings'] as $result) { $class = $result['class']['value']; $dataRange = $result['dataRange']['value']; $onProperty = $result['onProperty']['value']; cecho(' -> Record of type "' . $class . '" has an universal restriction when using datatype property "' . $onProperty . '" with value type "' . $dataRange . '"' . "\n", 'LIGHT_BLUE'); if (!isset($universals[$class])) { $universals[$class] = array(); } $universals[$class][] = array('onProperty' => $onProperty, 'dataRange' => $dataRange); } cecho("\n\n"); foreach ($universals as $class => $univs) { foreach ($univs as $universal) { $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from <' . $ontology . '> '; } $datatypeFilter = ''; // Here, if rdfs:Literal is used, we have to filter for xsd:string also since it is the default // used by Virtuoso... if (!empty($universal['dataRange'])) { if ($universal['dataRange'] == 'http://www.w3.org/2000/01/rdf-schema#Literal') { $datatypeFilter = 'filter((str(datatype(?value)) != \'http://www.w3.org/2000/01/rdf-schema#Literal\' && str(datatype(?value)) != \'http://www.w3.org/2001/XMLSchema#string\') && ?onProperty in (<' . $universal['onProperty'] . '>))'; } else { if (!empty($customDatatypes[$universal['dataRange']])) { if ($customDatatypes[$universal['dataRange']] === 'http://www.w3.org/2001/XMLSchema#anySimpleType') { $datatypeFilter = 'filter((str(datatype(?value)) = \'' . $universal['dataRange'] . '\' || str(datatype(?value)) = \'' . $customDatatypes[$universal['dataRange']] . '\' || str(datatype(?value)) = \'http://www.w3.org/2001/XMLSchema#string\') && ?onProperty in (<' . $universal['onProperty'] . '>))'; } else { $datatypeFilter = 'filter((str(datatype(?value)) != \'' . $universal['dataRange'] . '\' && str(datatype(?value)) != \'' . $customDatatypes[$universal['dataRange']] . '\') && ?onProperty in (<' . $universal['onProperty'] . '>))'; } } else { $datatypeFilter = 'filter((str(datatype(?value)) != \'' . $universal['dataRange'] . '\') && ?onProperty in (<' . $universal['onProperty'] . '>))'; } } } // With this query, we make sure that if we have a universal restriction for that property and class // that all the values uses the specified datatype. Otherwise, we return the ones that doesn't. $sparql->mime("application/sparql-results+json")->query('select ?s ' . $from . ' where { ?s a <' . $class . '> . ?s ?onProperty ?value . ' . $datatypeFilter . ' } ')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { foreach ($results['results']['bindings'] as $result) { $subject = $result['s']['value']; cecho(' -> record: ' . $subject . "\n", 'LIGHT_RED'); cecho(' -> property: ' . $universal['onProperty'] . "\n", 'LIGHT_RED'); $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-100', 'type' => 'error', 'invalidRecordURI' => $subject, 'invalidPropertyURI' => $universal['onProperty'], 'dataRange' => $universal['dataRange']); } } } else { cecho("We couldn't get the number of properties per record from the structWSF instance\n", 'YELLOW'); // Error: can't get the number of properties used per record $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-51', 'type' => 'warning'); } // Now let's make sure that there is at least one triple where the value belongs // to the defined datatype $values = array(); if (!empty($universal['dataRange'])) { if ($universal['dataRange'] == 'http://www.w3.org/2000/01/rdf-schema#Literal') { $datatypeFilter = 'filter(str(datatype(?value)) = \'http://www.w3.org/2000/01/rdf-schema#Literal\' || str(datatype(?value)) = \'http://www.w3.org/2001/XMLSchema#string\')'; } else { if (!empty($customDatatypes[$universal['dataRange']])) { if ($customDatatypes[$universal['dataRange']] === 'http://www.w3.org/2001/XMLSchema#anySimpleType') { $datatypeFilter = 'filter(str(datatype(?value)) = \'' . $universal['dataRange'] . '\' || str(datatype(?value)) = \'' . $customDatatypes[$universal['dataRange']] . '\' || str(datatype(?value)) = \'http://www.w3.org/2001/XMLSchema#string\')'; } else { $datatypeFilter = 'filter(str(datatype(?value)) = \'' . $universal['dataRange'] . '\' || str(datatype(?value)) = \'' . $customDatatypes[$universal['dataRange']] . '\' )'; } } else { $datatypeFilter = 'filter(str(datatype(?value)) = \'' . $universal['dataRange'] . '\')'; } } } $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; } $sparql->mime("application/sparql-results+json")->query('select distinct ?value ?s ' . $from . ' where { ?s a <' . $class . '> ; <' . $universal['onProperty'] . '> ?value. ' . $datatypeFilter . ' }')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); $values = array(); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { foreach ($results['results']['bindings'] as $result) { $value = $result['value']['value']; $s = ''; if (isset($result['s'])) { $s = $result['s']['value']; } $values[] = array('value' => $value, 'type' => $universal['dataRange'], 'affectedRecord' => $s); } } // For each value/type(s), we do validate that the range is valid // We just need to get one triple where the value comply with the defined datatype // to have this check validated foreach ($values as $value) { // First, check if we have a type defined for the value. If not, then we infer it is rdfs:Literal if (empty($value['type'])) { $value['type'] = array('http://www.w3.org/2000/01/rdf-schema#Literal'); } // If then match, then we make sure that the value is valid according to the // internal Check datatype validation tests $datatypeValidationError = FALSE; switch ($value['type']) { case "http://www.w3.org/2001/XMLSchema#anySimpleType": if (!$this->validateAnySimpleType($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#base64Binary": if (!$this->validateBase64Binary($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#boolean": if (!$this->validateBoolean($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#byte": if (!$this->validateByte($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#dateTimeStamp": if (!$this->validateDateTimeStampISO8601($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#dateTime": if (!$this->validateDateTimeISO8601($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#decimal": if (!$this->validateDecimal($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#double": if (!$this->validateDouble($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#float": if (!$this->validateFloat($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#hexBinary": if (!$this->validateHexBinary($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#int": if (!$this->validateInt($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#integer": if (!$this->validateInteger($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#language": if (!$this->validateLanguage($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#long": if (!$this->validateLong($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#Name": if (!$this->validateName($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#NCName": if (!$this->validateNCName($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#negativeInteger": if (!$this->validateNegativeInteger($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#NMTOKEN": if (!$this->validateNMTOKEN($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#nonNegativeInteger": if (!$this->validateNonNegativeInteger($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#nonPositiveInteger": if (!$this->validateNonPositiveInteger($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#normalizedString": if (!$this->validateNormalizedString($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral": if (!$this->validatePlainLiteral($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#positiveInteger": if (!$this->validatePositiveInteger($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#short": if (!$this->validateShort($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#string": if (!$this->validateString($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#token": if (!$this->validateToken($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#unsignedByte": if (!$this->validateUnsignedByte($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#unsignedInt": if (!$this->validateUnsignedInt($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#unsignedLong": if (!$this->validateUnsignedLong($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#unsignedShort": if (!$this->validateUnsignedShort($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral": if (!$this->validateXMLLiteral($value['value'])) { $datatypeValidationError = TRUE; } break; case "http://www.w3.org/2001/XMLSchema#anyURI": if (!$this->validateAnyURI($value['value'])) { $datatypeValidationError = TRUE; } break; default: // Custom type, try to validate it according to the // description of that custom datatype within the // ontology if (!$this->validateCustomDatatype($value['type'], $value['value'])) { $datatypeValidationError = TRUE; } break; } if ($datatypeValidationError === TRUE) { cecho(' -> Couldn\'t validate that this value: "' . $value['value'] . '" belong to the datatype "' . $universal['dataRange'] . '"' . "\n", 'LIGHT_RED'); cecho(' -> Affected record: "' . $value['affectedRecord'] . '"' . "\n", 'YELLOW'); // If it doesn't match, then we report an error directly $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-102', 'type' => 'error', 'datatypeProperty' => $universal['onProperty'], 'expectedDatatype' => $universal['dataRange'], 'invalidValue' => $value['value'], 'affectedRecord' => $value['affectedRecord']); } } } else { cecho("We couldn't get the list of values for the {$datatypePropety} property\n", 'YELLOW'); $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-54', 'type' => 'warning'); } } } if (count($this->errors) <= 0) { cecho("\n\n All records respects the universal restrictions cardinality specified in the ontologies...\n\n\n", 'LIGHT_GREEN'); } } else { cecho("No classes have any universal restriction cardinality defined in any ontologies. Move on to the next check...\n\n\n", 'LIGHT_GREEN'); } } else { cecho("We couldn't get the list of universal restriction from the structWSF instance\n", 'YELLOW'); // Error: can't get the list of retrictions $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-50', 'type' => 'warning'); } // Check for universal restriction on Object Properties $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from named <' . $ontology . '> '; } $sparql->mime("application/sparql-results+json")->query('select distinct ?restriction ?class ?onProperty ?classExpression ' . $from . ' where { ?s a ?class. graph ?g { ?class <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?restriction . ?restriction a <http://www.w3.org/2002/07/owl#Restriction> ; <http://www.w3.org/2002/07/owl#onProperty> ?onProperty ; <http://www.w3.org/2002/07/owl#allValuesFrom> ?classExpression . ?onProperty a <http://www.w3.org/2002/07/owl#ObjectProperty> . } }')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { cecho("Here is the list of all the OWL universal restrictions defined for the classes currently used in the target datasets applied on object properties:\n\n", 'LIGHT_BLUE'); $universals = array(); foreach ($results['results']['bindings'] as $result) { $class = $result['class']['value']; $onProperty = $result['onProperty']['value']; $classExpression = $result['classExpression']['value']; cecho(' -> Record of type "' . $class . '" have an universal restriction when using object property "' . $onProperty . '"' . "\n", 'LIGHT_BLUE'); if (!isset($universals[$class])) { $universals[$class] = array(); } $universals[$class][] = array('onProperty' => $onProperty, 'classExpression' => $classExpression); } cecho("\n\n"); foreach ($universals as $class => $univs) { foreach ($univs as $universal) { $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from <' . $ontology . '> '; } $classExpressionFilter = ''; if (!empty($universal['classExpression']) && $universal['classExpression'] != 'http://www.w3.org/2002/07/owl#Thing') { $subClasses = array($universal['classExpression']); // Get all the classes that belong to the class expression defined in this restriction $getSubClassesFunction = new GetSubClassesFunction(); $getSubClassesFunction->getClassesUris()->allSubClasses()->uri($universal['classExpression']); $ontologyRead = new OntologyReadQuery($this->network); $ontologyRead->ontology($this->getClassOntology($universal['classExpression']))->getSubClasses($getSubClassesFunction)->enableReasoner()->mime('resultset')->send(); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $subClasses = array_merge($subClasses, array_keys($resultset['unspecified'])); if (!empty($subClasses)) { $filter = ''; foreach ($subClasses as $subClass) { $filter .= ' str(?value_type) = "' . $subClass . '" ||'; } $classExpressionFilter .= " filter(" . trim(trim($filter, '||')) . ") \n"; } } else { cecho("We couldn't get sub-classes of class expression from the structWSF instance\n", 'YELLOW'); // Error: can't get the subclasses of a target ontology $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-53', 'type' => 'warning'); } } $sparql->mime("application/sparql-results+json")->query('select ?s ' . $from . ' where { ?s a <' . $class . '> . ?s <' . $universal['onProperty'] . '> ?value . filter not exists { ?value a ?value_type . ' . $classExpressionFilter . ' } } ')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { foreach ($results['results']['bindings'] as $result) { $subject = $result['s']['value']; cecho(' -> record: ' . $subject . "\n", 'LIGHT_RED'); cecho(' -> property: ' . $universal['onProperty'] . "\n", 'LIGHT_RED'); $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-101', 'type' => 'error', 'invalidRecordURI' => $subject, 'invalidPropertyURI' => $universal['onProperty'], 'classExpression' => $universal['classExpression']); } } } else { cecho("We couldn't check if the universal restriction was respected from the structWSF instance\n", 'YELLOW'); $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-53', 'type' => 'warning'); } } if (count($this->errors) <= 0) { cecho("\n\n All records respects the universal restrictions specified in the ontologies...\n\n\n", 'LIGHT_GREEN'); } } } } else { cecho("We couldn't get the number of object properties used per record from the structWSF instance\n", 'YELLOW'); // Error: can't get the number of object properties used per record $this->errors[] = array('id' => 'OWL-RESTRICTION-ONLY-52', 'type' => 'warning'); } }
public function run() { cecho("\n\n"); cecho("Data validation test: " . $this->description . "...\n\n", 'LIGHT_BLUE'); $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from named <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from <' . $ontology . '> '; } // Get the list of all the object properties used within the datasets $sparql->mime("application/sparql-results+json")->query('select distinct ?p ?range ' . $from . ' where { graph ?g { ?s ?p ?o . filter(isIRI(?o)) } optional { ?p <http://www.w3.org/2000/01/rdf-schema#range> ?range . } filter(str(?p) != "http://purl.org/dc/terms/isPartOf" && str(?p) != "http://www.w3.org/1999/02/22-rdf-syntax-ns#value" && str(?p) != "http://www.w3.org/1999/02/22-rdf-syntax-ns#type") }')->send(); if ($sparql->isSuccessful()) { $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { $objectProperties = array(); $thereAreEmptyRanges = FALSE; foreach ($results['results']['bindings'] as $result) { $objectProperty = $result['p']['value']; $objectProperties[$objectProperty] = ''; if (isset($result['range'])) { $objectProperties[$objectProperty] = $result['range']['value']; } else { $thereAreEmptyRanges = TRUE; } } // Display warnings if ($thereAreEmptyRanges) { cecho("The following object properties are used to describe records, but their range is not specified in the ontologies. owl:Thing is assumed as the range, but you may want to define it further and re-run this check:\n", 'YELLOW'); foreach ($objectProperties as $objectProperty => $range) { if (empty($range)) { cecho(' -> object property: ' . $objectProperty . "\n", 'YELLOW'); $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-50', 'type' => 'warning', 'objectProperty' => $objectProperty); } } } // Now, for each object properties that have a range defined, // we: // // (a) List all values used for a given property // (b) For each of these values, make sure they comply with what is defined in the ontology as // the range of the foreach ($objectProperties as $objectProperty => $range) { // If the range is empty, we consider it owl:Thing. // If the range is owl:Thing, then we simply skip this check since everything is an owl:Thing if (!empty($range) && $range != 'http://www.w3.org/2002/07/owl#Thing') { $values = array(); $sparql = new SparqlQuery($this->network); $from = ''; foreach ($this->checkOnDatasets as $dataset) { $from .= 'from <' . $dataset . '> '; $from .= 'from named <' . $dataset . '> '; } foreach ($this->checkUsingOntologies as $ontology) { $from .= 'from <' . $ontology . '> '; } $sparql->mime("application/sparql-results+json")->query('select distinct ?value ?value_type ' . $from . ' where { graph ?g { ?s <' . $objectProperty . '> ?value. filter(isIRI(?value)) } optional { ?value a ?value_type } }')->send(); if ($sparql->isSuccessful()) { // Create the array of object-values/types $results = json_decode($sparql->getResultset(), TRUE); if (isset($results['results']['bindings']) && count($results['results']['bindings']) > 0) { foreach ($results['results']['bindings'] as $result) { $value = $result['value']['value']; $type = ''; if (isset($result['value_type'])) { $type = $result['value_type']['value']; } if (!isset($values[$value])) { $values[$value] = array(); } if (!empty($type) && !in_array($type, $values[$value])) { $values[$value][] = $type; } } } // For each value/type(s), we do validate that the range is valid foreach ($values as $value => $types) { // First, check if we have a type defined for the value. If not, then we infer it is owl:Thing if (empty($types)) { $types = array('http://www.w3.org/2002/07/owl#Thing'); } // Then, check if the $range and the $types directly match if (in_array($range, $types)) { continue; } else { // If they are not, then we check in the ontology to see if the range is not // one of the super class of one of the type(s) $superClasses = array(); foreach ($types as $type) { $ontologyURI = $this->getTypeOntology($type); if ($ontologyURI !== FALSE) { $ontologyRead = new OntologyReadQuery($this->network); $getSuperClassesFunc = new GetSuperClassesFunction(); $getSuperClassesFunc->allSuperClasses()->getClassesUris()->uri($type); $ontologyRead->enableReasoner()->ontology($ontologyURI)->getSuperClasses($getSuperClassesFunc)->mime('resultset')->send(); if ($ontologyRead->isSuccessful()) { $scs = $ontologyRead->getResultset()->getResultset(); // If empty, then there is no super-classes if (!empty($scs)) { $scs = $scs[key($scs)]; foreach ($scs as $superClass => $description) { if (!in_array($superClass, $superClasses)) { $superClasses[] = $superClass; } } } } else { cecho("We couldn't get the list of super-classes of a target type from the structWSF instance\n", 'YELLOW'); // Log a warning // Can't get the super classes of the target type $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-51', 'type' => 'warning', 'objectProperty' => $objectProperty); } } else { cecho("We couldn't find the ontology where the {$type} is defined on the structWSF instance\n", 'YELLOW'); // Log a warning // Can't find ontology where the type $type is defined $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-52', 'type' => 'warning', 'objectProperty' => $objectProperty); } } $rangeMatch = FALSE; foreach ($superClasses as $superClass) { if ($superClass == $range) { $rangeMatch = TRUE; break; } } if (!$rangeMatch) { // Log an error // Couldn't match one of the super classe with the specified range cecho(' -> Object property "' . $objectProperty . '" doesn\'t match range "' . $range . '" for value "' . $value . '"' . "\n", 'LIGHT_RED'); $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-100', 'type' => 'error', 'objectProperty' => $objectProperty, 'definedRange' => $range, 'value' => $value, 'valueTypes' => $types, 'valueSuperTypes' => $superClasses, 'affectedRecords' => $this->getAffectedRecords($objectProperty, $value)); } } } } else { cecho("We couldn't get the range of the {$objectProperty} object property from the structWSF instance\n", 'YELLOW'); $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-54', 'type' => 'warning'); } } } } } else { cecho("We couldn't get the list of object properties from the structWSF instance\n", 'YELLOW'); $this->errors[] = array('id' => 'OBJECT-PROPERTIES-RANGE-53', 'type' => 'warning'); } }
function generateStructures($folder, $structwsf, $queryExtension = NULL) { include_once 'getLoadedOntologies.php'; cecho("Generating derivate ontological structures...\n", 'CYAN'); $ontologiesClustered = getLoadedOntologies($structwsf); $ontologies = array(); $ontologies = array_merge($ontologies, $ontologiesClustered['local'], $ontologiesClustered['reference'], $ontologiesClustered['admin']); // Generate the ironXML schemas foreach ($ontologies as $ontology) { cecho("Generating ironXML schema of the " . $ontology['label'] . " ontology...\n", 'CYAN'); $ontologyRead = new OntologyReadQuery($structwsf); $ontologyRead->ontology($ontology['uri'])->getIronXMLSchema()->send($queryExtension !== NULL ? $queryExtension : NULL); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $ironXML = $resultset['unspecified'][$ontology['uri']]['http://purl.org/ontology/wsf#serializedIronXMLSchema']['0']['value']; cecho("Generated...\n", 'CYAN'); $filename = substr($ontology['uri'], strripos($ontology['uri'], "/") + 1); $filename = substr($filename, 0, strripos($filename, ".")); file_put_contents(rtrim($folder, '/') . '/' . $filename . '.xml', $ironXML); cecho("Saved to: " . rtrim($folder, '/') . '/' . $filename . '.xml' . "\n", 'CYAN'); } else { $debugFile = md5(microtime()) . '.error'; file_put_contents('/tmp/' . $debugFile, var_export($ontologyRead, TRUE)); @cecho('Can\'t get the ironXML schema structure for this ontology: ' . $ontology . '. ' . $ontologyRead->getStatusMessage() . $ontologyRead->getStatusMessageDescription() . "\nDebug file: /tmp/{$debugFile}\n", 'RED'); continue; } } // Generate the ironJSON schemas foreach ($ontologies as $ontology) { cecho("Generating ironJSON schema of the " . $ontology['label'] . " ontology...\n", 'CYAN'); $ontologyRead = new OntologyReadQuery($structwsf); $ontologyRead->ontology($ontology['uri'])->getIronJsonSchema()->send($queryExtension !== NULL ? $queryExtension : NULL); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $ironJSON = $resultset['unspecified'][$ontology['uri']]['http://purl.org/ontology/wsf#serializedIronJSONSchema']['0']['value']; cecho("Generated...\n", 'CYAN'); $filename = substr($ontology['uri'], strripos($ontology['uri'], "/") + 1); $filename = substr($filename, 0, strripos($filename, ".")); file_put_contents(rtrim($folder, '/') . '/' . $filename . '.json', $ironJSON); cecho("Saved to: " . rtrim($folder, '/') . '/' . $filename . '.json' . "\n", 'CYAN'); // Create the pre-existing JS script to load that schema in a Schema object. $ironJSONSchema = 'var ' . $filename . '_schema_srz = ' . $ironJSON . ";"; $ironJSONSchema .= 'var ' . $filename . '_schema = new Schema(' . $filename . '_schema_srz);'; // Special handling: make sure to convert all "%5C" characters into "\". This has to be done because // of the way the ProcessorXML.php (so, the DOMDocument API) works, and how the xml-encoding currently // works. Enventually, we should use the simplexml API in the processorXML script to properly // manage the encoding, and decoding of the XML data, *AND* of the HTML entities (it is the HTML // entities that are strangely manipulated in the DOMDocument API). $ironJSONSchema = str_replace("%5C", '\\', $ironJSONSchema); file_put_contents(rtrim($folder, "/") . "/" . $filename . ".js", $ironJSONSchema); cecho("Saved to: " . rtrim($folder, '/') . '/' . $filename . '.js' . "\n", 'CYAN'); } else { $debugFile = md5(microtime()) . '.error'; file_put_contents('/tmp/' . $debugFile, var_export($ontologyRead, TRUE)); @cecho('Can\'t get the ironJSON schema structure for this ontology: ' . $ontology . '. ' . $ontologyRead->getStatusMessage() . $ontologyRead->getStatusMessageDescription() . "\nDebug file: /tmp/{$debugFile}\n", 'RED'); continue; } } // Create the JS schema file. $schemaJS = ' /* List of attribute URIs that are generally used for labeling entities in different ontologies */ var prefLabelAttributes = [ "http://www.w3.org/2004/02/skos/core#prefLabel", "http://purl.org/ontology/iron#prefLabel", "http://umbel.org/umbel#prefLabel", "http://purl.org/dc/terms/title", "http://purl.org/dc/elements/1.1/title", "http://xmlns.com/foaf/0.1/name", "http://xmlns.com/foaf/0.1/givenName", "http://xmlns.com/foaf/0.1/family_name", "http://www.geonames.org/ontology#name", "http://www.w3.org/2000/01/rdf-schema#label" ]; var altLabelAttributes = [ "http://www.w3.org/2004/02/skos/core#altLabel", "http://purl.org/ontology/iron#altLabel", "http://umbel.org/umbel#altLabel", ]; var descriptionAttributes = [ "http://purl.org/ontology/iron#description", "http://www.w3.org/2000/01/rdf-schema#comment", "http://purl.org/dc/terms/description", "http://purl.org/dc/elements/1.1/description", "http://www.w3.org/2004/02/skos/core#definition" ]; function Schema(sjson) { // Define all prefixes of this resultset this.prefixes = sjson.schema.prefixList; // Unprefixize all URIs of this Schema var resultsetJsonText = JSON.stringify(sjson); for(var prefix in this.prefixes) { if(this.prefixes.hasOwnProperty(prefix)) { var pattern = new RegExp(prefix+"_", "igm"); resultsetJsonText = resultsetJsonText.replace(pattern, this.prefixes[prefix]); } } sjson = JSON.parse(resultsetJsonText); this.attributes = sjson.schema.attributeList; this.types = sjson.schema.typeList; // Extend all attributes of this schema with additional functions for(var i = 0; i < this.attributes.length; i++) { this.attributes[i].prefixes = this.prefixes; } // Extend all types of this schema with additional functions for(var i = 0; i < this.types.length; i++) { this.types[i].prefixes = this.prefixes; } }'; file_put_contents(rtrim($folder, "/") . "/schema.js", $schemaJS); // Generate PHP serialized classes hierarchy cecho("Generating PHP serialized classes hierarchy structure file...\n", 'CYAN'); $ontologyRead = new OntologyReadQuery($structwsf); $ontologyRead->getSerializedClassHierarchy()->send($queryExtension !== NULL ? $queryExtension : NULL); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $ironXML = $resultset['unspecified'][""]['http://purl.org/ontology/wsf#serializedClassHierarchy']['0']['value']; cecho("Generated...\n", 'CYAN'); file_put_contents(rtrim($folder, '/') . '/classHierarchySerialized.srz', $ironXML); cecho("Saved to: " . rtrim($folder, '/') . '/classHierarchySerialized.srz' . "\n", 'CYAN'); } else { $debugFile = md5(microtime()) . '.error'; file_put_contents('/tmp/' . $debugFile, var_export($ontologyRead, TRUE)); @cecho('Can\'t get the PHP serialized classes hierarchy structure file' . $ontologyRead->getStatusMessage() . $ontologyRead->getStatusMessageDescription() . "\nDebug file: /tmp/{$debugFile}\n", 'RED'); } // Generate PHP serialized properties hierarchy cecho("Generating PHP serialized properties hierarchy structure file...\n", 'CYAN'); $ontologyRead = new OntologyReadQuery($structwsf); $ontologyRead->getSerializedPropertyHierarchy()->send($queryExtension !== NULL ? $queryExtension : NULL); if ($ontologyRead->isSuccessful()) { $resultset = $ontologyRead->getResultset()->getResultset(); $ironXML = $resultset['unspecified'][""]['http://purl.org/ontology/wsf#serializedPropertyHierarchy']['0']['value']; cecho("Generated...\n", 'CYAN'); file_put_contents(rtrim($folder, '/') . '/propertyHierarchySerialized.srz', $ironXML); cecho("Saved to: " . rtrim($folder, '/') . '/propertyHierarchySerialized.srz' . "\n", 'CYAN'); } else { $debugFile = md5(microtime()) . '.error'; file_put_contents('/tmp/' . $debugFile, var_export($ontologyRead, TRUE)); @cecho('Can\'t get the PHP serialized properties hierarchy structure file' . $ontologyRead->getStatusMessage() . $ontologyRead->getStatusMessageDescription() . "\nDebug file: /tmp/{$debugFile}\n", 'RED'); } cecho("All structures generates!\n", 'CYAN'); }