blob: c4760802997e14baf16a202b4b414e098e8b2ea4 [file] [log] [blame]
<?php
/**
* File containing the ezcReflectionArrayType class.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Reflection
* @version //autogen//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
* Provides type information of the array item type or map types
*
* @package Reflection
* @version //autogen//
* @author Stefan Marr <mail@stefan-marr.de>
* @author Falko Menge <mail@falko-menge.de>
* @todo add support for ArrayAccess stuff from http://www.php.net/~helly/php/ext/spl/
*/
class ezcReflectionArrayType extends ezcReflectionPrimitiveType {
/**#@+
* @var ezcReflectionType
*/
// protected $arrayType;
// protected $mapKeyType;
// protected $mapValueType;
protected $keyType;
protected $valueType;
/**#@-*/
/**#@+
* @var boolean
*/
protected $isList = false;
/**#@-*/
/**
* @param string $typeName
*/
public function __construct($typeName)
{
parent::__construct($typeName);
$this->_parseTypeName();
}
/**
* Returns true if this array has been documented as a list, i.e., using
* the notation of any type name followed by a pair of square brakets.
*
* Examples of list types include mixed[], stdClass[], sting[][], or
* array(mixed=>mixed)[].
*
* @return boolean True this array has been documented as a list.
*/
public function isList ()
{
return $this->isList;
}
/**
* Returns key type of the array
*
* @return ezcReflectionType
*/
public function getKeyType()
{
return $this->keyType;
}
/**
* Returns value type of the array
*
* @return ezcReflectionType
*/
public function getValueType()
{
return $this->valueType;
}
/**
* @return boolean
*/
public function isArray()
{
return true;
}
/**
* Returns wether this array is documented as 'array(mixed=>mixed)' or
* simply 'array'.
*
* @return boolean
*/
public function isMap()
{
return !$this->isList();
}
/**
* Internal method for parsing array type names.
*
* @return void
*/
protected function _parseTypeName()
{
//*
if ( strlen( $this->typeName ) > 0 )
{
// last two chars are [], thus it should be something like string[]
//if ( strlen( $this->typeName ) > 2 and substr( $this->typeName, -2 ) == '[]' )
if ( preg_match( ezcReflectionTypeMapper::REGEXP_TYPE_NAME_LIST, $this->typeName, $matches ) )
{
$this->isList = true;
$this->isMap = false;
$this->keyType
= ezcReflection::getTypeByName( ezcReflectionTypeMapper::CANONICAL_NAME_INTEGER );
$this->valueType
= ezcReflection::getTypeByName( $matches[1] );
}
// may be the author just wrote 'array'
elseif ( $this->typeName == ezcReflectionTypeMapper::CANONICAL_NAME_ARRAY )
{
$this->isList = false;
$this->isMap = true;
$this->keyType
= ezcReflection::getTypeByName( ezcReflectionTypeMapper::CANONICAL_NAME_MIXED );
$this->valueType
= ezcReflection::getTypeByName( ezcReflectionTypeMapper::CANONICAL_NAME_MIXED );
}
// test for array map types array(int=>float)
elseif ( preg_match( ezcReflectionTypeMapper::REGEXP_TYPE_NAME_MAP, $this->typeName, $matches ) )
{
$this->isList = false;
$this->isMap = true;
$this->keyType
= ezcReflection::getTypeByName( $matches[1] );
$this->valueType
= ezcReflection::getTypeByName( $matches[2] );
}
}
/*/
$seamsToBeMap = false;
$pos = strrpos($this->typeName, '[');
//there seams to be an array
if ($pos !== false) {
//proof there is no array map annotation around
$posm = strrpos($this->typeName, ')');
if ($posm !== false) {
if ($posm < $pos) {
$typeName = substr($this->typeName, 0, $pos);
$this->arrayType
= ezcReflection::getTypeByName($typeName);
}
}
else {
$typeName = substr($this->typeName, 0, $pos);
$this->arrayType
= ezcReflection::getTypeByName($typeName);
}
}
// TO BE DONE: add support for array(integer => mixed)
if (preg_match(self::TYPE_NAME_REGEXP, $this->typeName, $matches)) {
$type1 = null;
$type2 = null;
if (isset($matches[3])) {
$type1 = ezcReflection::getTypeByName($matches[3]);
}
if (isset($matches[5])) {
$type2 = ezcReflection::getTypeByName($matches[5]);
}
if ($type1 == null and $type2 != null) {
$this->arrayType = $type2;
}
elseif ($type1 != null and $type2 == null) {
$this->arrayType = $type1;
}
elseif ($type1 != null and $type2 != null) {
$this->mapKeyType = $type1;
$this->mapValueType = $type2;
}
}
//*/
}
/**
* Returns the canonical name for this array, which can be used in type
* annotations.
*
* @return string Canonical name for this array
*/
public function getTypeName()
{
if ( $this->isList() )
{
return $this->getValueType()->getTypeName().'[]';
}
else
{
return 'array(' . $this->getKeyType()->getTypeName()
. '=>' . $this->getValueType()->getTypeName() . ')';
}
}
/**
* Returns XML Schema name of the complexType for the array
*
* The `this namespace' (tns) prefix is comonly used to refer to the
* current XML Schema document.
*
* @param boolean $usePrefix augments common prefix `tns:' to the name
* @return string
*/
function getXmlName( $usePrefix = true )
{
if ( $usePrefix ) {
$prefix = 'tns:';
} else {
$prefix = '';
}
if ( $this->isList() )
{
return $prefix . 'ArrayOf' . $this->getValueType()->getXmlName( false );
}
else
{
throw new Exception( 'XML Schema mapping is not supported for map-types' );
}
}
/**
* @return string
*/
function getNamespace() {
return '';
}
/**
* Returns an <xsd:complexType/>
*
* @example
* <xs:complexType name="ArrayOfLecture">
* <xs:sequence>
* <xs:element minOccurs="0" maxOccurs="unbounded"
* name="Lecture" nillable="true" type="tns:Lecture" />
* </xs:sequence>
* </xs:complexType>
*
* @param DOMDocument $dom
* @return DOMElement
*/
function getXmlSchema(DOMDocument $dom, $namespaceXMLSchema = 'http://www.w3.org/2001/XMLSchema') {
if ( !$this->isList() )
{
throw new Exception('XML Schema mapping is not supported for map-types');
}
$schema = $dom->createElementNS($namespaceXMLSchema, 'xsd:complexType');
$schema->setAttribute('name', $this->getXmlName(false));
$seq = $dom->createElementNS($namespaceXMLSchema, 'xsd:sequence');
$schema->appendChild($seq);
$elm = $dom->createElementNS($namespaceXMLSchema, 'xsd:element');
$seq->appendChild($elm);
$elm->setAttribute('minOccurs', '0');
$elm->setAttribute('maxOccurs', 'unbounded');
$elm->setAttribute('nillable', 'true');
$elm->setAttribute( 'name', $this->getValueType()->getXmlName( false ) );
$elm->setAttribute( 'type', $this->getValueType()->getXmlName( true ) );
return $schema;
}
}
?>