Processor.php
Current file: C:\DATA\Viktor\Diplomka\XSLT-Benchmarking/XSLTBenchmarking/TestsRunner/Processors/Processor.php
Legend: executed not executed dead code

  Coverage
  Classes Functions / Methods Lines
Total
0.00% 0 / 1
87.50% 7 / 8 CRAP
90.51% 124 / 137
Processor
0.00% 0 / 1
87.50% 7 / 8 36.05
90.51% 124 / 137
 __construct( $tmpDir, MemoryUsage $memoryUsage, $driversDir = NULL, $driversNamespace = '\XSLTBenchmarking\TestsRunner\\' )
100.00% 1 / 1 2
100.00% 9 / 9
 getAvailable()
100.00% 1 / 1 2
100.00% 5 / 5
 getInformations()
100.00% 1 / 1 2
100.00% 5 / 5
 run($processorName, $templatePath, $xmlInputPath, $outputPath, $repeating)
0.00% 0 / 1 20.61
83.54% 66 / 79
 detectAvailable()
100.00% 1 / 1 6
100.00% 18 / 18
 readInformations()
100.00% 1 / 1 2
100.00% 5 / 5
 getCommand($commandTemplate, $templatePath, $xmlInputPath, $outputPath, $errorPath)
100.00% 1 / 1 1
100.00% 8 / 8
 makeInputWithTemplatePath($xmlInputPath, $templatePath)
100.00% 1 / 1 1
100.00% 8 / 8



       1                 : <?php                                                                                                                                     
       2                 :                                                                                                                                           
       3                 : /**                                                                                                                                       
       4                 :  * XSLT Benchmarking                                                                                                                      
       5                 :  * @link https://github.com/masicek/XSLT-Benchmarking                                                                                     
       6                 :  * @author Viktor Mašíček <viktor@masicek.net>                                                                                         
       7                 :  * @license "New" BSD License                                                                                                             
       8                 :  */                                                                                                                                       
       9                 :                                                                                                                                           
      10                 : namespace XSLTBenchmarking\TestsRunner;                                                                                                   
      11                 :                                                                                                                                           
      12                 : require_once ROOT . '/Exceptions.php';                                                                                                    
      13                 : require_once ROOT . '/Microtime.php';                                                                                                     
      14                 : require_once LIBS . '/PhpPath/PhpPath.min.php';                                                                                           
      15                 :                                                                                                                                           
      16                 : use XSLTBenchmarking\Microtime;                                                                                                           
      17                 : use PhpPath\P;                                                                                                                            
      18                 :                                                                                                                                           
      19                 :                                                                                                                                           
      20                 : /**                                                                                                                                       
      21                 :  * Class for parse one template in one processor                                                                                          
      22                 :  *                                                                                                                                        
      23                 :  * @author Viktor Mašíček <viktor@masicek.net>                                                                                         
      24                 :  */                                                                                                                                       
      25                 : class Processor                                                                                                                           
      26                 : {                                                                                                                                         
      27                 :                                                                                                                                           
      28                 :                                                                                                                                           
      29                 :     /**                                                                                                                                   
      30                 :      * Path of dirctory containing processors drivers                                                                                     
      31                 :      *                                                                                                                                    
      32                 :      * @var string                                                                                                                        
      33                 :      */                                                                                                                                   
      34                 :     private $driversDir;                                                                                                                  
      35                 :                                                                                                                                           
      36                 :     /**                                                                                                                                   
      37                 :      * Namespace of processors drivers                                                                                                    
      38                 :      *                                                                                                                                    
      39                 :      * @var string                                                                                                                        
      40                 :      */                                                                                                                                   
      41                 :     private $driversNamespace;                                                                                                            
      42                 :                                                                                                                                           
      43                 :     /**                                                                                                                                   
      44                 :      * Path of temporary directory                                                                                                        
      45                 :      *                                                                                                                                    
      46                 :      * @var string                                                                                                                        
      47                 :      */                                                                                                                                   
      48                 :     private $tmpDir;                                                                                                                      
      49                 :                                                                                                                                           
      50                 :     /**                                                                                                                                   
      51                 :      * Class for measure memory usage of run command                                                                                      
      52                 :      *                                                                                                                                    
      53                 :      * @var MemoryUsage                                                                                                                   
      54                 :      */                                                                                                                                   
      55                 :     private $memoryUsage;                                                                                                                 
      56                 :                                                                                                                                           
      57                 :     /**                                                                                                                                   
      58                 :      * List of available names of processors                                                                                              
      59                 :      *                                                                                                                                    
      60                 :      * @var array                                                                                                                         
      61                 :      */                                                                                                                                   
      62                 :     private $available = NULL;                                                                                                            
      63                 :                                                                                                                                           
      64                 :     /**                                                                                                                                   
      65                 :      * List of informations about processors                                                                                              
      66                 :      *                                                                                                                                    
      67                 :      * @var array                                                                                                                         
      68                 :      */                                                                                                                                   
      69                 :     private $informations = NULL;                                                                                                         
      70                 :                                                                                                                                           
      71                 :                                                                                                                                           
      72                 :     /**                                                                                                                                   
      73                 :      * Configure object                                                                                                                   
      74                 :      *                                                                                                                                    
      75                 :      * @param string $tmpDir Path of temporary directory                                                                                  
      76                 :      * @param MemoryUsage $memoryUsage Class for measure memory usage of run command                                                      
      77                 :      * @param string $driversDir Path of dirctory containing processor drivers                                                            
      78                 :      * @param string $driversNamespace Namespace of processors drivers                                                                    
      79                 :      */                                                                                                                                   
      80                 :     public function __construct(                                                                                                          
      81                 :         $tmpDir,                                                                                                                          
      82                 :         MemoryUsage $memoryUsage,                                                                                                         
      83                 :         $driversDir = NULL,                                                                                                               
      84                 :         $driversNamespace = '\XSLTBenchmarking\TestsRunner\\'                                                                             
      85                 :     )                                                                                                                                     
      86                 :     {                                                                                                                                     
      87               8 :         if (is_null($driversDir))                                                                                                         
      88               8 :         {                                                                                                                                 
      89               6 :             $driversDir = P::m(__DIR__, 'Drivers');                                                                                       
      90               6 :         }                                                                                                                                 
      91                 :                                                                                                                                           
      92               8 :         $this->tmpDir = P::mcd($tmpDir);                                                                                                  
      93               7 :         $this->memoryUsage = $memoryUsage;                                                                                                
      94               7 :         $this->driversDir = P::mcd($driversDir);                                                                                          
      95               6 :         $this->driversNamespace = $driversNamespace;                                                                                      
      96               6 :     }                                                                                                                                     
      97                 :                                                                                                                                           
      98                 :                                                                                                                                           
      99                 :     /**                                                                                                                                   
     100                 :      * Return list of available names of processors                                                                                       
     101                 :      *                                                                                                                                    
     102                 :      * @return array ([name] => AProcessorDriver)                                                                                         
     103                 :      */                                                                                                                                   
     104                 :     public function getAvailable()                                                                                                        
     105                 :     {                                                                                                                                     
     106               5 :         if (!$this->available)                                                                                                            
     107               5 :         {                                                                                                                                 
     108               5 :             $this->available = $this->detectAvailable();                                                                                  
     109               5 :         }                                                                                                                                 
     110               5 :         return $this->available;                                                                                                          
     111                 :     }                                                                                                                                     
     112                 :                                                                                                                                           
     113                 :                                                                                                                                           
     114                 :     /**                                                                                                                                   
     115                 :      * Return information about processors                                                                                                
     116                 :      *                                                                                                                                    
     117                 :      * @return array                                                                                                                      
     118                 :      */                                                                                                                                   
     119                 :     public function getInformations()                                                                                                     
     120                 :     {                                                                                                                                     
     121               1 :         if (!$this->informations)                                                                                                         
     122               1 :         {                                                                                                                                 
     123               1 :             $this->informations = $this->readInformations();                                                                              
     124               1 :         }                                                                                                                                 
     125               1 :         return $this->informations;                                                                                                       
     126                 :     }                                                                                                                                     
     127                 :                                                                                                                                           
     128                 :                                                                                                                                           
     129                 :     /**                                                                                                                                   
     130                 :      * Run one XSLT transformation in the processor                                                                                       
     131                 :      *                                                                                                                                    
     132                 :      * @param string $processorName Name of used processor                                                                                
     133                 :      * @param string $templatePath Path of XSLT template                                                                                  
     134                 :      * @param string $xmlInputPath Path of XML input file                                                                                 
     135                 :      * @param string $outputPath Path of generated output file                                                                            
     136                 :      *                                                                                                                                    
     137                 :      * @return array|string List of spend times on transformation|Error message                                                           
     138                 :      */                                                                                                                                   
     139                 :     public function run($processorName, $templatePath, $xmlInputPath, $outputPath, $repeating)                                            
     140                 :     {                                                                                                                                     
     141               8 :         $processors = $this->getAvailable();                                                                                              
     142               8 :         if (!isset($processors[$processorName]))                                                                                          
     143               8 :         {                                                                                                                                 
     144               1 :             throw new \XSLTBenchmarking\InvalidArgumentException('Unknown processor "' . $processorName . '"');                           
     145                 :         }                                                                                                                                 
     146                 :                                                                                                                                           
     147               7 :         $processor = $processors[$processorName];                                                                                         
     148                 :                                                                                                                                           
     149               7 :         P::mcf($templatePath);                                                                                                            
     150               6 :         P::mcf($xmlInputPath);                                                                                                            
     151                 :                                                                                                                                           
     152                 :         // stylesheet for transformation have to be set in input XML file                                                                 
     153               5 :         if ($processor->isTemplateSetInInput())                                                                                           
     154               5 :         {                                                                                                                                 
     155               1 :             $xmlInputPath = $this->makeInputWithTemplatePath($xmlInputPath, $templatePath);                                               
     156               1 :         }                                                                                                                                 
     157                 :                                                                                                                                           
     158               5 :         $errorPath = P::m($this->tmpDir, 'transformation.err');                                                                           
     159                 :                                                                                                                                           
     160               5 :         $beforeCommand = $this->getCommand($processor->getBeforeCommandTemplate(), $templatePath, $xmlInputPath, $outputPath, $errorPath);
     161               5 :         $commandBase = $this->getCommand($processor->getCommandTemplate(), $templatePath, $xmlInputPath, $outputPath, $errorPath);        
     162               5 :         $afterCommand = $this->getCommand($processor->getAfterCommandTemplate(), $templatePath, $xmlInputPath, $outputPath, $errorPath);  
     163                 :                                                                                                                                           
     164               5 :         $times = array();                                                                                                                 
     165               5 :         $memoryList = array();                                                                                                            
     166               5 :         for ($repeatingIdx = 0; $repeatingIdx < $repeating; $repeatingIdx++)                                                              
     167                 :         {                                                                                                                                 
     168               5 :             if (is_file($errorPath))                                                                                                      
     169               5 :             {                                                                                                                             
     170               1 :                 throw new \XSLTBenchmarking\InvalidStateException('Error tmp file should not exist "' . $errorPath . '"');                
     171                 :             }                                                                                                                             
     172                 :                                                                                                                                           
     173               4 :             $command = $commandBase;                                                                                                      
     174                 :                                                                                                                                           
     175                 :             // each transformation generate into separate file                                                                            
     176               4 :             if ($repeatingIdx != 0)                                                                                                       
     177               4 :             {                                                                                                                             
     178               3 :                 $outputPathNew = preg_replace('/[.]([^.]*)$/', '-' . $repeatingIdx . '.$1', $outputPath);                                 
     179               3 :                 $command = str_replace($outputPath, $outputPathNew, $command);                                                            
     180               3 :             }                                                                                                                             
     181                 :                                                                                                                                           
     182                 :             // preparing command                                                                                                          
     183                 :             if ($beforeCommand)                                                                                                           
     184               4 :             {                                                                                                                             
     185               1 :                 exec($beforeCommand);                                                                                                     
     186               1 :             }                                                                                                                             
     187                 :                                                                                                                                           
     188                 :             // memore usage - run                                                                                                         
     189               4 :             $command = $this->memoryUsage->run($command);                                                                                 
     190                 :                                                                                                                                           
     191                 :             // transformation command                                                                                                     
     192               4 :             $timeStart = Microtime::now();                                                                                                
     193               4 :             exec($command);                                                                                                               
     194               4 :             $timeEnd = Microtime::now();                                                                                                  
     195                 :                                                                                                                                           
     196                 :             // memore usage - get                                                                                                         
     197               4 :             $memoryList[] = (string)$this->memoryUsage->get();                                                                            
     198                 :                                                                                                                                           
     199                 :             // concluding comand                                                                                                          
     200                 :             if ($afterCommand)                                                                                                            
     201               4 :             {                                                                                                                             
     202               1 :                 exec($afterCommand);                                                                                                      
     203               1 :             }                                                                                                                             
     204                 :                                                                                                                                           
     205                 :             // check exitence of generated file                                                                                           
     206               4 :             if ($repeatingIdx == 0 && !is_file($outputPath))                                                                              
     207               4 :             {                                                                                                                             
     208               1 :                 $error = 'Output file was not be generated (' . $outputPath . ')';                                                        
     209                 :                 // detect generated error                                                                                                 
     210               1 :                 if (is_file($errorPath))                                                                                                  
     211               1 :                 {                                                                                                                         
     212               1 :                     $error .= '; ' . file_get_contents($errorPath);                                                                       
     213               1 :                     unlink($errorPath);                                                                                                   
     214               1 :                 }                                                                                                                         
     215                 :                                                                                                                                           
     216               1 :                 break;                                                                                                                    
     217                 :             }                                                                                                                             
     218               3 :             if ($repeatingIdx != 0 && !is_file($outputPathNew))                                                                           
     219               3 :             {                                                                                                                             
     220               0 :                 $error = 'Output file (repeated) was not be generated (' . $outputPathNew . ')';                                          
     221                 :                 // detect generated error                                                                                                 
     222               0 :                 if (is_file($errorPath))                                                                                                  
     223               0 :                 {                                                                                                                         
     224               0 :                     $error .= '; ' . file_get_contents($errorPath);                                                                       
     225               0 :                     unlink($errorPath);                                                                                                   
     226               0 :                 }                                                                                                                         
     227                 :                                                                                                                                           
     228               0 :                 break;                                                                                                                    
     229                 :             }                                                                                                                             
     230                 :                                                                                                                                           
     231                 :             // difference between two same transformation                                                                                 
     232               3 :             if ($repeatingIdx != 0)                                                                                                       
     233               3 :             {                                                                                                                             
     234               3 :                 if (file_get_contents($outputPath) == file_get_contents($outputPathNew))                                                  
     235               3 :                 {                                                                                                                         
     236               3 :                     unlink($outputPathNew);                                                                                               
     237               3 :                 }                                                                                                                         
     238                 :                 else                                                                                                                      
     239                 :                 {                                                                                                                         
     240               0 :                     $error = 'Difference between two same transformation: (' . $outputPath . ') != (' . $outputPathNew . ')';             
     241               0 :                     break;                                                                                                                
     242                 :                 }                                                                                                                         
     243               3 :             }                                                                                                                             
     244                 :                                                                                                                                           
     245                 :             // detect error                                                                                                               
     246               3 :             if (is_file($errorPath))                                                                                                      
     247               3 :             {                                                                                                                             
     248               0 :                 $error = file_get_contents($errorPath);                                                                                   
     249               0 :                 unlink($errorPath);                                                                                                       
     250               0 :             }                                                                                                                             
     251                 :             else                                                                                                                          
     252                 :             {                                                                                                                             
     253               3 :                 $error = '';                                                                                                              
     254                 :             }                                                                                                                             
     255                 :                                                                                                                                           
     256                 :             if ($error)                                                                                                                   
     257               3 :             {                                                                                                                             
     258               0 :                 break;                                                                                                                    
     259                 :             }                                                                                                                             
     260                 :                                                                                                                                           
     261                 :             // spend time                                                                                                                 
     262               3 :             $times[] = Microtime::substract($timeEnd, $timeStart);                                                                        
     263               3 :         }                                                                                                                                 
     264                 :                                                                                                                                           
     265                 :         if ($error)                                                                                                                       
     266               4 :         {                                                                                                                                 
     267               1 :             return $error;                                                                                                                
     268                 :         }                                                                                                                                 
     269                 :         else                                                                                                                              
     270                 :         {                                                                                                                                 
     271                 :             return array(                                                                                                                 
     272               3 :                 'times' => $times,                                                                                                        
     273                 :                 'memory' => $memoryList                                                                                                   
     274               3 :             );                                                                                                                            
     275                 :         }                                                                                                                                 
     276                 :     }                                                                                                                                     
     277                 :                                                                                                                                           
     278                 :                                                                                                                                           
     279                 :     // --- PRIVATE FUNCTIONS ---                                                                                                          
     280                 :                                                                                                                                           
     281                 :                                                                                                                                           
     282                 :     /**                                                                                                                                   
     283                 :      * Detect list of available names of processors                                                                                       
     284                 :      *                                                                                                                                    
     285                 :      * @return array ([name] => AProcessorDriver)                                                                                         
     286                 :      */                                                                                                                                   
     287                 :     private function detectAvailable()                                                                                                    
     288                 :     {                                                                                                                                     
     289               5 :         $driversFiles = scandir($this->driversDir);                                                                                       
     290                 :                                                                                                                                           
     291               5 :         $drivers = array();                                                                                                               
     292               5 :         foreach ($driversFiles as $driverFile)                                                                                            
     293                 :         {                                                                                                                                 
     294               5 :             if (in_array($driverFile, array('AProcessorDriver.php', '.', '..')))                                                          
     295               5 :             {                                                                                                                             
     296               5 :                 continue;                                                                                                                 
     297                 :             }                                                                                                                             
     298                 :                                                                                                                                           
     299                 :             // driver have to be php file                                                                                                 
     300               5 :             if (substr($driverFile, -4) !== '.php')                                                                                       
     301               5 :             {                                                                                                                             
     302               4 :                 continue;                                                                                                                 
     303                 :             }                                                                                                                             
     304                 :                                                                                                                                           
     305               5 :             require_once P::m($this->driversDir, $driverFile);                                                                            
     306               5 :             $className = $this->driversNamespace . substr($driverFile, 0, -4);                                                            
     307               5 :             $driver = new $className;                                                                                                     
     308                 :                                                                                                                                           
     309                 :             // driver have to be instance of AProcessorDriver                                                                             
     310               5 :             if (($driver instanceof AProcessorDriver) && ($driver->isAvailable()))                                                        
     311               5 :             {                                                                                                                             
     312               5 :                 $drivers[$driver->getName()] = $driver;                                                                                   
     313               5 :             }                                                                                                                             
     314               5 :         }                                                                                                                                 
     315                 :                                                                                                                                           
     316               5 :         return $drivers;                                                                                                                  
     317                 :     }                                                                                                                                     
     318                 :                                                                                                                                           
     319                 :                                                                                                                                           
     320                 :     /**                                                                                                                                   
     321                 :      * Read information about processors                                                                                                  
     322                 :      *                                                                                                                                    
     323                 :      * @return array                                                                                                                      
     324                 :      */                                                                                                                                   
     325                 :     private function readInformations()                                                                                                   
     326                 :     {                                                                                                                                     
     327               1 :         $informations = array();                                                                                                          
     328               1 :         foreach ($this->getAvailable() as $name => $processorDriver)                                                                      
     329                 :         {                                                                                                                                 
     330               1 :             $informations[$name] = $processorDriver->getInformations();                                                                   
     331               1 :         }                                                                                                                                 
     332                 :                                                                                                                                           
     333               1 :         return $informations;                                                                                                             
     334                 :     }                                                                                                                                     
     335                 :                                                                                                                                           
     336                 :                                                                                                                                           
     337                 :     /**                                                                                                                                   
     338                 :      * Make command from template                                                                                                         
     339                 :      *                                                                                                                                    
     340                 :      * Templates substitutions:                                                                                                           
     341                 :      * [XSLT] = path of XSLT template for transformation                                                                                  
     342                 :      * [INPUT] = path of input XML file                                                                                                   
     343                 :      * [OUTPUT] = path of generated output XML file                                                                                       
     344                 :      * [ERROR] = path of file for eventual generated error message                                                                        
     345                 :      * [PROCESSORS] = path of directory containing XSLT processors (libraries, command-line program etc.)                                 
     346                 :      * [LIBS] = path of Libs directory                                                                                                    
     347                 :      *                                                                                                                                    
     348                 :      * @param string $commandTemplate Template of command                                                                                 
     349                 :      * @param string $templatePath Path of XSLT template for transformation                                                               
     350                 :      * @param string $xmlInputPath Path of input XML file                                                                                 
     351                 :      * @param string $outputPath Path of generated output XML file                                                                        
     352                 :      * @param string $errorPath Path of file for eventual generated error message                                                         
     353                 :      *                                                                                                                                    
     354                 :      * @return string                                                                                                                     
     355                 :      */                                                                                                                                   
     356                 :     private function getCommand($commandTemplate, $templatePath, $xmlInputPath, $outputPath, $errorPath)                                  
     357                 :     {                                                                                                                                     
     358               8 :         $command = $commandTemplate;                                                                                                      
     359                 :                                                                                                                                           
     360                 :         // replace substitutions                                                                                                          
     361               8 :         $command = str_replace('[XSLT]', $templatePath, $command);                                                                        
     362               8 :         $command = str_replace('[INPUT]', $xmlInputPath, $command);                                                                       
     363               8 :         $command = str_replace('[OUTPUT]', $outputPath, $command);                                                                        
     364               8 :         $command = str_replace('[ERROR]', $errorPath, $command);                                                                          
     365               8 :         $command = str_replace('[PROCESSORS]', P::m(LIBS, 'Processors'), $command);                                                       
     366               8 :         $command = str_replace('[LIBS]', P::m(LIBS), $command);                                                                           
     367                 :                                                                                                                                           
     368               8 :         return $command;                                                                                                                  
     369                 :     }                                                                                                                                     
     370                 :                                                                                                                                           
     371                 :                                                                                                                                           
     372                 :     /**                                                                                                                                   
     373                 :      * Add into input XML path of template by directive "<?xml-stylesheet href="[XSLT]" type="text/xml" ..."                              
     374                 :      * and return path of generated file (in temporary directory).                                                                        
     375                 :      *                                                                                                                                    
     376                 :      * @param string $xmlInputPath Path of input XML                                                                                      
     377                 :      * @param string $templatePath Path of template                                                                                       
     378                 :      *                                                                                                                                    
     379                 :      * @return string                                                                                                                     
     380                 :      */                                                                                                                                   
     381                 :     private function makeInputWithTemplatePath($xmlInputPath, $templatePath)                                                              
     382                 :     {                                                                                                                                     
     383               1 :         $content = file_get_contents($xmlInputPath);                                                                                      
     384                 :                                                                                                                                           
     385                 :         // add template path                                                                                                              
     386               1 :         $content = str_replace(                                                                                                           
     387               1 :             '<?xml version="1.0" encoding="UTF-8"?>',                                                                                     
     388               1 :             '<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="' . $templatePath . '" ?>',                     
     389                 :             $content                                                                                                                      
     390               1 :         );                                                                                                                                
     391                 :                                                                                                                                           
     392               1 :         $xmlInputPath = P::m($this->tmpDir, basename($xmlInputPath));                                                                     
     393               1 :         file_put_contents($xmlInputPath, $content);                                                                                       
     394                 :                                                                                                                                           
     395               1 :         return $xmlInputPath;                                                                                                             
     396                 :     }                                                                                                                                     
     397                 :                                                                                                                                           
     398                 :                                                                                                                                           
     399                 : }                                                                                                                                         


Generated by PHP_CodeCoverage @package_version@ using PHP 5.3.6 and PHPUnit @package_version@ at Tue Jun 26 15:06:55 CEST 2012.