Esempio n. 1
0
 /**
  * Read and process file, read dependencies if exist.
  *
  * @param[in] $filename Name of the file to parse and interpet.
  * @param[out] $extendedFiles List of files additionaly loaded via `extends_file` directive.
  */
 public static function parseFile($filename, &$extendedFiles = null)
 {
     $schema = static::annotateSchema(\Smalldb\StateMachine\Utils::parse_json_file($filename), false);
     $extends_file = isset($schema['extends_file']) ? dirname($filename) . '/' . $schema['extends_file'] : null;
     while ($extends_file !== null) {
         if ($extendedFiles !== null) {
             $extendedFiles[] = $extends_file;
         }
         $part = static::annotateSchema(\Smalldb\StateMachine\Utils::parse_json_file($extends_file), str_replace('.schema.json', '', basename($extends_file)));
         $extends_file = isset($part['extends_file']) ? dirname($extends_file) . '/' . $part['extends_file'] : null;
         $schema = static::extendSchema($part, $schema);
     }
     if (isset($schema['extends_file'])) {
         unset($schema['extends_file']);
     }
     return $schema;
 }
Esempio n. 2
0
 /**
  * Constructor compatible with cascade resource factory.
  */
 public function __construct($options, $context = null, $alias)
 {
     parent::__construct($options, $context, $alias);
     // Get base dir (constants are available)
     $this->base_dir = rtrim(Utils::filename_format($options['base_dir'], array()), '/') . '/';
     // Load machine definitions from APC cache
     if (!empty($options['cache_disabled'])) {
         $cache_loaded = false;
         $cache_mtime = 0;
         $cache_disabled = true;
     } else {
         $cache_disabled = false;
         $cache_key = __CLASS__ . ':' . $alias . ':' . $this->base_dir;
         $cache_data = apc_fetch($cache_key, $cache_loaded);
         if ($cache_loaded) {
             list($this->machine_type_table, $cache_mtime) = $cache_data;
             //debug_dump($this->machine_type_table, 'Cached @ '.strftime('%F %T', $cache_mtime));
         }
     }
     // Scan base dir for machines and find youngest file
     $dh = opendir($this->base_dir);
     if (!$dh) {
         throw new RuntimeException('Cannot open base dir: ' . $this->base_dir);
     }
     $youngest_mtime = filemtime(__FILE__);
     // Make sure cache gets regenerated when this file is changed
     $file_list = array();
     while (($file = readdir($dh)) !== false) {
         if ($file[0] != '.') {
             $file_list[] = $file;
         }
         $mtime = filemtime($this->base_dir . $file);
         if ($youngest_mtime < $mtime) {
             $youngest_mtime = $mtime;
         }
     }
     closedir($dh);
     // Load data if cache is obsolete
     if (!$cache_loaded || $youngest_mtime >= $cache_mtime) {
         //debug_msg('Machine type table cache miss. Reloading...');
         $this->machine_type_table = array();
         // Find all machine types
         foreach ($file_list as $file) {
             @(list($machine_type, $ext) = explode('.', $file, 2));
             switch ($ext) {
                 case 'json':
                 case 'json.php':
                     $filename = $this->base_dir . $file;
                     $this->machine_type_table[$machine_type] = JsonReader::loadString(file_get_contents($filename), [], $filename);
                     break;
             }
         }
         ksort($this->machine_type_table);
         // Load all included files
         foreach ($this->machine_type_table as $machine_type => $json_config) {
             $graphml_reader_used = false;
             $bpmn_reader_used = false;
             $machine_def =& $this->machine_type_table[$machine_type];
             foreach ((array) @$json_config['include'] as $include) {
                 // String is filename
                 if (!is_array($include)) {
                     $include_file = $include;
                     $include_opts = array();
                 } else {
                     $include_file = $include['file'];
                     $include_opts = $include;
                 }
                 // Relative path is relative to base directory
                 if ($include_file[0] != '/') {
                     $include_file = $this->base_dir . $include_file;
                 }
                 // Detect file type and use proper loader
                 // FIXME: Replace this with extendible loading infrastructure.
                 if (preg_match('/\\.json\\(\\.php\\)\\?$/i', $include_file)) {
                     // Include JSON file (simple merge)
                     $machine_def = array_replace_recursive(JsonReader::loadString(file_get_contents($include_file), $include_opts, $include_file), $machine_def);
                 } else {
                     if (preg_match('/\\.graphml$/i', $include_file)) {
                         // Include GraphML file (find states and transitions, then simply add them to the definition)
                         $machine_def = array_replace_recursive(GraphMLReader::loadString(file_get_contents($include_file), $include_opts, $include_file), $machine_def);
                         $graphml_reader_used = true;
                     } else {
                         if (preg_match('/\\.bpmn$/i', $include_file)) {
                             // Load relevant fragment of BPMN diagram, it will be merged with other fragments and added to the definition later.
                             $machine_def = array_replace_recursive(BpmnReader::loadString(file_get_contents($include_file), $include_opts, $include_file), $machine_def);
                             $bpmn_reader_used = true;
                         } else {
                             throw new RuntimeException('Unknown file format: ' . $include_file);
                         }
                     }
                 }
             }
             if ($graphml_reader_used) {
                 GraphMLReader::postprocessDefinition($machine_def);
             }
             if ($bpmn_reader_used) {
                 BpmnReader::postprocessDefinition($machine_def);
             }
             JsonReader::postprocessDefinition($machine_def);
             unset($machine_def);
         }
         if (!$cache_disabled) {
             apc_store($cache_key, array($this->machine_type_table, time()));
         }
     }
 }