PEIP_XML_Context.php

Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  * This file is part of the PEIP package.
00005  * (c) 2010 Timo Michna <timomichna/yahoo.de>
00006  * 
00007  * For the full copyright and license information, please view the LICENSE
00008  * file that was distributed with this source code.
00009  */
00010 
00021 class PEIP_XML_Context 
00022     implements 
00023         PEIP_INF_Context,
00024         PEIP_INF_Channel_Resolver {
00025 
00026     protected 
00027         $services = array(),
00028         $configs = array(),
00029         $gateways = array(),
00030         $nodeBuilders = array(),
00031         $channelRegistry;
00032     
00033     
00034     
00035     
00041     public function __construct($xml){
00042         $this->simpleXML = new SimpleXMLIterator($xml);
00043         $this->initNodeBuilders();
00044         $this->init();
00045     }
00046 
00047     public static function createFromString($xml){
00048         return new PEIP_XML_Context($xml);
00049     }
00050     
00051     public static function createFromFile($file){
00052         if(file_exists($file)){
00053             return self::createFromString(file_get_contents($file));
00054         }else{
00055             throw new RuntimeException('Cannot open file  "'.$file.'".');
00056         }
00057     }
00058 
00059     
00066     public function registerNodeBuilder($nodeName, $callable){
00067         $this->nodeBuilders[$nodeName] = $callable;     
00068     }
00069 
00070     
00076     public function addPlugin(PEIP_INF_Context_Plugin $plugin){
00077         $plugin->init($this);   
00078     }
00079 
00080     
00086     public function createPlugin($config){
00087         $plugin = $this->createService($config);    
00088         $this->addPlugin($plugin);
00089     }
00090     
00091     
00092     private function initNodeBuilders(){
00093         $builders = array(
00094             'plugin' => 'createPlugin',
00095             'channel' => 'createChannel',
00096             'publish_subscribe_channel' => 'createSubscribebalChannel',
00097             'service' => 'initService',
00098             'service_activator' => 'createServiceActivator',
00099             'gateway' => 'createGateway',
00100             'splitter' => 'createSplitter',
00101             'router' => 'createRouter',
00102             'aggregator' => 'createAggregator',
00103             'wiretap' => 'createWiretap'
00104                 
00105         );
00106         foreach($builders as $nodeName => $method){
00107             $this->registerNodeBuilder($nodeName, array($this, $method));   
00108         }       
00109     }
00110 
00111     
00125     protected function buildNode($node){
00126         $nodeName = $node->getName();
00127         if(array_key_exists($nodeName, $this->nodeBuilders)){
00128             call_user_func($this->nodeBuilders[$nodeName], $node);
00129         }           
00130     }
00131     
00132     
00137     protected function init(){
00138         $xml = $this->simpleXML;
00139         $this->channelRegistry = PEIP_Channel_Registry::getInstance();
00140         if($xml['id']){
00141             $this->services[(string)$xml['id']] = $this;    
00142         }
00143         foreach($xml->children() as $entry){
00144             $this->buildNode($entry);
00145         }
00146     }
00147 
00148     
00154     public function resolveChannelName($channelName){
00155         return $this->channelRegistry->get($channelName);
00156     }   
00157     
00158     
00164     public function getService($id){    
00165         return $this->hasService($id)  
00166             ? $this->services[$id]
00167             : NULL;
00168     }
00169 
00170     
00176     public function hasService($id){
00177         return isset($this->services[$id]);
00178     }
00179     
00180     
00186     protected function requestService($id){
00187         $service = $this->getService($id);
00188         if($service === NULL){
00189             throw new RuntimeException('Service "'.$id.'" not found.');
00190         } 
00191         return $service;
00192     }
00193     
00194     
00205     protected function initService($config){
00206         $id = trim((string)$config['id']);
00207         if($id != ''){
00208             return $this->services[$id] = $this->createService($config);    
00209         }   
00210     }
00211 
00212                 
00213     
00219     public function createService($config){
00220         $args = array();
00221         if($config->constructor_arg){
00222             foreach($config->constructor_arg as $arg){
00223                 $args[] = $this->buildArg($arg);
00224             }
00225         }
00226         return $this->buildAndModify($config, $args);       
00227     }
00228 
00229     
00236     protected function modifyService($service, $config){
00237         if($config->property){          
00238             foreach($config->property as $property){
00239                 $setter = self::getSetter($property);
00240                 if($setter){                
00241                     $arg = $this->buildArg($property);
00242                     if($arg){
00243                         $service->{$setter}($arg);  
00244                     }
00245                 }
00246             }
00247         }   
00248         if($config->action){            
00249             foreach($config->action as $action){
00250                 if($action['method'] && method_exists($service, (string)$action['method'])){
00251                     $args = array();
00252                     foreach($action->children() as $argument){
00253                         $args[] = $this->buildArg($argument);
00254                     }
00255                     call_user_func_array(array($service, (string)$action['method']), $args);
00256                 }
00257             }
00258         }       
00259         if($service instanceof PEIP_INF_Connectable){
00260             if($config->listener){
00261                 foreach($config->listener as $listenerConf){
00262                     $event = (string)$listenerConf['event'];
00263                     $listener = $this->provideService($config);  
00264                     $service->connect($event, $listener);   
00265                 }
00266             }
00267         }
00268         return $service;
00269     }   
00270     
00271     
00277     public function getGateway($id){
00278         return $this->gateways[$id];
00279     }   
00280 
00281     
00287     public function createChannel($config){
00288         return $this->doCreateChannel($config, 'PEIP_Pollable_Channel');        
00289     }
00290 
00291     
00297     public function createSubscribebalChannel($config){
00298         return $this->doCreateChannel($config, 'PEIP_Publish_Subscribe_Channel');       
00299     }   
00300 
00301     
00309     public function doCreateChannel($config, $defaultChannel, array $additionalArguments = array()){
00310         $id = (string)$config['id'];
00311         if($id != ''){
00312             array_unshift($additionalArguments, $id);
00313             $channel = $this->buildAndModify($config, array($id), $defaultChannel);
00314             $this->channelRegistry->register($channel);
00315             return $channel;
00316         }
00317     }
00318     
00319     
00320     
00327     public function createGateway($config, $defaultClass = false){
00328         $args = array(
00329             $this->getRequestChannel($config), 
00330             $this->getReplyChannel($config)
00331         );
00332         $defaultClass = $defaultClass ? $defaultClass : 'PEIP_Simple_Messaging_Gateway';
00333         $gateway = $this->buildAndModify($config, $args, $defaultClass);
00334         $id = (string)$config["id"];
00335         $this->gateways[$id] = $gateway;
00336         return $gateway;    
00337     }
00338 
00339     
00345     public function createRouter($config){
00346         $resolver = $config['channel_resolver'] ? (string)$config['channel_resolver'] : $this->channelRegistry;
00347         return $this->buildAndModify($config, array(
00348             $resolver,
00349             $this->doGetChannel('input', $config)
00350         ));
00351     }
00352     
00353     
00359     public function createSplitter($config){
00360         return $this->createReplyMessageHandler($config);           
00361     }   
00362     
00363     
00369     public function createAggregator($config){
00370         return $this->createReplyMessageHandler($config);       
00371     }
00372 
00373     
00379     public function createWiretap($config){
00380         return $this->createReplyMessageHandler($config, 'PEIP_Wiretap');       
00381     }
00382 
00383     
00390     public function createReplyMessageHandler($config, $defaultClass = false){
00391         return $this->buildAndModify($config, $this->getReplyHandlerArguments($config), $defaultClass); 
00392     }
00393     
00394     
00395     
00408     public function createServiceActivator($config, $defaultClass = false){
00409         $method = (string)$config['method'];
00410         $service = $this->getService((string)$config['ref']);
00411         if($method && $service){        
00412             $args = $this->getReplyHandlerArguments($config);
00413             array_unshift($args,array(
00414                 $service,
00415                 $method             
00416             )); 
00417             echo $defaultClass = $defaultClass ? $defaultClass : 'PEIP_Service_Activator';
00418             return $this->buildAndModify($config, $args, $defaultClass);                
00419         }
00420     }   
00421     
00422     
00428     protected function provideService($config){
00429         $ref = trim((string)$config['ref']);
00430         if($ref != ''){
00431             $service = $this->getService($ref); 
00432         }else{
00433             $service = $this->createService($config);
00434         }
00435         return $service;
00436     }
00437        
00438     protected static function getSetter($config){
00439         if($config['setter']){
00440             $setter = (string)$config['setter'];
00441         }elseif($config['name']){
00442             $setter = 'set'.ucfirst((string)$config['name']);   
00443         }
00444         return $setter;     
00445     }
00446     
00447     
00448        
00449     
00463     protected function buildArg($config){
00464         if(trim((string)$config['value']) != ''){
00465             $arg = (string)$config['value'];
00466         }elseif($config->getName() == 'value'){
00467             $arg = (string)$config;
00468         }elseif($config->getName() == 'list'){
00469             $arg = array();
00470             foreach($config->children() as $entry){ 
00471                 if($entry->getName() == 'value'){
00472                     if($entry['key']){
00473                         $arg[(string)$entry['key']] = (string)$entry;   
00474                     }else{
00475                         $arg[] = (string)$entry;
00476                     }
00477                 }elseif($entry->getName() == 'service'){
00478                     $arg[] = $this->provideService($entry);
00479                 }
00480             }
00481         }elseif($config->getName() == 'service'){
00482             $arg = $this->provideService($config);
00483         }elseif($config->list){
00484             $arg = $this->buildArg($config->list);
00485         }elseif($config->service){
00486             $arg = $this->buildArg($config->service);
00487         }
00488         return $arg;
00489     }       
00490 
00491     
00497     protected function getReplyHandlerArguments($config){
00498         $args = array(
00499             $this->doGetChannel('input', $config),
00500             $this->doGetChannel('output', $config)
00501         );
00502         if($args[0] == NULL){
00503             throw new RuntimeException('Could not receive input channel.');
00504         }
00505         return $args;
00506     }
00507     
00508     
00514     protected function getRequestChannel($config){
00515         return $this->doGetChannel('request', $config); 
00516     }
00517     
00518     
00524     protected function getReplyChannel($config){
00525         return $this->doGetChannel('reply', $config);   
00526     }
00527     
00528     
00535     public function doGetChannel($type, $config){
00536         $channelName = $config[$type."_channel"] 
00537             ? $config[$type."_channel"] 
00538             : $config["default_".$type."_channel"]; 
00539         $channel =  $this->services[trim((string)$channelName)];
00540         if($channel instanceof PEIP_INF_Channel){
00541             return $channel;    
00542         }else{
00543             return NULL;
00544         }       
00545     }
00546 
00547     
00555     public function buildAndModify($config, $arguments, $defaultClass = false){
00556         $service = $this->modifyService(self::doBuild($config, $arguments, $defaultClass), $config);
00557         $id = trim((string)$config['id']);
00558         if($service && $id != ''){
00559             $this->services[$id] = $service;    
00560         }
00561         return $service;
00562     }
00563     
00564     protected static function doBuild($config, $arguments, $defaultClass = false){
00565         $cls = $config["class"] ? trim((string)$config["class"]) : (string)$defaultClass;
00566         if($cls != ''){
00567             try {
00568                 return self::build($cls, $arguments);       
00569             }catch(Exception $e){
00570                 throw new RuntimeException('Could not create Service "'.$cls.'" -> '.$e->getMessage());
00571             }           
00572         }
00573         throw new RuntimeException('Could not create Service "'.$cls.'". Class does not exist.');           
00574     }   
00575     
00576     protected static function build($className, $arguments){
00577         return PEIP_Generic_Builder::getInstance($className)->build($arguments);
00578     }
00579 
00580 
00581 } 

Generated on Mon Apr 12 11:39:00 2010 for PEIP by  doxygen 1.5.1