/** * test container functions of classs map */ function testClassMapContainer() { // get the singleton class map factory $cmf =& epClassMapFactory::instance(); $this->assertTrue(isset($cmf)); // create a class map $cm_tb =& $cmf->make('epTestBase'); $this->assertTrue(isset($cm_tb)); // create class map children $num_children = 100; for ($i = 0; $i < $num_children; $i++) { // create class map 1 $child_name = sprintf('epTest%03d', $i); $cm_t =& $cmf->make($child_name); $this->assertTrue(isset($cm_t)); $this->assertTrue($cm_tb !== $cm_t); $cm_t->setParent($cm_tb); $this->assertTrue($cm_tb->addChild($cm_t)); } // check parent-child relationship $children = $cm_tb->getChildren(false, true); // false: non-recursive; true: sort $this->assertTrue(count($children) == $num_children); $i = 0; foreach ($children as $child) { $parent =& $child->getParent(); $this->assertTrue(isset($parent)); $this->assertTrue($parent->getName() == 'epTestBase'); $child_name = sprintf('epTest%03d', $i); $this->assertTrue($child->getName() == $child_name); $i++; } }
/** * Implement {@link epSingleton} interface * Forcefully destroy old instance (only used for tests). * After reset(), {@link instance()} returns a new instance. */ public static function destroy() { self::$instance = null; }
/** * Loads compiled info into manager * * According to compile options, 'force_compile' and 'auto_compile', * the method decides whether to recompile all or some of the class * files. * * @return boolean */ protected function _loadCompiled() { // get the compiled info if (!($rcmf = $this->getConfigOption('compiled_file'))) { throw new epExceptionManagerBase('Compiled file not specified'); return false; } // get the dir that holds the class map file if ($compiled_dir = $this->getConfigOption('compiled_dir')) { // if compiled dir is a relative path, make is absolute $compiled_dir = $this->getAbsolutePath($compiled_dir); $rcmf = $compiled_dir . '/' . $rcmf; } // check if force_compile is set if ($this->getConfigOption('force_compile')) { // if so, delete the compiled file to force compile if (file_exists($rcmf)) { @unlink($rcmf); } } // get the contetns of the runtime config map file $compiled_info = false; if (file_exists($rcmf)) { $compiled_info = file_get_contents($rcmf); } // unserializing compiled info into class map factory include_once EP_SRC_ORM . '/epClassMap.php'; if ($compiled_info) { // unserialize class map info $this->cmf =& epClassMapFactory::unserialize($compiled_info); if (!$this->cmf) { throw new epExceptionManagerBase('Cannot unserialize compiled info'); return false; } // only when auto compile do we check config file mtime if ($this->getConfigOption('auto_compile')) { // if config file is newer than compiled info if (filemtime($this->getConfigSource()) > filemtime($rcmf)) { // remove all classes to force recompile $this->cmf->removeAll(); } } } else { // simply get the class map factory instance $this->cmf =& epClassMapFactory::instance(); // remove all classes now $this->cmf->removeAll(); } // check if auto_compile is enabled if ($this->getConfigOption('auto_compile')) { $this->_compileAll(); } return true; }
/** * The major task of a parser: parse a file and build class maps * @param string $file file to be parsed * @param array classes to be parsed (all if not specified) * @return bool * @access public * @see token_get_all() */ public function parse($file, $classes = null) { // get instance of class map factory $this->cmf = epClassMapFactory::instance(); // check if file exists if (!file_exists($file)) { throw new epExceptionParser('File [' . $file . '] does not exist.'); return false; } // get file content $content = file_get_contents($file); if (empty($content)) { throw new epExceptionParser('File [' . $file . '] is empty.'); return false; } // set the classes to be parsed $this->classes_to_parse = $classes; // keep track of the current file and tokens $this->file = $file; // reset comment $this->comment = ''; // setup scanner if (!$this->scanner) { include_once EP_SRC_COMPILER . '/epScanner.php'; $this->scanner = new epScanner(); } // setup FSM if (!$this->setupFSM()) { throw new epExceptionParser('Failed to setup FSM. Quit parsing.'); return false; } // set input content to scanner $this->scanner->input($content); // go through tokens while (false !== ($this->token = $this->scanner->next())) { // get token name $token_name = $this->token; if (is_array($this->token)) { $token_name = token_name($this->token[0]); } // intercept comments if ($token_name == 'T_COMMENT' || $token_name == 'T_DOC_COMMENT') { $this->comment = $this->token[1]; continue; } // drive FSM with token name we care if (!in_array($token_name, epClassParser::$tokens_to_process)) { continue; } $this->fsm->process($token_name); } return true; }
/** * Filter a given array of input files and returns only * the newly modifed after last compile and those files * that have not been compiled * * @param array $input_files * @return array */ protected function getNewFiles($input_files) { // get class map factory if (!($cmf = epClassMapFactory::instance())) { return $input_files; } // get all class maps if (!($cms = $cmf->allMade())) { // recompile all if no class map found at all return $input_files; } // arrays to keep track of new files to parse $new_files = array(); // arrays to keep track of files compiled $compiled_files = array(); // go through each foreach ($cms as &$cm) { // get the source file if (!($f = $cm->getClassFile())) { continue; } // is file in input files? if (in_array($f, $input_files) && !in_array($f, $compiled_files)) { // a file that's been compiled $compiled_files[] = $f; } // skip classes no need to compile if ($cm->needRecompile() && !in_array($f, $new_files)) { $new_files[] = $f; } } // now get the uncompiled files $uncompiled_files = array_diff($input_files, $compiled_files); // return both uncompiled files and new files return array_merge($new_files, $uncompiled_files); }
/** * test epClassCompiler: auto-compile (compiles class loaded in memory) */ function testCompilerAuto() { // make input/output path absolute $this->c->setConfigOption('source_dirs', EP_TESTS . '/classes/bookstore/src'); // compile (static) $this->assertTrue($this->c->compile()); // get the class map file output by static compile $compiled_dir = $this->c->getConfigOption('compiled_dir'); $compiled_file_static = $this->c->getConfigOption('compiled_file'); // validate file $this->assertTrue(!empty($compiled_file_static)); // get class map factory $this->assertTrue($cmf = epClassMapFactory::instance()); // get all classes and include files from class map factory $this->assertTrue($cms = $cmf->allMade()); $class_files = array(); // array to key class-file pairs foreach ($cms as $cm) { $class_files[$cm->getName()] = $cm->getClassFile(); } // make sure we have some classes $this->assertTrue(!empty($class_files)); // auto-compile preparation: include all class files foreach ($class_files as $class => $file) { include_once $file; } $cmf_string_static = $this->_cmfToString($cmf); // -------------------------------------------------------------- // compile by passing class names // before auto-compile lets remove all class maps in class factory $cmf->removeAll(); // make sure there is no class map in class map factory $this->assertFalse($cms = $cmf->allMade()); $this->assertTrue(count($cms) == 0); // make up a new class file name $compiled_file_auto = $compiled_file_static . '.2'; // set config to use new class map file $this->c->setConfigOption('compiled_file', $compiled_file_auto); // auto-compile each class foreach ($class_files as $class => $file) { $this->assertTrue($this->c->compile($class)); } // get contents of the two class map files $class_map_content_static = file_get_contents($this->c->getAbsolutePath($compiled_dir) . '/' . $compiled_file_static); $this->assertTrue($class_map_content_static); $class_map_content_auto = file_get_contents($this->c->getAbsolutePath($compiled_dir) . '/' . $compiled_file_auto); $this->assertTrue($class_map_content_auto); // check if results of static-compiled and auto-compiled are the same $cmf_string_auto = $this->_cmfToString($cmf); $this->assertTrue($cmf_string_static == $cmf_string_auto); // -------------------------------------------------------------- // compile by passing objects // before auto-compile lets remove all class maps in class factory $cmf->removeAll(); // make sure there is no class map in class map factory $this->assertFalse($cms = $cmf->allMade()); $this->assertTrue(count($cms) == 0); // make up a new class file name $compiled_file_auto = $compiled_file_static . '.3'; // set config to use new class map file $this->c->setConfigOption('compiled_file', $compiled_file_auto); // auto-compile each class foreach ($class_files as $class => $file) { $this->assertTrue($o = new $class()); $this->assertTrue($this->c->compile($o)); } // get contents of the two class map files $class_map_content_static = file_get_contents($this->c->getAbsolutePath($compiled_dir) . '/' . $compiled_file_static); $this->assertTrue($class_map_content_static); $class_map_content_auto = file_get_contents($this->c->getAbsolutePath($compiled_dir) . '/' . $compiled_file_auto); $this->assertTrue($class_map_content_auto); // check if results of static-compiled and auto-compiled are the same $cmf_string_auto = $this->_cmfToString($cmf); $this->assertTrue($cmf_string_static == $cmf_string_auto); }
/** * Constructor * @param epConfig|array * @access public * @see epConfig */ public function __construct($config = null) { parent::__construct($config); $this->cmf = epClassMapFactory::instance(); }
/** * Initialization * @param bool $force whether to force initialization * @return bool * @throws epExceptionManagerBase */ protected function initialize($force = false) { // done if not forced, and class map and db factories are set if (!$force && $this->cmf && $this->dbf) { return true; } // get the runtime class map file if (!($rcmf = $this->getConfigOption('compiled_file'))) { throw new epExceptionManagerBase('Runtime class map file not specified'); return false; } // get the dir that holds the class map file if ($compiled_dir = $this->getConfigOption('compiled_dir')) { // if compiled dir is a relative path, make is absolute $compiled_dir = $this->getAbsolutePath($compiled_dir); $rcmf = $compiled_dir . '/' . $rcmf; } // check if force_compile is set if ($this->getConfigOption('force_compile')) { // if so, delete the compiled file to force compile if (file_exists($rcmf)) { @unlink($rcmf); } } // unserializing class map file into class map factory include_once EP_SRC_ORM . '/epClassMap.php'; // get the contetns of the runtime config map file $runtime_map_content = false; if (file_exists($rcmf)) { $runtime_map_content = file_get_contents($rcmf); } // if compiled runtime map content exists and config file is older than compiled if ($runtime_map_content && filemtime($this->getConfigSource()) < filemtime($rcmf)) { // unserialize class map info $this->cmf =& epClassMapFactory::unserialize($runtime_map_content); if (!$this->cmf) { throw new epExceptionManagerBase('Cannot unserialize runtime class mapping info'); return false; } // need to recompile new class files $this->_compileAll(); } else { // if no compiled class map file found, simply get the class map factory instance $this->cmf =& epClassMapFactory::instance(); // remove all classes now $this->cmf->removeAll(); // check if the source dir is set if ($source_dirs = $this->getConfigOption('source_dirs')) { // compile all if so $this->_compileAll(); } } // get the db factory include_once EP_SRC_DB . '/epDbObject.php'; if (!($this->dbf =& epDbFactory::instance())) { throw new epExceptionManagerBase('Cannot get db factory instance'); return false; } // remove all connections $this->dbf->removeAll(); // set the db lib to use $this->dbf->setDbLib($this->getConfigOption('db_lib')); return true; }