5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 Hub Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class BaseList extends BaseHubSystem implements IteratorAggregate {
25 // Exception constants
26 const EXCEPTION_GROUP_ALREADY_ADDED = 0xf20;
27 const EXCEPTION_GROUP_NOT_FOUND = 0xf21;
32 private $listGroups = array();
37 private $listEntries = array();
42 private $listIndex = array();
45 * Protected constructor
47 * @param $className Name of the class
50 protected function __construct ($className) {
51 // Call parent constructor
52 parent::__construct($className);
54 // Remove some attributes
55 $this->removeNumberFormaters();
56 $this->removeSystemArray();
60 * Getter for iterator instance from this list
62 * @return $iteratorInstance An instance of a Iterator class
64 public function getIterator () {
65 // Prepare a default iterator
66 $iteratorInstance = ObjectFactory::createObjectByConfiguredName('default_iterator_class');
69 return $iteratorInstance;
73 * Checks wether the given group is set
75 * @param $groupName Group to check if found in list
76 * @return $isset Wether the group is valid
78 public function isGroupSet ($groupName) {
79 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName);
80 return isset($this->listGroups[$groupName]);
84 * Adds the given group or if already added issues a ListGroupAlreadyAddedException
86 * @param $groupName Group to add
88 * @throws ListGroupAlreadyAddedException If the given group is already added
90 public function addGroup ($groupName) {
91 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . ' - START');
92 // Is the group already added?
93 if ($this->isGroupSet($groupName)) {
94 // Throw the exception here
95 throw new ListGroupAlreadyAddedException(array($this, $groupName), self::EXCEPTION_GROUP_ALREADY_ADDED);
98 // Add the group which is a simple array
99 $this->listGroups[$groupName] = ObjectFactory::createObjectByConfiguredName('list_group_class');
100 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . ' - FINISHED');
104 * Adds the given instance to list group and sub group
106 * @param $groupName Group to add instance to
107 * @param $subGroup Sub group to add instance to
108 * @param $instance An instance of Visitable
110 * @throws NoListGroupException If the given group is not found
112 public function addInstance ($groupName, $subGroup, Visitable $instance) {
113 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . '/' . $subGroup . ' - START');
114 // Is the group there?
115 if (!$this->isGroupSet($groupName)) {
116 // Throw the exception here
117 throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
120 // Is the sub group there?
121 if (!$this->listGroups[$groupName]->isGroupSet($subGroup)) {
122 // Automatically add it
123 $this->listGroups[$groupName]->addGroup($subGroup);
127 $hash = $this->generateHash($groupName, $subGroup, $instance);
129 // Now add it to the group list and hash it
130 $this->listGroups[$groupName]->addEntry($subGroup, $hash);
132 // Add the hash to the index
133 $this->listIndex[] = $hash;
135 // Add the instance itself to the list
136 $this->listEntries[$hash] = $instance;
137 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . '/' . $subGroup . ' - START');
141 * Adds the given entry to list group
143 * @param $groupName Group to add instance to
144 * @param $entry An entry of any type
146 * @throws NoListGroupException If the given group is not found
148 public function addEntry ($groupName, $entry) {
149 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . ' - START');
150 // Is the group already added?
151 if (!$this->isGroupSet($groupName)) {
152 // Throw the exception here
153 throw new NoListGroupException(array($this, $groupName), self::EXCEPTION_GROUP_NOT_FOUND);
157 $hash = $this->generateHash($groupName, $groupName, $entry);
159 // Add the hash to the index
160 $this->listIndex[] = $hash;
162 // Now add the entry to the list
163 $this->listEntries[$hash] = $entry;
164 //* DEBUG: */ $this->debugOutput(__METHOD__.': '.$groupName . ' - FINISHED');
168 * Generates a hash from given group, sub group and entry
170 * @param $groupName Group to add instance to
171 * @param $subGroup Sub group to add instance to
172 * @param $entry An entry of any type
173 * @return $hash The generated
175 private function generateHash ($groupName, $subGroup, $entry) {
176 // Created entry, 'null' is default
179 // Determine type of entry
180 if (is_null($entry)) {
182 } elseif ($entry instanceof FrameworkInterface) {
183 // Own instance detected
184 $entry2 = $entry->hashCode();
185 } elseif (!is_array($entry)) {
186 // Non-array found, use it directly with type
187 $entry2 = gettype($entry) . ':' . $entry2;
189 // Arrays are unsupported at the momement
190 $this->debugOutut(__METHOD__ . ': entry is an array. UNSUPPORTED!');
192 // @TODO Extend this somehow?
193 $entry2 = gettype($entry);
196 // Construct string which we shall hash
197 $hashString = $groupName . ':' . $subGroup . ':' . $entry2;
199 // Hash it with fastest hasher
200 $hash = crc32($hashString);