<commit_before><?php

namespace BiSight\Etl\JobLoader;

use BiSight\Etl\Job;
use SimpleXMLElement;
use ReflectionClass;
use RuntimeException;
use DOMDocument;

class XmlJobLoader implements JobLoaderInterface
{
    public function loadFile($filename)
    {
        if (!file_exists($filename)) {
            throw new RuntimeException("Jobs file not found: " . $filename);
        }
        
        $xml = file_get_contents($filename);
        
        $dom = new DOMDocument;
        $dom->loadXML($xml);
        $dom->documentURI = $filename;
        $dom->xinclude();
        $dom->formatOutput = true;
        $dom->preserveWhiteSpace = false;

        //echo $dom->saveXML(); exit();
        $element = simplexml_import_dom($dom);
        return $this->load($element);
    }

    public function load(SimpleXMLElement $xml)
    {
        $jobs = array();
        foreach ($xml->job as $jobNode) {
            $job = new Job();
            
            $job->setName((string)$jobNode['name']);
            
            foreach ($jobNode->extractor as $extractorNode) {
                $instance = $this->getInstanceByNode($extractorNode);
                $job->setExtractor($instance);
            }
            
            foreach ($jobNode->loader as $loaderNode) {
                $instance = $this->getInstanceByNode($loaderNode);
                $job->addLoader($instance);
            }

            foreach ($jobNode->transform as $transformNode) {
                $instance = $this->getInstanceByNode($transformNode);
                $job->addTransform($instance);
            }
            $jobs[] = $job;
        }

        return $jobs;
    }
    
    private function getInstanceByNode(SimpleXMLElement $node)
    {
        $className = (string)$node->class;
        $reflector = new ReflectionClass($className);<commit_msg>Transparently support job and jobs root elements<commit_after><?php

namespace BiSight\Etl\JobLoader;

use BiSight\Etl\Job;
use SimpleXMLElement;
use ReflectionClass;
use RuntimeException;
use DOMDocument;

class XmlJobLoader implements JobLoaderInterface
{
    public function loadFile($filename)
    {
        if (!file_exists($filename)) {
            throw new RuntimeException("Jobs file not found: " . $filename);
        }
        
        $xml = file_get_contents($filename);
        
        $dom = new DOMDocument;
        $dom->loadXML($xml);
        $dom->documentURI = $filename;
        $dom->xinclude();
        $dom->formatOutput = true;
        $dom->preserveWhiteSpace = false;

        //echo $dom->saveXML(); exit();
        $element = simplexml_import_dom($dom);
        switch ($element->getName()) {
            case 'job':
                $jobs = array();
                $jobs[] = $this->loadJob($element);
                break;
            case 'jobs':
                $jobs = $this->loadJobs($element);
                break;
            default:
                throw new RuntimeException(
                    "Unsupported root element (should be job or jobs): " .
                    $element->getName()
                );
        }
        return $jobs;
    }

    public function loadJob(SimpleXMLElement $jobNode)
    {
        $job = new Job();
        
        $job->setName((string)$jobNode['name']);
        
        foreach ($jobNode->extractor as $extractorNode) {
            $instance = $this->getInstanceByNode($extractorNode);
            $job->setExtractor($instance);
        }
        
        foreach ($jobNode->loader as $loaderNode) {
            $instance = $this->getInstanceByNode($loaderNode);
            $job->addLoader($instance);
        }

        foreach ($jobNode->transform as $transformNode) {
            $instance = $this->getInstanceByNode($transformNode);
            $job->addTransform($instance);
        }
        return $job;

    }
    public function loadJobs(SimpleXMLElement $xml)
    {
        $jobs = array();
        foreach ($xml->job as $jobNode) {
            $job = $this->loadJob($jobNode);
            $jobs[] = $job;
        }
        return $jobs;
    }
    
    private function getInstanceByNode(SimpleXMLElement $node)
    {
        $className = (string)$node->class;
        $reflector = new ReflectionClass($className);
{'fraction_non_alphanumeric': 0.12561750176429076, 'fraction_numerical': 0.0, 'mean_word_length': 1.9203296703296704, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3078680', 'n_tokens_mistral': 1170, 'n_tokens_neox': 1134, 'n_words': 234}