protected function open() { $this->graph = new Graph(); $rdfa_parser = new RdfaParser(); $json_parser = new JsonLd(); \EasyRdf\RdfNamespace::set('dcat', 'http://www.w3.org/ns/dcat#'); \EasyRdf\RdfNamespace::set('lbld', 'http://decisions.data.vlaanderen.be/ns#'); $data = file_get_contents($this->extractor->uri); // Assume we have an rdfa document to begin with $rdfa_parser->parse($this->graph, $data, 'rdfa', $this->extractor->base_uri); // Check if we have properties we need to include into the current graph $properties = explode(',', $this->extractor->follow_properties); foreach ($this->graph->resources() as $resource) { foreach ($properties as $property) { $resolve_resources = $resource->allResources($property); if (!empty($resolve_resources)) { foreach ($resolve_resources as $resolve_resource) { $data = file_get_contents($resolve_resource->getUri()); // Parse any rdfa data in the document into the existing graph $this->graph->parse($data, 'rdfa', $resolve_resource->getUri()); $json = $this->parseJsonldSnippet($data); if (!empty($json)) { try { $this->graph->parse($json, 'jsonld', $resolve_resource->getUri()); } catch (\Exception $ex) { \Log::error("We could not parse json from the data, the data was:" . $json); } } } } } } // We only return the graph once as a full datastructure $this->has_next = true; }
public static function getBody($dataObj) { if ($dataObj->is_semantic) { // Check if a configuration is given $conf = array(); if (!empty($dataObj->semantic->conf)) { $conf = $dataObj->semantic->conf; foreach ($conf['ns'] as $prefix => $uri) { RdfNamespace::set($prefix, $uri); } } // Add the configured ontology prefixes $ontologies = \App::make('Tdt\\Core\\Repositories\\Interfaces\\OntologyRepositoryInterface'); $context = array(); // Only add the common namespaces $namespaces = array('hydra', 'rdf', 'rdfs', 'foaf', 'void', 'xsd', 'skos', 'xs'); foreach ($namespaces as $ns) { $namespace = $ontologies->getByPrefix($ns); if (!empty($namespace)) { $context[$ns] = $namespace['uri']; } } $output = $dataObj->data->serialise('jsonld'); // Next, encode the context as JSON $jsonContext = json_encode($context); // Compact the JsonLD by using @context -> Needs tweaking can only return the // URI spaces that are used in the document. $compacted = JsonLD::compact($output, $jsonContext); // Print the resulting JSON-LD! return JsonLD::toString($compacted, true); } else { \App::abort(400, "The data is not a semantically linked document, a linked data JSON representation is not possible."); } }
public function __construct($endpoint, $namespaces) { $this->endpoint = $endpoint; $this->namespaces = $namespaces; foreach ($namespaces as $namespace => $uri) { \EasyRdf\RdfNamespace::set($namespace, $uri); } }
/** * @param $types * @return array|null */ public function getMostAccurateType($types, $knowTypesForExternService = array()) { // filter types to have only types filiation defined with subClassOf annotation $definedOntoTypes = array(); foreach ($types as $type) { $type = (string) $type; if ($type && !empty($type)) { $shortenType = RdfNamespace::shorten($type); if (isset($this->rdfFiliation[$shortenType])) { $definedOntoTypes[] = $shortenType; } } } $arrayAccurateOnes = array(); if (count($definedOntoTypes) == 0) { return null; } else { if (count($definedOntoTypes) == 1) { $arrayAccurateOnes = $definedOntoTypes; } else { // try to find the most accurate type foreach ($definedOntoTypes as $currentType) { $mostAccurate = true; if (isset($this->rdfFiliation[$currentType]['parentClassOf'])) { $subClassTypes = $this->rdfFiliation[$currentType]['parentClassOf']; // in class children types, look if one of them is defined with subClassOf annotation foreach ($definedOntoTypes as $type) { if (in_array($type, $subClassTypes)) { $mostAccurate = false; break; } } } if ($mostAccurate) { $arrayAccurateOnes[] = $currentType; } } } } if (!empty($knowTypesForExternService)) { return $this->findMostAccurateTypesInKnowTypesByExternalService($arrayAccurateOnes, $knowTypesForExternService); } return $arrayAccurateOnes; }
/** * Create the DCAT document of the published (non-draft) resources * * @return mixed \Data object with a graph of DCAT information */ private function createDcat() { $ns = $this->dcat->getNamespaces(); foreach ($ns as $prefix => $uri) { RdfNamespace::set($prefix, $uri); } // If limit is empty, provide a custom page size for the DCAT document $limit = \Input::get('limit'); if (empty($limit)) { \Input::merge(array('limit' => 100)); } // Apply paging when fetching the definitions list($limit, $offset) = Pager::calculateLimitAndOffset(); $definition_count = $this->definitions->countPublished(); $definitions = $this->definitions->getAllPublished($limit, $offset); $oldest = $this->definitions->getOldest(); $describedDefinitions = array(); // Add the source type description to the definition foreach ($definitions as $definition) { $definition = array_merge($definition, $this->definitions->getFullDescription($definition['collection_uri'] . '/' . $definition['resource_name'])); array_push($describedDefinitions, $definition); } $graph = $this->dcat->getDcatDocument($describedDefinitions, $oldest); // Return the dcat feed in our internal data object $data_result = new Data(); $data_result->data = $graph; $data_result->is_semantic = true; $data_result->paging = Pager::calculatePagingHeaders($limit, $offset, $definition_count); // Add the semantic configuration for the ARC graph $data_result->semantic = new \stdClass(); $data_result->semantic->conf = array('ns' => $ns); $data_result->definition = []; $data_result->definition['resource_name'] = 'dcat'; $data_result->definition['collection_uri'] = 'info'; $data_result->definition['source_type'] = 'DCAT'; return $data_result; }
protected function open() { // Perform XLST $xsl_url = "https://webgate.ec.europa.eu/CITnet/stash/projects/ODCKAN/repos/iso-19139-to-dcat-ap/browse/iso-19139-to-dcat-ap.xsl?raw"; $proc = null; try { $xml = new DOMDocument(); $xml->load($this->extractor->uri); $xsl = new DOMDocument(); $xsl->load($xsl_url); $proc = new XSLTProcessor(); $proc->importStyleSheet($xsl); } catch (\ErrorException $ex) { $this->log('Something went wrong: ' . $ex->getMessage()); die; } $dcat_document = $proc->transformToXML($xml); \EasyRdf\RdfNamespace::set('locn', 'http://www.w3.org/ns/locn#'); // Parse the dcat graph $graph = new Graph(); $rdf_parser = new RdfXml(); $rdf_parser->parse($graph, $dcat_document, 'rdfxml', 'http://foo'); $this->datasets = $graph->allOfType('dcat:Dataset'); }
private function sparqlRetrieveTriplesForNotation($notation) { // alternative query (the fuseki's query is the same except that # must be encoded as %23 or it will be understood as eof //$query = "prefix skos: <http://www.w3.org/2004/02/skos/core#> select ?s ?p ?o where {?s skos:notation '" . $notation . "' . }"; \EasyRdf\RdfNamespace::set('skos', 'http://www.w3.org/2004/02/skos/core#'); $query = "select ?s ?p ?o where {?s skos:notation '" . $notation . "' . }"; $sparqlClient = new \EasyRdf\Sparql\Client(BASE_URI_ . ':3030/openskos/query'); $result = $sparqlClient->query($query); return $result; }
/** * @ignore */ protected function serialisePrefixes() { $turtle = ''; foreach ($this->prefixes as $prefix => $count) { $url = RdfNamespace::get($prefix); $turtle .= "@prefix {$prefix}: <{$url}> .\n"; } return $turtle; }
/** * Retrieve a Data object identified by $uri * * @param string $uri The identifier that identifies a resource * * @return \Response */ public function get($uri) { // Check permissions Auth::requirePermissions('dataset.view'); // Split for an (optional) extension list($uri, $extension) = self::processURI($uri); $extension = strtolower($extension); // Check for caching // Based on: URI / Rest parameters / Query parameters / Paging headers $cache_string = $uri; list($limit, $offset) = Pager::calculateLimitAndOffset(); $cache_string .= '/limit=' . $limit . 'offset=' . $offset; $omit = ['limit', 'offset', 'page', 'page_size']; $query_string_params = \Input::get(); foreach ($query_string_params as $key => $val) { if (in_array($key, $omit)) { unset($query_string_params[$key]); } } $cache_string .= http_build_query($query_string_params); $cache_string = sha1($cache_string); if (Cache::has($cache_string)) { return ContentNegotiator::getResponse(Cache::get($cache_string), $extension); } else { // Get definition $definition = $this->definition->getByIdentifier($uri); if ($definition) { // Get source definition $source_definition = $this->definition->getDefinitionSource($definition['source_id'], $definition['source_type']); if ($source_definition) { $source_type = $source_definition['type']; // KML can be formatted into different formats if ($source_definition['type'] == 'XML' && $source_definition['geo_formatted'] == 1) { $source_type == 'kml'; $source_definition['type'] = 'KML'; } // Create the right datacontroller $controller_class = 'Tdt\\Core\\DataControllers\\' . $source_type . 'Controller'; $data_controller = \App::make($controller_class); // Get REST parameters $uri_segments = explode('/', $uri); $definition_segments = explode('/', $definition['collection_uri']); array_push($definition_segments, $definition['resource_name']); $rest_parameters = array_diff($uri_segments, $definition_segments); $rest_parameters = array_values($rest_parameters); $throttle_response = $this->applyThrottle($definition); if (!empty($throttle_response)) { return $throttle_response; } // Retrieve dataobject from datacontroller $data = $data_controller->readData($source_definition, $rest_parameters); // If the source type is XML, just return the XML contents, don't transform if (strtolower($source_type) == 'xml' && $extension == 'xml') { return $this->createXMLResponse($data->data); } elseif (strtolower($source_type) == 'xml' && $extension == 'kml' && $data->geo_formatted) { return $this->createXMLResponse($data->data); } elseif (!$data->is_semantic && $extension == 'xml' && $source_type != 'xml') { \App::abort(406, "The requested format for the datasource is not available."); } elseif (strtolower($source_type) == 'xml' && !$data->geo_formatted && !empty($extension) && $extension != 'xml') { \App::abort(406, "The requested format for the datasource is not available."); } elseif (strtolower($source_type) == 'xml' && $data->geo_formatted && !empty($extension) && !in_array($extension, $data->preferred_formats)) { \App::abort(406, "The requested format for the datasource is not available."); } $data->rest_parameters = $rest_parameters; // REST filtering if ($source_type != 'INSTALLED' && count($data->rest_parameters) > 0) { $data->data = self::applyRestFilter($data->data, $data->rest_parameters); } // Semantic paging with the hydra voc if ($data->is_semantic && !empty($data->paging)) { RdfNamespace::set('hydra', 'http://www.w3.org/ns/hydra/core#'); $graph = $data->data; $url = \URL::to($definition['collection_uri'] . '/' . $definition['resource_name']); $request_url = \Request::url(); $graph->addResource($request_url, 'void:subset', $url); foreach ($data->paging as $key => $val) { $paged_url = $request_url . '?offset=' . $val[0] . '&limit=' . $val[1] . Pager::buildQuerystring(); switch ($key) { case 'next': $graph->addResource($request_url, 'hydra:nextPage', $paged_url); break; case 'previous': $graph->addResource($request_url, 'hydra:previousPage', $paged_url); break; case 'last': $graph->addResource($request_url, 'hydra:lastPage', $paged_url); break; case 'first': $graph->addResource($request_url, 'hydra:firstPage', $paged_url); break; } } $graph->addResource($url, 'a', 'dcat:Dataset'); $title = null; if (!empty($definition['title'])) { $title = $definition['title']; } else { $title = $definition['collection_uri'] . '/' . $definition['resource_name']; } $graph->addLiteral($url, 'dc:title', $title); $graph->addLiteral($url, 'dc:description', $source_definition['description']); $graph->addResource($url, 'dcat:distribution', $url . '.json'); $data->data = $graph; } // Add definition to the object $data->definition = $definition; // Add source definition to the object $data->source_definition = $source_definition; // Add the available, supported formats to the object $format_helper = new FormatHelper(); $data->formats = $format_helper->getAvailableFormats($data); // Store in cache if (!empty($definition['cache_minutes'])) { Cache::put($cache_string, $data, $definition['cache_minutes']); } // Return the formatted response with content negotiation return ContentNegotiator::getResponse($data, $extension); } else { \App::abort(404, "Source for the definition could not be found."); } } else { // Coulnd't find a definition, but it might be a collection $resources = $this->definition->getByCollection($uri); if (count($resources) > 0) { $data = new Data(); $data->data = new \stdClass(); $data->data->datasets = array(); $data->data->collections = array(); foreach ($resources as $res) { // Check if it's a subcollection or a dataset $collection_uri = rtrim($res['collection_uri'], '/'); if ($collection_uri == $uri) { array_push($data->data->datasets, \URL::to($collection_uri . '/' . $res['resource_name'])); } else { // Push the subcollection if it's not already in the array if (!in_array(\URL::to($collection_uri), $data->data->collections)) { array_push($data->data->collections, \URL::to($collection_uri)); } } } // Fake a definition $data->definition = new \Definition(); $uri_array = explode('/', $uri); $last_chunk = array_pop($uri_array); $data->definition->collection_uri = join('/', $uri_array); $data->definition->resource_name = $last_chunk; // Return the formatted response with content negotiation return ContentNegotiator::getResponse($data, $extension); } else { \App::abort(404, "The dataset or collection you were looking for could not be found (URI: {$uri})."); } } } }
/** * Parses qnames and boolean values, which have equivalent starting * characters. * @ignore */ protected function parseQNameOrBoolean() { // First character should be a ':' or a letter $c = $this->read(); if ($c == -1) { throw new Exception("Turtle Parse Error: unexpected end of file while readying value", $this->line, $this->column); } if ($c != ':' && !self::isPrefixStartChar($c)) { throw new Exception("Turtle Parse Error: expected a ':' or a letter, found '{$c}'", $this->line, $this->column); } $namespace = null; if ($c == ':') { // qname using default namespace if (isset($this->namespaces[''])) { $namespace = $this->namespaces['']; } else { throw new Exception("Turtle Parse Error: default namespace used but not defined", $this->line, $this->column); } } else { // $c is the first letter of the prefix $prefix = $c; $c = $this->read(); while (self::isPrefixChar($c)) { $prefix .= $c; $c = $this->read(); } if ($c != ':') { // prefix may actually be a boolean value $value = $prefix; if ($value == "true" || $value == "false") { return array('type' => 'literal', 'value' => $value, 'datatype' => RdfNamespace::get('xsd') . 'boolean'); } } $this->verifyCharacterOrFail($c, ":"); if (isset($this->namespaces[$prefix])) { $namespace = $this->namespaces[$prefix]; } else { throw new Exception("Turtle Parse Error: namespace prefix '{$prefix}' used but not defined", $this->line, $this->column); } } // $c == ':', read optional local name $localName = ''; $c = $this->read(); if (self::isNameStartChar($c)) { if ($c == '\\') { $localName .= $this->readLocalEscapedChar(); } else { $localName .= $c; } $c = $this->read(); while (self::isNameChar($c)) { if ($c == '\\') { $localName .= $this->readLocalEscapedChar(); } else { $localName .= $c; } $c = $this->read(); } } // Unread last character $this->unread($c); // Note: namespace has already been resolved return array('type' => 'uri', 'value' => $namespace . $localName); }
/** * Adds missing prefix-definitions to the query * * Overriding classes may execute arbitrary query-alteration here * * @param string $query * @return string */ protected function preprocessQuery($query) { // Check for undefined prefixes $prefixes = ''; foreach (RdfNamespace::namespaces() as $prefix => $uri) { if (strpos($query, "{$prefix}:") !== false and strpos($query, "PREFIX {$prefix}:") === false) { $prefixes .= "PREFIX {$prefix}: <{$uri}>\n"; } } return $prefixes . $query; }
protected function open() { \EasyRdf\RdfNamespace::set('locn', 'http://www.w3.org/ns/locn#'); $graph = Graph::newAndLoad($this->extractor->uri, $this->extractor->format); $this->datasets = $graph->allOfType('dcat:Dataset'); }
public function subscribe($agentURI, $digestSubscriptionURI, $period) { $index = 1; $query = <<<INSERT <{$agentURI}> tal:subscriptionApplied _:b{$index} . _:b{$index} tal:subscriptionType <{$digestSubscriptionURI}> . _:b{$index} tal:subscriptionPeriod {$period} . INSERT; $graphIRI = 'tal:SubscriptionGraph'; $graphURI = RdfNamespace::expand($graphIRI); echo $query; try { $this->endpoint->insert($query, $graphURI); } catch (\EasyRdf\Http\Exception $e) { echo $e->getBody(); } }
/** * If a types resource has changed and the new type is mapped to another document type, then the old document is removed * @param $uri * @param $types * @param $oldType * @return bool */ protected function deleteOldDocument($uri, $types, $oldType) { $newTypes = array(); foreach ($types as $type) { $type = (string) $type; if ($type && !empty($type)) { $newTypes[] = RdfNamespace::shorten($type); } } // Get most accurtype of oldtype $mostAccurateTypes = $this->filiationBuilder->getMostAccurateType(array(RdfNamespace::expand($oldType)), $this->serializerHelper->getAllTypes()); $mostAccurateType = null; // not specified in project ontology description if (count($mostAccurateTypes) == 1) { $mostAccurateType = $mostAccurateTypes[0]; } else { // echo "Seems to not have to be indexed"; } if (!in_array($mostAccurateType, $newTypes)) { $typesConfig = $this->configManager->getTypesConfigurationByClass($mostAccurateType); foreach ($typesConfig as $typeConfig) { $indexConfig = $typeConfig->getIndex(); $index = $indexConfig->getName(); $this->container->get('nemrod.elastica.jsonld.frame.loader')->setEsIndex($index); if ($index !== null) { $esType = $this->indexRegistry->getIndex($index)->getType($typeConfig->getType()); // Trow an exeption if document does not exist try { $esType->deleteDocument(new Document($uri, array(), $mostAccurateType, $indexConfig->getElasticSearchName())); return true; } catch (\Exception $e) { } } } } return false; }
protected function expandCurie($node, &$context, $value) { if (preg_match('/^(\\w*?):(.*)$/', $value, $matches)) { list(, $prefix, $local) = $matches; $prefix = strtolower($prefix); if ($prefix === '_') { // It is a bnode return $this->remapBnode(substr($value, 2)); } elseif (empty($prefix) and $context['vocab']) { // Empty prefix return $context['vocab'] . $local; } elseif (isset($context['prefixes'][$prefix])) { return $context['prefixes'][$prefix] . $local; } elseif ($uri = $node->lookupNamespaceURI($prefix)) { return $uri . $local; } elseif (!empty($prefix) and $uri = RdfNamespace::get($prefix)) { // Expand using well-known prefixes return $uri . $local; } } }
/** * @param $shortUri * * @return string */ public function expand($shortUri) { return RdfNamespace::expand($shortUri); }
/** * Method to serialise an EasyRdf\Graph to RDF/XML * * @param Graph $graph An EasyRdf\Graph object. * @param string $format The name of the format to convert to. * @param array $options * * @return string The RDF in the new desired format. * @throws Exception */ public function serialise(Graph $graph, $format, array $options = array()) { parent::checkSerialiseParams($format); if ($format != 'rdfxml') { throw new Exception("EasyRdf\\Serialiser\\RdfXml does not support: {$format}"); } // store of namespaces to be appended to the rdf:RDF tag $this->prefixes = array('rdf' => true); // store of the resource URIs we have serialised $this->outputtedResources = array(); $xml = ''; // Serialise URIs first foreach ($graph->resources() as $resource) { if (!$resource->isBnode()) { $xml .= $this->rdfxmlResource($resource, true); } } // Serialise bnodes afterwards foreach ($graph->resources() as $resource) { if ($resource->isBnode()) { $xml .= $this->rdfxmlResource($resource, true); } } // iterate through namepsaces array prefix and output a string. $namespaceStr = ''; foreach ($this->prefixes as $prefix => $count) { $url = RdfNamespace::get($prefix); if (strlen($namespaceStr)) { $namespaceStr .= "\n "; } if (strlen($prefix) === 0) { $namespaceStr .= ' xmlns="' . htmlspecialchars($url) . '"'; } else { $namespaceStr .= ' xmlns:' . $prefix . '="' . htmlspecialchars($url) . '"'; } } return "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" . "<rdf:RDF" . $namespaceStr . ">\n" . $xml . "\n</rdf:RDF>\n"; }
/** * Internal function to serialise an EasyRdf\Graph into a DOT formatted string * * @ignore */ protected function serialiseDot(Graph $graph) { $result = "digraph {\n"; // Write the graph attributes foreach ($this->attributes as $k => $v) { $result .= ' ' . $this->escape($k) . '=' . $this->escape($v) . ";\n"; } // Go through each of the properties and write the edges $nodes = array(); $result .= "\n // Edges\n"; foreach ($graph->resources() as $resource) { $name1 = $this->nodeName($resource); foreach ($resource->propertyUris() as $property) { $label = null; if ($this->useLabels) { $label = $graph->resource($property)->label(); } if ($label === null) { if ($this->onlyLabelled == true) { continue; } else { $label = RdfNamespace::shorten($property); } } foreach ($resource->all("<{$property}>") as $value) { $name2 = $this->nodeName($value); $nodes[$name1] = $resource; $nodes[$name2] = $value; $result .= $this->serialiseRow($name1, $name2, array('label' => $label)); } } } ksort($nodes); $result .= "\n // Nodes\n"; foreach ($nodes as $name => $node) { $type = substr($name, 0, 1); $label = ''; if ($type == 'R') { if ($this->useLabels) { $label = $node->label(); } if (!$label) { $label = $node->shorten(); } if (!$label) { $label = $node->getURI(); } $result .= $this->serialiseRow($name, null, array('URL' => $node->getURI(), 'label' => $label, 'shape' => 'ellipse', 'color' => 'blue')); } elseif ($type == 'B') { if ($this->useLabels) { $label = $node->label(); } $result .= $this->serialiseRow($name, null, array('label' => $label, 'shape' => 'circle', 'color' => 'green')); } else { $result .= $this->serialiseRow($name, null, array('label' => strval($node), 'shape' => 'record')); } } $result .= "}\n"; return $result; }