Skip to content

Commit

Permalink
Introduce Graph as a first step towards supporting named graphs in pa…
Browse files Browse the repository at this point in the history
…rsed documents

Furthermore, NodeInterface was created so that more specialized nodes can be created in custom implementations.

This addresses #15.
  • Loading branch information
lanthaler committed Feb 2, 2013
1 parent cf0b5bd commit f043ef0
Show file tree
Hide file tree
Showing 9 changed files with 769 additions and 382 deletions.
140 changes: 56 additions & 84 deletions Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,19 @@
class Document implements DocumentInterface
{
/**
* The base IRI
*
* @var IRI
* @var IRI The document's IRI
*/
private $baseIri = null;
private $iri = null;

/**
* An associative array holding all nodes in the graph
*
* @var array
* @var GraphInterface The default graph
*/
protected $nodes = array();
private $defaultGraph = null;

/**
* A term map containing terms/prefixes mapped to IRIs. This is similar
* to a JSON-LD context but ignores all definitions except the IRI.
*
* @var array
* @var array An associative array holding all named graphs in the document
*/
protected $termMap = array();

/**
* Blank node counter
*
* @var int
*/
private $blankNodeCounter = 0;
protected $namedGraphs = array();

/**
* Parses a JSON-LD document and returns it as a Document
Expand All @@ -60,8 +46,8 @@ class Document implements DocumentInterface
* $document = Document::load('document.jsonld');
* </code>
*
* <strong>Please note that currently all data is merged into one graph,
* named graphs are not supported yet!</strong>
* <strong>Please note that currently all data is merged into the
* default graph, named graphs are not supported yet!</strong>
*
* It is possible to configure the processing by setting the options
* parameter accordingly. Available options are:
Expand All @@ -87,116 +73,102 @@ public static function load($document, $options = null)
*/
public function __construct($iri = null)
{
$this->baseIri = new IRI($iri);
$this->iri = new IRI($iri);
$this->defaultGraph = new Graph($this);
}

/**
* {@inheritdoc}
*/
public function createNode($id = null)
public function setIri($iri)
{
if (!is_string($id) || ('_:' === substr($id, 0, 2))) {
$id = $this->createBlankNodeId();
$abs_id = $id;
} else {
$id = (string) $this->baseIri->resolve($id);
if (isset($this->nodes[$id])) {
return $this->nodes[$id];
}
}

return $this->nodes[$id] = new Node($this, $id);
$this->iri = new IRI($iri);
}

/**
* {@inheritdoc}
*/
public function removeNode(Node $node)
public function getIri($asObject = false)
{
if ($node->getDocument() === $this) {
$node->removeFromDocument();
}
return ($asObject) ? $this->iri : (string) $this->iri;
}

$id = $node->getId();
/**
* {@inheritdoc}
*/
public function createGraph($name)
{
$name = (string) $this->iri->resolve($name);

if (!$node->isBlankNode()) {
$id = (string) $this->baseIri->resolve($id);
if (isset($this->namedGraphs[$name])) {
return $this->namedGraphs[$name];
}

unset($this->nodes[$id]);
return $this->namedGraphs[$name] = new Graph($this, $name);
}

/**
* {@inheritdoc}
*/
public function getNodes()
public function getGraph($name = null)
{
return array_values($this->nodes);
if (null === $name) {
return $this->defaultGraph;
}

$name = (string) $this->iri->resolve($name);

return isset($this->namedGraphs[$name])
? $this->namedGraphs[$name]
: null;
}

/**
* {@inheritdoc}
*/
public function getNode($id)
public function getGraphNames()
{
if (!((strlen($id) >= 2) && ('_:' === substr($id, 0, 2)))) {
$id = (string) $this->baseIri->resolve($id);
}

return isset($this->nodes[$id])
? $this->nodes[$id]
: null;
return array_keys($this->namedGraphs);
}

/**
* {@inheritdoc}
*/
public function getNodesByType($type)
public function containsGraph($name)
{
if (is_string($type)) {
if (null === ($type = $this->getNode($type))) {
return array();
}
}
$name = (string) $this->iri->resolve($name);

return $type->getNodesWithThisType();
return isset($this->namedGraphs[$name]);
}

/**
* {@inheritdoc}
*/
public function contains($id)
public function removeGraph($graph = null)
{
$node = $id;
if (null === $graph) {
$this->defaultGraph = new Graph($this);

if ($node instanceof Node) {
$id = $node->getId();
return;
}

if ((null === $id) || !is_string($id)) {
return false;
}
$name = $graph;

if ((strlen($id) >= 2) && ('_:' === substr($id, 0, 2))) {
if (isset($this->nodes[$id]) && ($node === $this->nodes[$id])) {
return true;
if ($graph instanceof GraphInterface) {
foreach ($this->namedGraphs as $n => $g) {
if ($g === $graph) {
$name = $n;
break;
}
}

return false;
}

$id = (string) $this->baseIri->resolve($id);

return isset($this->nodes[$id]);
}
if (isset($this->namedGraphs[$name])) {
if ($this->namedGraphs[$name]->getDocument() === $this) {
$this->namedGraphs[$name]->removeFromDocument();
}

/**
* Create a new blank node identifier unique to the document.
*
* @return string The new blank node identifier.
*/
protected function createBlankNodeId()
{
return '_:b' . $this->blankNodeCounter++;
unset($this->namedGraphs[$name]);
}
}
}
76 changes: 37 additions & 39 deletions DocumentInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,69 +19,67 @@
interface DocumentInterface
{
/**
* Creates a new node which is linked to this document
* Set the document's IRI
*
* If a blank node identifier or an invalid ID is passed, the ID will be
* ignored and a new blank node identifier unique to the document is
* created for the node.
*
* If there exists already a node with the passed ID in the document,
* that node will be returned instead of creating a new one.
* @param string|IRI The IRI.
*/
public function setIri($iri);

/**
* Get the document's IRI
*
* @param null|string $id The ID of the node.
* @param boolean $asObject If set to true, the return value will be an
* {@link IRI} object; otherwise a string.
*
* @return Node The newly created node.
* @return string|IRI The document's IRI (might be empty).
*/
public function createNode($id = null);
public function getIri($asObject = false);

/**
* Removes a node from the document
* Creates a new graph which is linked to this document
*
* This will also eliminate all references to the node within the
* document.
* If there exists already a graph with the passed name in the document,
* that graph will be returned instead of creating a new one.
*
* @param Node $node The node to remove from the document.
* @param string|IRI $name The graph's name.
*
* @return GraphInterface The newly created graph.
*/
public function removeNode(Node $node);
public function createGraph($name);

/**
* Get all nodes
* Get a graph by name
*
* @param null|string $name The name of the graph to retrieve. If null
* is passed, the default will be returned.
*
* @return array[Node] Returns an array containing all nodes defined in
* the document.
* @return GraphInterface|null Returns the graph if found; null otherwise.
*/
public function getNodes();
public function getGraph($name = null);

/**
* Get a node by ID
* Get graph names
*
* @param string $id The ID of the node to retrieve.
*
* @return Node|null Returns the node if found; null otherwise.
* @return array[string] Returns the names of all graphs in the document.
*/
public function getNode($id);
public function getGraphNames();

/**
* Get nodes by type
* Check whether the document contains a graph with the specified name
*
* @param string|Node $type The type
* @param string $name The graph name.
*
* @return array[Node] Returns an array containing all nodes of the
* specified type in the document.
* @return bool Returns true if the document contains a graph with the
* specified name; false otherwise.
*/
public function getNodesByType($type);
public function containsGraph($name);

/**
* Check whether the document already contains a node with the
* specified ID
*
* @param string|Node $id The node ID to check. Blank node identifiers
* will always return false except a node instance
* which is part of the document will be passed
* instead of a string.
* Removes a graph from the document
*
* @return bool Returns true if the document contains a node with the
* specified ID; false otherwise.
* @param null|string|GraphInterface $graph The graph (or its name) to
* remove. If null is passed,
* the default will be reset.
*/
public function contains($id);
public function removeGraph($graph = null);
}
Loading

0 comments on commit f043ef0

Please sign in to comment.