1<?php 2/** 3* 4*@package phpSesame 5*/ 6 7require_once "HTTP/Request2.php";//The PEAR base directory must be in your include_path 8 9require_once "resultFormats.php"; 10 11/** 12 * This Class is an interface to Sesame. It connects and perform queries through http. 13 * 14 * This class requires Sesame running in a servlet container (tested on tomcat). 15 * The class does not perform all the operation implemented in the sesame http api but 16 * does the minimal work needed for hyperJournal. You can find more details about Sesame 17 * and its HTTP API at www.openrdf.orguery('SELECT ?value W... 18 * 19 * Based on the phesame library, http://www.hjournal.org/phesame/ 20 * 21 * @author Alex Latchford 22 * @version 0.1 23 */ 24class phpSesame 25{ 26 // Return MIME types 27 const SPARQL_XML = 'application/sparql-results+xml'; 28 const SPARQL_JSON = 'application/sparql-results+json'; // Unsupported - No results handler 29 const BINARY_TABLE = 'application/x-binary-rdf-results-table'; // Unsupported - No results handler 30 const BOOLEAN = 'text/boolean'; // Unsupported - No results handler 31 32 // Input MIME Types 33 const RDFXML = 'application/rdf+xml'; 34 const NTRIPLES = 'text/plain'; 35 const TURTLE = 'application/x-turtle'; 36 const N3 = 'text/rdf+n3'; 37 const TRIX = 'application/trix'; 38 const TRIG = 'application/x-trig'; 39 40 //const RDFTRANSACTION = 'application/x-rdftransaction'; // Unsupported, needs more documentation (http://www.franz.com/agraph/allegrograph/doc/http-protocol.html#header3-67) 41 42 /** 43 * @var string connection string 44 */ 45 private $dsn; 46 /** 47 * @var string the selected repository 48 */ 49 private $repository; 50 51 /** 52 * 53 * 54 * @param string $sesameUrl Sesame server connection string 55 * @param string $repository The repository name 56 */ 57 function __construct($sesameUrl = 'http://localhost:8080/openrdf-sesame', $repository = null) 58 { 59 $this->dsn = $sesameUrl; 60 $this->setRepository($repository); 61 } 62 63 /** 64 * Selects a repository to work on 65 * 66 * @return void 67 * @param string $rep The repository name 68 */ 69 public function setRepository($rep) 70 { 71 $this->repository = $rep; 72 } 73 74 /** 75 * Gets a list of all the available repositories on the Sesame installation 76 * 77 * @return phpSesame_SparqlRes 78 */ 79 public function listRepositories() 80 { 81 $request =& new HTTP_Request2($this->dsn . '/repositories', HTTP_Request2::METHOD_GET); 82 $request->setHeader('Accept: ' . self::SPARQL_XML); 83 84 $response = $request->send(); 85 if($response->getStatus() != 200) 86 { 87 throw new Exception ('Phesame engine response error'); 88 } 89 90 return new phpSesame_SparqlRes($response->getBody()); 91 } 92 93 private function checkRepository() 94 { 95 if (empty($this->repository) || $this->repository == '') 96 { 97 throw new Exception ('No repository has been selected.'); 98 } 99 } 100 101 private function checkQueryLang($queryLang) 102 { 103 if ($queryLang != 'sparql' && $queryLang != 'serql') 104 { 105 throw new Exception ('Please supply a valid query language, SPARQL or SeRQL supported.'); 106 } 107 } 108 109 /** 110 * @todo Add in the other potentially supported formats once handlers have been written. 111 * 112 * @param string $format 113 */ 114 private function checkResultFormat($format) 115 { 116 if ($format != self::SPARQL_XML) 117 { 118 throw new Exception ('Please supply a valid result format.'); 119 } 120 } 121 122 /** 123 * 124 * 125 * @param string &$context 126 */ 127 private function checkContext(&$context) 128 { 129 if($context != 'null') 130 { 131 $context = (substr($context, 0, 1) != '<' || substr($context, strlen($context) - 1, 1) != '>') ? "<$context>" : $context; 132 $context = urlencode($context); 133 } 134 } 135 136 private function checkInputFormat($format) 137 { 138 if ($format != self::RDFXML && $format != self::N3 && $format != self::NTRIPLES 139 && $format != self::TRIG && $format != self::TRIX && $format != self::TURTLE) 140 { 141 throw new Exception ('Please supply a valid input format.'); 142 } 143 } 144 145 /** 146 * Performs a simple Query. 147 * 148 * Performs a query and returns the result in the selected format. Throws an 149 * exception if the query returns an error. 150 * 151 * @param string $query String used for query 152 * @param string $resultFormat Returned result format, see const definitions for supported list. 153 * @param string $queryLang Language used for querying, SPARQL and SeRQL supported 154 * @param bool $infer Use inference in the query 155 * 156 * @return phpSesame_SparqlRes 157 */ 158 public function query($query, $resultFormat = self::SPARQL_XML, $queryLang = 'sparql', $infer = true) 159 { 160// msg("running query: ".$query); 161 $this->checkRepository(); 162 $this->checkQueryLang($queryLang); 163 $this->checkResultFormat($resultFormat); 164 165 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository, HTTP_Request2::METHOD_POST); 166 $request->setHeader('Accept: ' . self::SPARQL_XML); 167 $request->addPostParameter('query', $query); 168 $request->addPostParameter('queryLn', $queryLang); 169 $request->addPostParameter('infer', $infer); 170 171 $response = $request->send(); 172 if($response->getStatus() != 200) 173 { 174 throw new Exception ('Failed to run query, HTTP response error: ' . $response->getStatus()); 175 } 176 177 return new phpSesame_SparqlRes($response->getBody()); 178 } 179 180 181 /** 182 * Performs a simple Update. 183 * 184 * Performs a query and returns the result in the selected format. Throws an 185 * exception if the query returns an error. Copied from query, possibly superfluous parameters 186 * 187 * @param string $query String used for query 188 * @param string $resultFormat Returned result format, see const definitions for supported list. 189 * @param string $queryLang Language used for querying, SPARQL and SeRQL supported 190 * @param bool $infer Use inference in the query 191 * 192 * @return phpSesame_SparqlRes 193 */ 194 public function update($query, $resultFormat = self::SPARQL_XML, $queryLang = 'sparql', $infer = true) 195 { 196// msg("running query: ".$query); 197 $this->checkRepository(); 198 $this->checkQueryLang($queryLang); 199 $this->checkResultFormat($resultFormat); 200 201 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/statements', HTTP_Request2::METHOD_POST); 202 $request->setHeader('Accept: ' . self::SPARQL_XML); 203 $request->addPostParameter('update', $query); 204 $request->addPostParameter('queryLn', $queryLang); 205 $request->addPostParameter('infer', $infer); 206 207 $response = $request->send(); 208 if($response->getStatus() != 204) 209 { 210 throw new Exception ('Failed to run query, HTTP response error: ' . $response->getStatus()); 211 } 212 213 //return new phpSesame_SparqlRes($response->getBody()); 214 } 215 216 /** 217 * Appends data to the selected repository 218 * 219 * 220 * 221 * @param string $data Data in the supplied format 222 * @param string $context The context the query should be run against 223 * @param string $inputFormat See class const definitions for supported formats. 224 */ 225 public function append($data, $context = 'null', $inputFormat = self::RDFXML) 226 { 227 $this->checkRepository(); 228 $this->checkContext($context); 229 $this->checkInputFormat($inputFormat); 230 231 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/statements?context=' . $context, HTTP_Request2::METHOD_POST); 232 $request->setHeader('Content-type: ' . $inputFormat); 233 $request->setBody($data); 234 235 $response = $request->send(); 236 if($response->getStatus() != 204) 237 { 238 throw new Exception ('Failed to append data to the repository, HTTP response error: ' . $response->getStatus()); 239 } 240 } 241 242 /** 243 * Appends data to the selected repository 244 * 245 * 246 * 247 * @param string $filePath The filepath of data, can be a URL 248 * @param string $context The context the query should be run against 249 * @param string $inputFormat See class const definitions for supported formats. 250 */ 251 public function appendFile($filePath, $context = 'null', $inputFormat = self::RDFXML) 252 { 253 $data = $this->getFile($filePath); 254 $this->append($data, $context, $inputFormat); 255 } 256 257 /** 258 * Overwrites data in the selected repository, can optionally take a context parameter 259 * 260 * @param string $data Data in the supplied format 261 * @param string $context The context the query should be run against 262 * @param string $inputFormat See class const definitions for supported formats. 263 */ 264 public function overwrite($data, $context = 'null', $inputFormat = self::RDFXML) 265 { 266 $this->checkRepository(); 267 $this->checkContext($context); 268 $this->checkInputFormat($inputFormat); 269 270 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/statements?context=' . $context, HTTP_Request2::METHOD_PUT); 271 $request->setHeader('Content-type: ' . $inputFormat); 272 $request->setBody($data); 273 274 $response = $request->send(); 275 if($response->getStatus() != 204) 276 { 277 throw new Exception ('Failed to append data to the repository, HTTP response error: ' . $response->getStatus()); 278 } 279 } 280 281 /** 282 * Overwrites data in the selected repository, can optionally take a context parameter 283 * 284 * @param string $filePath The filepath of data, can be a URL 285 * @param string $context The context the query should be run against 286 * @param string $inputFormat See class const definitions for supported formats. 287 */ 288 public function overwriteFile($filePath, $context = 'null', $inputFormat = self::RDFXML) 289 { 290 $data = $this->getFile($filePath); 291 $this->overwrite($data, $context, $inputFormat); 292 } 293 294 /** 295 * @param string $filePath The filepath of data, can be a URL 296 * @return string 297 */ 298 private function getFile($filePath) 299 { 300 if(empty($filePath) || $filePath == '') 301 { 302 throw new Exception('Please supply a filepath.'); 303 } 304 305 return file_get_contents($filePath); 306 } 307 308 /** 309 * Gets the namespace URL for the supplied prefix 310 * 311 * @param string $prefix Data in the supplied format 312 * 313 * @return string The URL of the namespace 314 */ 315 public function getNS($prefix) 316 { 317 $this->checkRepository(); 318 319 if(empty($prefix)) 320 { 321 throw new Exception('Please supply a prefix.'); 322 } 323 324 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/namespaces/' . $prefix, HTTP_Request2::METHOD_GET); 325 $request->setHeader('Accept: text/plain'); 326 327 $response = $request->send(); 328 if($response->getStatus() != 200) 329 { 330 throw new Exception ('Failed to run query, HTTP response error: ' . $response->getStatus()); 331 } 332 333 return (string) $response->getBody(); 334 } 335 336 /** 337 * Sets the the namespace for the specified prefix 338 * 339 * @param string $prefix Data in the supplied format 340 * @param string $namespace The context the query should be run against 341 */ 342 public function setNS($prefix, $namespace) 343 { 344 $this->checkRepository(); 345 346 if(empty($prefix) || empty($namespace)) 347 { 348 throw new Exception('Please supply both a prefix and a namesapce.'); 349 } 350 351 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/namespaces/' . $prefix, HTTP_Request2::METHOD_PUT); 352 $request->setHeader('Content-type: text/plain'); 353 $request->setBody($namespace); 354 355 $response = $request->send(); 356 if($response->getStatus() != 204) 357 { 358 throw new Exception ('Failed to set the namespace, HTTP response error: ' . $response->getStatus()); 359 } 360 } 361 362 /** 363 * Deletes the the namespace for the specified prefix 364 * 365 * @param string $prefix Data in the supplied format 366 */ 367 public function deleteNS($prefix) 368 { 369 $this->checkRepository(); 370 371 if(empty($prefix)) 372 { 373 throw new Exception('Please supply a prefix.'); 374 } 375 376 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/namespaces/' . $prefix, HTTP_Request2::METHOD_DELETE); 377 378 $response = $request->send(); 379 if($response->getStatus() != 204) 380 { 381 throw new Exception ('Failed to delete the namespace, HTTP response error: ' . $response->getStatus()); 382 } 383 } 384 385 /** 386 * Returns a list of all the contexts in the repository. 387 * 388 * @param string $resultFormat Returned result format, see const definitions for supported list. 389 * 390 * @return phpSesame_SparqlRes 391 */ 392 public function contexts($resultFormat = self::SPARQL_XML) 393 { 394 $this->checkRepository(); 395 $this->checkResultFormat($resultFormat); 396 397 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/contexts', HTTP_Request2::METHOD_POST); 398 $request->setHeader('Accept: ' . self::SPARQL_XML); 399 400 $response = $request->send(); 401 if($response->getStatus() != 200) 402 { 403 throw new Exception ('Failed to run query, HTTP response error: ' . $response->getStatus()); 404 } 405 406 return new phpSesame_SparqlRes($response->getBody()); 407 } 408 409 /** 410 * Returns the size of the repository 411 * 412 * @param string $context The context the query should be run against 413 * 414 * @return int 415 */ 416 public function size($context = 'null') 417 { 418 $this->checkRepository(); 419 420 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/size?context=' . $context, HTTP_Request2::METHOD_POST); 421 $request->setHeader('Accept: text/plain'); 422 423 $response = $request->send(); 424 if($response->getStatus() != 200) 425 { 426 throw new Exception ('Failed to run query, HTTP response error: ' . $response->getStatus()); 427 } 428 429 return (int) $response->getBody(); 430 } 431 432 /** 433 * Clears the repository 434 * 435 * Removes all data from the selected repository from ALL contexts. 436 * 437 * @return void 438 */ 439 public function clear() 440 { 441 $this->checkRepository(); 442 443 $request =& new HTTP_Request2($this->dsn . '/repositories/' . $this->repository . '/statements', HTTP_Request2::METHOD_DELETE); 444 445 $response = $request->send(); 446 if($response->getStatus() != 204) 447 { 448 throw new Exception ('Failed to clear repository, HTTP response error: ' . $response->getStatus()); 449 } 450 } 451} 452?> 453