8 * Copyright (c) 2013 Nicholas J Humfrey. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
18 * promote products derived from this software without specific prior
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 * @copyright Copyright (c) 2013 Nicholas J Humfrey
35 * @license http://www.opensource.org/licenses/bsd-license.php
39 * Sub-class of EasyRdf_Resource that represents an RDF container
40 * (rdf:Alt, rdf:Bag and rdf:Seq)
42 * This class can be used to iterate through a list of items.
45 * @link http://www.w3.org/TR/xmlschema-2/#date
46 * @copyright Copyright (c) 2013 Nicholas J Humfrey
47 * @license http://www.opensource.org/licenses/bsd-license.php
49 class EasyRdf_Container extends EasyRdf_Resource implements ArrayAccess, Countable, SeekableIterator
53 /** Create a new container - do not use this directly
57 public function __construct($uri, $graph)
60 parent::__construct($uri, $graph);
63 /** Seek to a specific position in the container
65 * The first item is postion 1
67 * @param integer $position The position in the container to seek to
68 * @throws OutOfBoundsException
70 public function seek($position)
72 if (is_int($position) and $position > 0) {
73 if ($this->hasProperty('rdf:_'.$position)) {
74 $this->position = $position;
76 throw new OutOfBoundsException(
77 "Unable to seek to position $position in the container"
81 throw new InvalidArgumentException(
82 "Container position must be a positive integer"
87 /** Rewind the iterator back to the start of the container (item 1)
90 public function rewind()
95 /** Return the current item in the container
97 * @return mixed The current item
99 public function current()
101 return $this->get('rdf:_'.$this->position);
104 /** Return the key / current position in the container
106 * @return int The current position
108 public function key()
110 return $this->position;
113 /** Move forward to next item in the container
116 public function next()
121 /** Checks if current position is valid
123 * @return bool True if the current position is valid
125 public function valid()
127 return $this->hasProperty('rdf:_'.$this->position);
130 /** Counts the number of items in the container
132 * Note that this is an slow method - it is more efficient to use
133 * the iterator interface, if you can.
135 * @return integer The number of items in the container
137 public function count()
140 while ($this->hasProperty('rdf:_'.$pos)) {
146 /** Append an item to the end of the container
148 * @param mixed $value The value to append
149 * @return integer The number of values appended (1 or 0)
151 public function append($value)
153 // Find the end of the list
155 while ($this->hasProperty('rdf:_'.$pos)) {
160 return $this->add('rdf:_'.$pos, $value);
163 /** Array Access: check if a position exists in container using array syntax
165 * Example: isset($seq[2])
167 public function offsetExists($offset)
169 if (is_int($offset) and $offset > 0) {
170 return $this->hasProperty('rdf:_'.$offset);
172 throw new InvalidArgumentException(
173 "Container position must be a positive integer"
178 /** Array Access: get an item at a specified position in container using array syntax
180 * Example: $item = $seq[2];
182 public function offsetGet($offset)
184 if (is_int($offset) and $offset > 0) {
185 return $this->get('rdf:_'.$offset);
187 throw new InvalidArgumentException(
188 "Container position must be a positive integer"
194 * Array Access: set an item at a positon in container using array syntax
196 * Example: $seq[2] = $item;
198 * Warning: creating gaps in the sequence will result in unexpected behavior
200 public function offsetSet($offset, $value)
202 if (is_int($offset) and $offset > 0) {
203 return $this->set('rdf:_'.$offset, $value);
204 } elseif (is_null($offset)) {
205 return $this->append($value);
207 throw new InvalidArgumentException(
208 "Container position must be a positive integer"
214 * Array Access: delete an item at a specific postion using array syntax
216 * Example: unset($seq[2]);
218 * Warning: creating gaps in the sequence will result in unexpected behavior
220 public function offsetUnset($offset)
222 if (is_int($offset) and $offset > 0) {
223 return $this->delete('rdf:_'.$offset);
225 throw new InvalidArgumentException(
226 "Container position must be a positive integer"