Changeset 61

Show
Ignore:
Timestamp:
11/29/06 23:54:41 (2 years ago)
Author:
mikey
Message:

Reworked the dynamic type feature after discussion with schst: Introduced the AbstractTag? which enables to state the concrete type not within the defines but within the concrete xml configuration file. However the concrete type has to be an instance of the abstract type declared as attribute of the abstract tag.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/XJConf/DefinedTag.php

    r53 r61  
    77 */ 
    88XJConfLoader::load('Tag', 
    9                    'definitions.TagDefinition' 
     9                   'definitions.BaseTagDefinition' 
    1010); 
    1111/** 
     
    5555         * value of the tag 
    5656         * 
    57          * @var  TagDefinition 
     57         * @var  BaseTagDefinition 
    5858         */ 
    5959        private $tagDef = null; 
     
    265265    * Set the tag definition object used for this tag 
    266266    * 
    267     * @param  TagDefinition  $tagDef 
    268     * @todo   in case of dynamic types the original type should not get lost  
    269     *         but used to check if the dynamic type is as well an instance of 
    270     *         the original type >>> forcing interfaces/inheritance 
     267    * @param  BaseTagDefinition  $tagDef 
    271268    */ 
    272     public function setDefinition(TagDefinition $tagDef) 
    273     { 
    274         if ($this->hasAttribute('__type') == false) { 
    275             $this->tagDef = $tagDef; 
     269    public function setDefinition(BaseTagDefinition $tagDef) 
     270    { 
     271        if ($tagDef instanceof TagDefinition) { 
     272               $this->tagDef = $tagDef; 
    276273            return; 
    277274        } 
    278275         
    279         $clonedTagDef = clone $tagDef; 
    280         $this->tagDef = $clonedTagDef; 
    281         $this->tagDef->setType($this->getAttribute('__type')); 
     276        $this->tagDef = clone $tagDef; 
     277        $this->tagDef->setType($this->getAttribute($this->tagDef->getConcreteTypeAttributeName())); 
    282278    } 
    283279 
     
    285281     * get the tag definition object used for this tag 
    286282     * 
    287      * @return  TagDefinition 
     283     * @return  BaseTagDefinition 
    288284     */ 
    289285    public function getDefinition() 
  • trunk/XJConf/converters/AbstractObjectValueConverter.php

    r56 r61  
    2727     * Add all attributes using the appropriate setter methods 
    2828     * 
    29      * @param   Tag         $tag 
    30      * @param   Definition  $def 
    31      * @param   object      $instance 
     29     * @param   Tag                $tag 
     30     * @param   BaseTagDefinition  $def 
     31     * @param   object             $instance 
    3232     * @throws  ValueConversionException 
    3333     */ 
    34     protected function addAttributesToValue(Tag $tag, TagDefinition $def, $instance) 
     34    protected function addAttributesToValue(Tag $tag, BaseTagDefinition $def, $instance) 
    3535    { 
    3636        $class = new ReflectionClass(get_class($instance)); 
  • trunk/XJConf/converters/ArrayValueConverter.php

    r33 r61  
    77XJConfLoader::load('converters.ValueConverter', 
    88                   'definitions.Definition', 
    9                    'definitions.TagDefinition' 
     9                   'definitions.BaseTagDefinition' 
    1010); 
    1111/** 
     
    4848     * @param   array       $array 
    4949     */ 
    50     protected function addAttributesToValue(Tag $tag, TagDefinition $def, $array) 
     50    protected function addAttributesToValue(Tag $tag, BaseTagDefinition $def, $array) 
    5151    { 
    5252        // set all attributes 
  • trunk/XJConf/converters/ConstructorValueConverter.php

    r56 r61  
    7070 
    7171        // add attributes and child elements 
    72         if ($def instanceof TagDefinition) { 
     72        if ($def instanceof BaseTagDefinition) { 
    7373            $this->addAttributesToValue($tag, $def, $instance); 
    7474            $this->addCDataToValue($tag, $def, $instance); 
  • trunk/XJConf/converters/FactoryMethodValueConverter.php

    r56 r61  
    7373 
    7474        // add attributes and child elements 
    75         if ($def instanceof TagDefinition) { 
     75        if ($def instanceof BaseTagDefinition) { 
    7676            $this->addAttributesToValue($tag, $def, $instance); 
    7777            $this->addCDataToValue($tag, $def, $instance); 
  • trunk/XJConf/definitions/NamespaceDefinition.php

    r2 r61  
    1111     * list of tag definitions 
    1212     *  
    13      * @var  array<String,TagDefinition> 
     13     * @var  array<String,BaseTagDefinition> 
    1414     */ 
    1515        private $tagDefinitions = array(); 
     
    3535    * Add a new tag definition 
    3636    *  
    37     * @param  TagDefinition  $tagDefinition 
     37    * @param  BaseTagDefinition  $tagDefinition 
    3838    */ 
    39     public function addTagDefinition(TagDefinition $tagDefinition) 
     39    public function addTagDefinition(BaseTagDefinition $tagDefinition) 
    4040    { 
    4141        $this->tagDefinitions[$tagDefinition->getTagName()] = $tagDefinition; 
     
    6767    *  
    6868    * @param   tagName name of the tag 
    69     * @return  TagDefinition 
     69    * @return  BaseTagDefinition 
    7070    */ 
    7171    public function getDefinition($tagName) 
  • trunk/XJConf/definitions/NamespaceDefinitions.php

    r2 r61  
    8181     * Get the definition of a single tag 
    8282     *  
    83      * @param   string         $namespace  namespace URI 
    84      * @param   string         $tagName    local tag name 
    85      * @return  TagDefinition 
     83     * @param   string             $namespace  namespace URI 
     84     * @param   string             $tagName    local tag name 
     85     * @return  BaseTagDefinition 
    8686     */ 
    8787    public function getTagDefinition($namespace, $tagName) 
  • trunk/XJConf/definitions/TagDefinition.php

    r46 r61  
    66 * @author  Frank Kleine <frank.kleine@schlund.de> 
    77 */ 
    8 XJConfLoader::load('converters.factories.ValueConverterFactoryChain', 
    9                    'definitions.AttributeDefinition', 
    10                    'definitions.CDataDefinition', 
    11                    'definitions.ConstructorDefinition', 
    12                    'definitions.FactoryMethodDefinition', 
    13                    'definitions.Definition', 
    14                    'exceptions.ValueConversionException', 
    15                    'exceptions.XJConfException', 
    16                    'XJConfClassLoader' 
    17 ); 
     8XJConfLoader::load('definitions.BaseTagDefinition'); 
    189/** 
    1910 * Definition of an XML tag. 
     
    2213 * @subpackage  definitions 
    2314 */ 
    24 class TagDefinition implements Definition 
     15class TagDefinition extends BaseTagDefinition 
    2516{ 
    26     /** 
    27      * the name 
    28      * 
    29      * @var  string 
    30      */ 
    31         private $name           = null; 
    32         /** 
    33      * the name of the tag 
    34      * 
    35      * @var  string 
    36      */ 
    37         private $tagName        = null; 
    38         /** 
    39      * type of the tag 
    40      * 
    41      * @var  string 
    42      */ 
    43         private $type           = null; 
    44         /** 
    45      * list of attribute definitions 
    46      * 
    47      * @var  array<AttributeDefinition> 
    48      */ 
    49         private $atts           = array(); 
    50         /** 
    51      * name of the setter 
    52      * 
    53      * @var  string 
    54      */ 
    55         private $setter         = null; 
    56         /** 
    57          * name of attribute that contains the name 
    58          * 
    59          * @var  string 
    60          */ 
    61         private $nameAttribute  = null; 
    62         /** 
    63          * definition of how to construct the object 
    64          * 
    65          * @var  ConstructorDefinition 
    66          */ 
    67     private $constructor    = null; 
    68     /** 
    69      * definition of factory that is able to construct the object 
    70      * 
    71      * @var  FactoryMethodDefinition 
    72      */ 
    73     private $factoryMethod  = null; 
    74     /** 
    75      * converts the value 
    76      * 
    77      * @var  ValueConverter 
    78      */ 
    79     private $valueConverter; 
    80     /** 
    81      * definition of tag content 
    82      * 
    83      * @var   CDataDefinition 
    84      * @todo  Eventually call the setter method for the cdata 
    85      */ 
    86         private $cdata          = null; 
    87         /** 
    88          * the class loader to use 
    89          * 
    90          * @var  XJConfClassLoader 
    91          */ 
    92         private $classLoader    = null; 
    93  
    9417    /** 
    9518     * Create a new tag definition 
     
    9720     * @param   string  $name  name of the tag 
    9821     * @param   string  $type  type of the tag 
    99      * @throws  XJConfException 
     22     * @throws  InvalidTagDefinitionException 
    10023     */ 
    10124        public function __construct($name, $type) 
    10225        { 
    10326                if (null == $name || strlen($name) == 0) { 
    104                         throw new XJConfException('TagDefinition needs a name.'); 
     27                        throw new InvalidTagDefinitionException('TagDefinition needs a name.'); 
    10528                } 
    10629                if (null == $type || strlen($type) == 0) { 
    107                         throw new XJConfException('TagDefinition needs a type.'); 
     30                        throw new InvalidTagDefinitionException('TagDefinition needs a type.'); 
    10831                } 
    10932 
     
    11235                $this->setType($type); 
    11336        } 
    114  
    115         /** 
    116          * set the name of the value 
    117          * 
    118          * @param  string  $name 
    119          */ 
    120         public function setName($name) 
    121         { 
    122                 $this->name = $name; 
    123         } 
    124  
    125         /** 
    126          * get the name of the value 
    127          * 
    128          * @return  string 
    129          */ 
    130         public function getName() 
    131         { 
    132                 return $this->name; 
    133         } 
    134  
    135         /** 
    136          * Set the type of the tag 
    137          * 
    138          * @param  string  $type 
    139          */ 
    140         public function setType($type) 
    141         { 
    142                 $this->type = $type; 
    143         } 
    144  
    145         /** 
    146          * get the type of the tag 
    147          * 
    148          * @return  string 
    149          */ 
    150         public function getType() 
    151         { 
    152             if (null != $this->classLoader) { 
    153                 return $this->classLoader->getType($this->type); 
    154             } 
    155              
    156                 return $this->type; 
    157         } 
    158  
    159         /** 
    160          * Convert the value of the tag. 
    161          * 
    162          * @param   Tag    $tag  tag that will be converted 
    163          * @return  mixed  converted value 
    164          * @throws  ValueConversionException 
    165          */ 
    166         public function convertValue(Tag $tag) 
    167     { 
    168                 // get the data 
    169                 $data = $tag->getContent(); 
    170                 if (null == $data) { 
    171                         $data = ''; 
    172                 } 
    173                  
    174         // no constructor definition has been set, 
    175         // create a new one 
    176         if (null == $this->constructor && null == $this->factoryMethod) { 
    177             $this->constructor = new ConstructorDefinition(); 
    178             $this->constructor->addChildDefinition(new CDataDefinition()); 
    179         } 
    180  
    181         $instance = $this->getValueConverter()->convertValue($tag, $this); 
    182                 return $instance; 
    183         } 
    184  
    185         /** 
    186      * Get the type of the tag 
    187      * 
    188      * @return  string 
    189      */ 
    190     public function getValueType(Tag $tag) 
    191     { 
    192         return $this->getValueConverter()->getType(); 
    193     } 
    194  
    195     /** 
    196          * Set the setter method 
    197          * 
    198          * @param  string  $setter  name of the setter method 
    199          */ 
    200         public function setSetterMethod($setter) 
    201         { 
    202                 $this->setter = $setter; 
    203         } 
    204  
    205         /** 
    206          * Get the name of the setter method that should be used 
    207          * 
    208          * @return  string 
    209          */ 
    210         public function getSetterMethod(Tag $tag) 
    211         { 
    212                 if (null != $this->setter) { 
    213                         return $this->setter; 
    214                 } 
    215  
    216                 // no name, the parent should be a collection 
    217                 if ('__none' == $this->name) { 
    218                         return null; 
    219                 } 
    220  
    221                 return 'set' . ucfirst($this->getKey($tag)); 
    222         } 
    223  
    224     /** 
    225      * Add a new child definition 
    226      * 
    227      * Possible definitions are: 
    228      * - AttributeDefinition 
    229      * - ConstructorDefinition 
    230      * - FactoryMethodDefinition 
    231      * - CDataDefinition 
    232      * 
    233      * @param  Definition  $def 
    234      */ 
    235     public function addChildDefinition(Definition $def) 
    236     { 
    237         if ($def instanceof AttributeDefinition) { 
    238             $this->addAttribute($def); 
    239             return; 
    240         } 
    241  
    242         if ($def instanceof FactoryMethodDefinition) { 
    243             $this->factoryMethod = $def; 
    244             return; 
    245         } 
    246  
    247         if ($def instanceof ConstructorDefinition) { 
    248             $this->constructor = $def; 
    249             return; 
    250         } 
    251  
    252         if ($def instanceof CDataDefinition) { 
    253             $this->cdata = $def; 
    254             return; 
    255         } 
    256     } 
    257  
    258     /** 
    259      * Checks whether this definition has a specific child condition 
    260      * 
    261      * @param   string   $def 
    262      * @return  boolean  true if definition has a specific child condition, else false 
    263      */ 
    264     public function hasChildDefinition($def) 
    265     { 
    266         $children = $this->getChildDefinitions(); 
    267         foreach ($children as $child) { 
    268             if (get_class($child) == $def) { 
    269                 return true; 
    270             } 
    271         } 
    272  
    273         return false; 
    274     } 
    275  
    276     /** 
    277      * Returns the first found definition of type $def 
    278      * 
    279      * @param   string   $def 
    280      * @return  Definition 
    281      */ 
    282     public function getChildDefinition($def) 
    283     { 
    284         $children = $this->getChildDefinitions(); 
    285         foreach ($children as $child) { 
    286             if (get_class($child) == $def) { 
    287                 return $child; 
    288             } 
    289         } 
    290  
    291         return null; 
    292     } 
    293  
    294     /** 
    295      * Return all child definitions. 
    296      * 
    297      * @return  array 
    298      */ 
    299     public function getChildDefinitions() 
    300     { 
    301         $children = $this->atts; 
    302         if ($this->factoryMethod instanceof Definition) { 
    303             $children[] = $this->factoryMethod; 
    304         } 
    305  
    306         if ($this->constructor instanceof Definition) { 
    307             $children[] = $this->constructor; 
    308         } 
    309  
    310         if ($this->cdata instanceof Definition) { 
    311             $children[] = $this->cdata; 
    312         } 
    313  
    314         return $children; 
    315     } 
    316  
    317         /** 
    318          * Add an attribute to the tag 
    319          * 
    320          * @param  AttributeDefinition  $att 
    321          */ 
    322         public function addAttribute(AttributeDefinition $att) 
    323         { 
    324                 array_push($this->atts, $att); 
    325         } 
    326  
    327         /** 
    328          * Return list of attributes for this tag 
    329          * 
    330          * @return  array 
    331          */ 
    332         public function getAttributes() { 
    333             return $this->atts; 
    334         } 
    335  
    336         /** 
    337          * Set the name of the tag 
    338          * 
    339          * @param name 
    340          */ 
    341         public function setTagName($name) 
    342         { 
    343                 $this->tagName = $name; 
    344         } 
    345  
    346         /** 
    347          * Set the attribute that will be used as key. 
    348      * 
    349          * @return   name of the value 
    350          */ 
    351         public function setKeyAttribute($att) 
    352         { 
    353         $this->name          = '__attribute'; 
    354                 $this->nameAttribute = $att; 
    355         } 
    356  
    357         /** 
    358          * get the name of the tag 
    359          * 
    360          * @return  string 
    361          */ 
    362         public function getTagName() 
    363         { 
    364                 return $this->tagName; 
    365         } 
    366  
    367         /** 
    368          * get the name of the tag 
    369          * 
    370          * @return  string 
    371          */ 
    372         public function getKey(DefinedTag $tag) 
    373         { 
    374                 if ('__attribute' == $this->name) { 
    375                 return $tag->getAttribute($this->nameAttribute); 
    376         } 
    377  
    378         return $this->name; 
    379         } 
    380  
    381     /** 
    382      * Check, whether the value supports indexed children 
    383      * 
    384      * @return  boolean 
    385      */ 
    386         public function supportsIndexedChildren() 
    387         { 
    388                 if ($this->getType() == 'array') { 
    389                         return true; 
    390                 } 
    391  
    392                 return false; 
    393         } 
    394          
    395         /** 
    396          * set the class loader for this tag 
    397          * 
    398          * @param  XJConfClassLoader  $classLoader 
    399          */ 
    400         public function setClassLoader(XJConfClassLoader $classLoader) 
    401         { 
    402             $this->classLoader = $classLoader; 
    403         } 
    404  
    405     /** 
    406      * Get the value converter for this tag 
    407      * 
    408      * @return  ValueConverter 
    409      */ 
    410     private function getValueConverter() 
    411     { 
    412         if (null != $this->classLoader) { 
    413                     $this->classLoader->loadClass($this->type); 
    414                 } 
    415                  
    416         if (null == $this->valueConverter) { 
    417             $this->valueConverter = ValueConverterFactoryChain::getFactory($this)->createValueConverter($this); 
    418         } 
    419  
    420         return $this->valueConverter; 
    421     } 
    42237} 
    42338?> 
  • trunk/examples/xml/defines-dynamic-types.xml

    r53 r61  
    11<defines> 
    22        <tag name="foo" type="MyCollector"/> 
    3         <tag name="bar" type="MyInterface" setter="addBar" /> 
     3        <abstractTag name="bar" abstractType="MyInterface" setter="addBar" concreteTypeAttribute="__type" /> 
    44</defines>