server/src/app/Http/Controllers/Sparql/SparqlClientController.php
changeset 386 c731ab9b934d
child 387 7fba86fa8604
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/app/Http/Controllers/Sparql/SparqlClientController.php	Mon Oct 31 14:24:23 2016 +0100
@@ -0,0 +1,215 @@
+<?php
+
+namespace CorpusParole\Http\Controllers\Sparql;
+
+use Log;
+
+use Illuminate\Http\Request;
+use GuzzleHttp\Client;
+use EasyRdf\Sparql\Result as SparqlResult;
+use EasyRdf\Graph;
+use EasyRdf\RdfNamespace;
+
+use CorpusParole\Http\Controllers\Controller;
+use CorpusParole\Libraries\Utils;
+
+use CorpusParole\Libraries\Sparql\SparqlClient;
+use CorpusParole\Libraries\Sparql\SparqlQueryAnalyser;
+use RdfHelper;
+
+class SparqlClientController extends Controller
+{
+
+    const HEADERS_FORWARDED = [ "host", "user-agent", "accept", "accept-language", "accept-encoding", "connection" ];
+
+    const SELECT_RESULT_FORMAT = [
+        "SPARQL/CSV" => "text/csv",
+        "SPARQL/JSON" => "application/sparql-results+json",
+        "SPARQL/XML" => "application/sparql-results+xml",
+        "SPARQL/TSV" => "text/tab-separated-values",
+        "BINARY" => "application/x-binary-rdf-results-table"
+    ];
+
+    const GRAPH_RESULT_FORMAT = [
+        "N-Triples" => "application/n-triples",
+        "RDF/XML" => "application/rdf+xml",
+        "Turtle" => "text/turtle",
+        "N3" => "text/n3",
+        "RDF/JSON" => "application/rdf+json",
+        "TriG" => "application/trig",
+        "N-Quads" => "application/n-quads",
+        "BinaryRDF" => "application/x-binary-rdf",
+        "TriX" => "application/trix",
+        "JSON-LD" => "application/ld+json"
+    ];
+
+
+    private $sparqlClient;
+    private $httpClient;
+
+    public function __construct(SparqlClient $sparqlClient, Client $httpClient) {
+        $this->sparqlClient = $sparqlClient;
+        $this->httpClient = $httpClient;
+    }
+
+    // display form
+    public function index() {
+        return view('sparql/sparqlClientForm');
+    }
+
+    private function querySelect(Request $request, $query, $analyser) {
+        $countResult = $this->sparqlClient->query($analyser->getCountQuery());
+        $countField = $countResult->getFields()[0];
+        $count = $countResult->current()->$countField;
+        $docs = $this->sparqlClient->query($query);
+        $fields = $docs->getFields();
+        $results = [];
+        foreach($docs as $row) {
+            $results[] = array_reduce($fields, function($res, $field) use ($row) {
+                if(isset($row->$field)) {
+                    $res[$field] = RdfHelper::serialiseValue($row->$field);
+                } else {
+                    $res[$field] = "<span class=\"corpus-rdf-blank-value\">&nbsp;</span>";
+                }
+                return $res;
+            }, []);
+        }
+        $namespaces = array_reduce(array_keys(RdfHelper::getPrefixes()), function($res, $p) {
+            $res[$p] = RdfNamespace::namespaces()[$p];
+            return $res;
+        }, []);
+        $data = [
+            'query' => $query,
+            'count' => $count,
+            'fields' => $fields,
+            'fieldPrefix' => "?",
+            'results' => $results,
+            'namespaces' => $namespaces,
+            'downloadFormats' => self::SELECT_RESULT_FORMAT
+        ];
+        $view = 'sparql/sparqlClientResultList';
+        return [$view, $data];
+    }
+
+    private function queryGraph(Request $request, $query, $analyser) {
+
+        $docs = $this->sparqlClient->query($query);
+        $fields = ["subject", "predicate", "object"];
+        $results = [];
+        foreach ($docs->resources() as $resource ) {
+            foreach ($resource->propertyUris() as $property) {
+                $propertyResource = $docs->resource($property);
+                foreach ($resource->all($propertyResource) as $value) {
+                    $results[] = [
+                        'subject' => RdfHelper::serialiseValue($resource),
+                        'predicate'=> RdfHelper::serialiseValue($propertyResource),
+                        'object'=> RdfHelper::serialiseValue($value)
+                    ];
+                }
+            }
+        }
+        $namespaces = array_reduce(array_keys(RdfHelper::getPrefixes()), function($res, $p) {
+            $res[$p] = RdfNamespace::namespaces()[$p];
+            return $res;
+        }, []);
+
+
+        $data = [
+            'query' => $query,
+            'count' => count($results),
+            'fields' => $fields,
+            'fieldPrefix' => "",
+            'results' => $results,
+            'namespaces' => $namespaces,
+            'downloadFormats' => self::GRAPH_RESULT_FORMAT
+        ];
+        $view = 'sparql/sparqlClientResultList';
+
+        return [$view, $data];
+    }
+
+    private function queryAsk(Request $request, $query, $analyser) {
+        $data = [
+            'results' => $this->sparqlClient->query($query),
+            'namespaces' => $analyser->getPrefixes()
+        ];
+
+        $view = 'sparql/sparqlClientResultBoolean';
+        return [$view, $data];
+    }
+
+    private function showHtml(Request $request) {
+
+        $query = $request->input('query');
+
+        $analyser = new SparqlQueryAnalyser($query);
+
+        $queryType = $analyser->getQueryType();
+
+        $namespaces = $analyser->getPrefixes();
+
+        foreach($namespaces as $prefix => $nUri) {
+            RdfNamespace::set($prefix,$nUri);
+        }
+
+        if($queryType === SparqlQueryAnalyser::SELECT_QUERY) {
+            list($view, $data) = $this->querySelect($request, $query, $analyser);
+        } elseif($queryType === SparqlQueryAnalyser::GRAPH_QUERY) {
+            list($view, $data) = $this->queryGraph($request, $query, $analyser);
+        } elseif($queryType === SparqlQueryAnalyser::ASK_QUERY) {
+            list($view, $data) = $this->queryAsk($request, $query, $analyser);
+        } else {
+            //return 500
+            abort(500, "Serialization format unknown");
+        }
+
+        return view($view, $data);
+
+    }
+
+
+    private function proxyQuery(Request $request, $format=null) {
+        $query = $request->input('query');
+        $headers = [];
+        foreach (self::HEADERS_FORWARDED as $h) {
+            $headerValue = $request->header($h);
+            if($headerValue) {
+                $headers[$h] = $headerValue;
+            }
+        }
+
+        if(!empty($format)){
+            $headers['Accept'] = $format;
+        }
+
+        $sesameResp = $this->httpClient->get(config('corpusparole.sesame_query_url'), ['query' => $request->all(), 'headers' => $headers]);
+
+        $resp = response((string)$sesameResp->getBody(), $sesameResp->getStatusCode());
+        foreach ($sesameResp->getHeaders() as $name => $values) {
+            if($name != 'Transfer-Encoding') {
+                $resp->header($name, $values);
+            }
+        }
+
+        return $resp;
+    }
+
+    // display result
+    public function show(Request $request) {
+
+        $format = $request->input('format');
+
+        if($format === 'text/html') {
+            return $this->showHtml($request);
+        } else {
+            return $this->proxyQuery($request, $format);
+        }
+
+    }
+
+    // do the query
+    public function query(Request $request) {
+        return $this->proxyQuery($request);
+    }
+
+}