* instance of get_called_class(): ILLI\Core\Std\Def\ADT* * instance of __CLASS__: ILLI\Core\Std\Def\ADT * * :adtDef * collection of defined __const_Type(s) * * @var array [{:hashAddr} => {:adtDef}] */ private static $__gc = []; /** * Instantiate a new Abstract Data Type. * * define ADT * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @throws ILLI\Core\Std\Exception\ArgumentLengthZeroException when definition is an empty array * @catchable ILLI\Core\Std\Def\ADT\ComponentInitializationException * @see ILLI\Core\Std\Def\__const_Type * @see ILLI\Core\Std\Def\ADTInstance * @see ILLI\Core\Std\Spl\Fsb */ public function __construct(array $__defineTypes = []) { try { if([] === $__defineTypes) throw new ComponentMethodCallException ( ComponentMethodCallException::CTOR_DEFINITION_LENGTH_ZERO, ['method' => __METHOD__], new ArgumentLengthZeroException ); $n = $this->createHashAddr($__defineTypes); $t = &self::$__gc[$n]; parent::setSize(1); parent::offsetSet(0, $n); if(FALSE === isset($t)) $t = Fsb::fromArray($this->parseDef($__defineTypes)); } catch(\Exception $E) { throw new ComponentInitializationException($E, ['class' => get_called_class()]); } } /** * value validation * * The type of given value equals with one of the registered gc-types * * @param mixed $__value * @return boolean * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_VALIDATE * @see ILLI\Core\Std\Def\__const_Type */ public function validate($__value) { try { $v = &$__value; $t = getType($v); foreach($this->getGC() as $h) { if($t === $h ||($t === __const_Type::SPL_OBJECT && (class_exists($h) || interface_exists($h)) && (is_subclass_of($v, $h) || $v instanceOf $h))) return TRUE; } return FALSE; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_VALIDATE, ['method' => __METHOD__]); } } /** * get ADT-gc hash address * * @return string * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_GET_NAME * @see ::$__gc */ public function getName() { try { return parent::offsetGet(0); } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_GET_NAME, ['method' => __METHOD__]); } } /** * get ADT-gc * * @return ILLI\Core\Std\Spl\Fsb * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_GET_GC * @see ::$__gc */ public function getGC() { try { return self::$__gc[$this->getName()]; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_GET_GC, ['method' => __METHOD__]); } } /** * join registered gc-type(s) * * @return ILLI\Core\Std\Spl\Fsb * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_TO_STRING * @see ::$__gc * @see ILLI\Core\Std\Def\__const_Type */ public function toString() { try { return implode('|', $this->getGC()->toArray()); } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_TO_STRING, ['method' => __METHOD__]); } } /** * generate gc-hash-address from called-class or from spl_object_hash * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_CREATE_HASH_ADDR * @return string * @see ::$__gc */ protected function createHashAddr(array $__defineTypes = []) { try { #~ performanced ADT: cache request by called-class; otherwise by hash return ($c = get_called_class()) === __CLASS__ ? Spl::nameWithHash($c, $this) : $c; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_CREATE_HASH_ADDR, ['method' => __METHOD__]); } } /** * validate typedef request * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @throws ILLI\Core\Std\Exception\ArgumentExpectedException when {:gcType} is not of type string * @throws ILLI\Core\Std\Exception\ArgumentLengthZeroException result-array is empty * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_PARSE_DEF_EXPECTED_STRING * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_PARSE_DEF_RESULT_LENGTH_ZERO * @catchable ILLI\Core\Std\Def\ADT\ComponentMethodCallException ComponentMethodCallException::ERROR_PARSE_DEF */ protected function parseDef(array $__defineTypes) { try { $r = []; foreach($__defineTypes as $k => $v) { if(FALSE === is_string($v)) throw new ComponentMethodCallException ( ComponentMethodCallException::ERROR_PARSE_DEF_EXPECTED_STRING, ['offset' => $k, 'class' => get_called_class()], new ArgumentExpectedException ([ 'target' => $this->getName().'['.$k.']', 'expected' => 'string', 'detected' => $t = getType($v), 'value' => is_object($v) ? get_class($v) : (is_scalar($v) ? $v : NULL) ]) ); $r[$k] = $v; } if([] === $r) throw new ComponentMethodCallException ( ComponentMethodCallException::ERROR_PARSE_DEF_RESULT_LENGTH_ZERO, ['method' => __METHOD__], new ArgumentLengthZeroException ); return $r; } catch(ComponentMethodCallException $E) { throw $E; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_PARSE_DEF, ['method' => __METHOD__]); } }