/** * Main * * Exitcodes used: * <ul> * <li>127: Archive referenced in -xar [...] does not exist</li> * <li>126: No manifest or manifest does not have a main-class</li> * </ul> * * @see http://tldp.org/LDP/abs/html/exitcodes.html * @param string[] args * @return int */ public static function main(array $args) { // Open archive $f = new File(array_shift($args)); if (!$f->exists()) { Console::$err->writeLine('*** Cannot find archive ' . $f->getURI()); return 127; } // Register class loader $cl = ClassLoader::registerLoader(new ArchiveClassLoader(new Archive($f))); if (!$cl->providesResource(self::MANIFEST)) { Console::$err->writeLine('*** Archive ' . $f->getURI() . ' does not have a manifest'); return 126; } // Load manifest $pr = Properties::fromString($cl->getResource(self::MANIFEST)); if (NULL === ($class = $pr->readString('archive', 'main-class', NULL))) { Console::$err->writeLine('*** Archive ' . $f->getURI() . '\'s manifest does not have a main class'); return 126; } // Run main() try { return XPClass::forName($class, $cl)->getMethod('main')->invoke(NULL, array($args)); } catch (TargetInvocationException $e) { throw $e->getCause(); } }
/** * Prepare "environment" for invocation on bean method. Configures * the PropertyManager (always), the Logger (if log.ini has been provided * with the bean) and ConnectionManager (if database.ini has been provided * with the bean). * */ protected function prepare() { if ($this->configuration['log.ini']) { Logger::getInstance()->configure(Properties::fromString($this->configuration['cl']->getResource('etc/log.ini'))); } if ($this->configuration['database.ini']) { ConnectionManager::getInstance()->configure(Properties::fromString($this->configuration['cl']->getResource('etc/database.ini'))); } }
/** * Returns an instance with a given number of DSNs * * @param [:string] dsns * @return rdbms.ConnectionManager */ protected function instanceWith($dsns) { $properties = ''; foreach ($dsns as $name => $dsn) { $properties .= '[' . $name . "]\ndsn=\"" . $dsn . "\"\n"; } $cm = ConnectionManager::getInstance(); $cm->configure(Properties::fromString($properties)); return $cm; }
/** * Set up testcase * */ public function setUp() { $this->dsn = Properties::fromString($this->getClass()->getPackage()->getResource('database.ini'))->readString($this->_dsn(), 'dsn', NULL); if (NULL === $this->dsn) { throw new PrerequisitesNotMetError('No credentials for ' . $this->getClassName()); } try { $this->conn = DriverManager::getConnection($this->dsn); } catch (Throwable $t) { throw new PrerequisitesNotMetError($t->getMessage(), $t); } }
/** * Sets up test case * */ public function setUp() { $this->dsn = Properties::fromString($this->getClass()->getPackage()->getResource('database.ini'))->readString($this->_dsn(), 'dsn', NULL); if (NULL === $this->dsn) { throw new PrerequisitesNotMetError('No credentials for ' . $this->getClassName()); } try { $this->dropTables(); $this->createTables(); } catch (Throwable $e) { throw new PrerequisitesNotMetError($e->getMessage(), $e); } }
/** * Get a list of deployments * * @return remote.server.deploy.Deployable[] */ public function scanDeployments() { clearstatcache(); $this->changed = FALSE; while ($entry = $this->folder->getEntry()) { if (!preg_match($this->pattern, $entry)) { continue; } $f = new File($this->folder->getURI() . $entry); if (isset($this->files[$entry]) && $f->lastModified() <= $this->files[$entry]) { // File already deployed continue; } $this->changed = TRUE; $ear = new Archive(new File($this->folder->getURI() . $entry)); try { $ear->open(ARCHIVE_READ) && ($meta = $ear->extract('META-INF/bean.properties')); } catch (Throwable $e) { $this->deployments[$entry] = new IncompleteDeployment($entry, $e); continue; } $prop = Properties::fromString($meta); $beanclass = $prop->readString('bean', 'class'); if (!$beanclass) { $this->deployments[$entry] = new IncompleteDeployment($entry, new FormatException('bean.class property missing!')); continue; } $d = new Deployment($entry); $d->setClassLoader(new ArchiveClassLoader($ear)); $d->setImplementation($beanclass); $d->setInterface($prop->readString('bean', 'remote')); $d->setDirectoryName($prop->readString('bean', 'lookup')); $this->deployments[$entry] = $d; $this->files[$entry] = time(); delete($f); } // Check existing deployments foreach (array_keys($this->deployments) as $entry) { $f = new File($this->folder->getURI() . $entry); if (!$f->exists()) { unset($this->deployments[$entry], $this->files[$entry]); $this->changed = TRUE; } delete($f); } $this->folder->close(); return $this->changed; }
/** * Main method * * @param util.cmd.ParamString params * @return int */ public function run(ParamString $params) { // No arguments given - show our own usage if ($params->count < 1) { self::$err->writeLine(self::textOf(XPClass::forName(xp::nameOf(__CLASS__))->getComment())); return 1; } // Configure properties $pm = PropertyManager::getInstance(); // Separate runner options from class options for ($offset = 0, $i = 0; $i < $params->count; $i++) { switch ($params->list[$i]) { case '-c': if (0 == strncmp('res://', $params->list[$i + 1], 6)) { $pm->appendSource(new ResourcePropertySource(substr($params->list[$i + 1], 6))); } else { $pm->appendSource(new FilesystemPropertySource($params->list[$i + 1])); } $offset += 2; $i++; break; case '-cp': ClassLoader::registerPath($params->list[$i + 1], NULL); $offset += 2; $i++; break; case '-v': $this->verbose = TRUE; $offset += 1; $i++; break; default: break 2; } } // Sanity check if (!$params->exists($offset)) { self::$err->writeLine('*** Missing classname'); return 1; } // Use default path for PropertyManager if no sources set if (!$pm->getSources()) { $pm->configure(self::DEFAULT_CONFIG_PATH); } unset($params->list[-1]); $classname = $params->value($offset); $classparams = new ParamString(array_slice($params->list, $offset + 1)); // Class file or class name if (strstr($classname, xp::CLASS_FILE_EXT)) { $file = new File($classname); if (!$file->exists()) { self::$err->writeLine('*** Cannot load class from non-existant file ', $classname); return 1; } $uri = $file->getURI(); $path = dirname($uri); $paths = array_flip(array_map('realpath', xp::$classpath)); $class = NULL; while (FALSE !== ($pos = strrpos($path, DIRECTORY_SEPARATOR))) { if (isset($paths[$path])) { $class = XPClass::forName(strtr(substr($uri, strlen($path) + 1, -10), DIRECTORY_SEPARATOR, '.')); break; } $path = substr($path, 0, $pos); } if (!$class) { self::$err->writeLine('*** Cannot load class from ', $file); return 1; } } else { try { $class = XPClass::forName($classname); } catch (ClassNotFoundException $e) { self::$err->writeLine('*** ', $this->verbose ? $e : $e->getMessage()); return 1; } } // Check whether class is runnable if (!$class->isSubclassOf('lang.Runnable')) { self::$err->writeLine('*** ', $class->getName(), ' is not runnable'); return 1; } // Usage if ($classparams->exists('help', '?')) { self::showUsage($class); return 0; } // Load, instantiate and initialize $l = Logger::getInstance(); $pm->hasProperties('log') && $l->configure($pm->getProperties('log')); $cm = ConnectionManager::getInstance(); $pm->hasProperties('database') && $cm->configure($pm->getProperties('database')); // Setup logger context for all registered log categories foreach (Logger::getInstance()->getCategories() as $category) { if (NULL === ($context = $category->getContext()) || !$context instanceof EnvironmentAware) { continue; } $context->setHostname(System::getProperty('host.name')); $context->setRunner($this->getClassName()); $context->setInstance($class->getName()); $context->setResource(NULL); $context->setParams($params->string); } $instance = $class->newInstance(); $instance->in = self::$in; $instance->out = self::$out; $instance->err = self::$err; $methods = $class->getMethods(); // Injection foreach ($methods as $method) { if (!$method->hasAnnotation('inject')) { continue; } $inject = $method->getAnnotation('inject'); if (isset($inject['type'])) { $type = $inject['type']; } else { if ($restriction = $method->getParameter(0)->getTypeRestriction()) { $type = $restriction->getName(); } else { $type = $method->getParameter(0)->getType()->getName(); } } try { switch ($type) { case 'rdbms.DBConnection': $args = array($cm->getByHost($inject['name'], 0)); break; case 'util.Properties': $p = $pm->getProperties($inject['name']); // If a PropertyAccess is retrieved which is not a util.Properties, // then, for BC sake, convert it into a util.Properties if ($p instanceof PropertyAccess && !$p instanceof Properties) { $convert = Properties::fromString(''); $section = $p->getFirstSection(); while ($section) { // HACK: Properties::writeSection() would first attempts to // read the whole file, we cannot make use of it. $convert->_data[$section] = $p->readSection($section); $section = $p->getNextSection(); } $args = array($convert); } else { $args = array($p); } break; case 'util.log.LogCategory': $args = array($l->getCategory($inject['name'])); break; default: self::$err->writeLine('*** Unknown injection type "' . $type . '" at method "' . $method->getName() . '"'); return 2; } $method->invoke($instance, $args); } catch (TargetInvocationException $e) { self::$err->writeLine('*** Error injecting ' . $type . ' ' . $inject['name'] . ': ' . $e->getCause()->compoundMessage()); return 2; } catch (Throwable $e) { self::$err->writeLine('*** Error injecting ' . $type . ' ' . $inject['name'] . ': ' . $e->compoundMessage()); return 2; } } // Arguments foreach ($methods as $method) { if ($method->hasAnnotation('args')) { // Pass all arguments if (!$method->hasAnnotation('args', 'select')) { $begin = 0; $end = $classparams->count; $pass = array_slice($classparams->list, 0, $end); } else { $pass = array(); foreach (preg_split('/, ?/', $method->getAnnotation('args', 'select')) as $def) { if (is_numeric($def) || '-' == $def[0]) { $pass[] = $classparams->value((int) $def); } else { sscanf($def, '[%d..%d]', $begin, $end); isset($begin) || ($begin = 0); isset($end) || ($end = $classparams->count - 1); while ($begin <= $end) { $pass[] = $classparams->value($begin++); } } } } try { $method->invoke($instance, array($pass)); } catch (Throwable $e) { self::$err->writeLine('*** Error for arguments ' . $begin . '..' . $end . ': ', $this->verbose ? $e : $e->getMessage()); return 2; } } else { if ($method->hasAnnotation('arg')) { // Pass arguments $arg = $method->getAnnotation('arg'); if (isset($arg['position'])) { $name = '#' . ($arg['position'] + 1); $select = intval($arg['position']); $short = NULL; } else { if (isset($arg['name'])) { $name = $select = $arg['name']; $short = isset($arg['short']) ? $arg['short'] : NULL; } else { $name = $select = strtolower(preg_replace('/^set/', '', $method->getName())); $short = isset($arg['short']) ? $arg['short'] : NULL; } } if (0 == $method->numParameters()) { if (!$classparams->exists($select, $short)) { continue; } $args = array(); } else { if (!$classparams->exists($select, $short)) { list($first, ) = $method->getParameters(); if (!$first->isOptional()) { self::$err->writeLine('*** Argument ' . $name . ' does not exist!'); return 2; } $args = array(); } else { $args = array($classparams->value($select, $short)); } } try { $method->invoke($instance, $args); } catch (TargetInvocationException $e) { self::$err->writeLine('*** Error for argument ' . $name . ': ', $this->verbose ? $e->getCause() : $e->getCause()->compoundMessage()); return 2; } } } } try { $instance->run(); } catch (Throwable $t) { self::$err->writeLine('*** ', $t->toString()); return 70; // EX_SOFTWARE according to sysexits.h } return 0; }
public function mappingWithoutCorrespondingSection() { with($p = Properties::fromString('')); $p->writeSection('app'); $p->writeString('app', 'map.service', '/service'); create(new xp·scriptlet·WebConfiguration($p))->mappedApplications(); }
public function memoryPropertiesAlwaysHavePrecendenceInCompositeProperties() { $fixture = $this->preconfigured(); $this->assertEquals('value', $fixture->getProperties('example')->readString('section', 'key')); $fixture->register('example', Properties::fromString('[section] key="overwritten value"')); $this->assertEquals('overwritten value', $fixture->getProperties('example')->readString('section', 'key')); }
public function injectCompositeProperties() { $command = newinstance('util.cmd.Command', array(), '{ #[@inject(name= "debug")] public function setTrace(Properties $prop) { $this->out->write("Have ", $prop->readString("section", "key")); } public function run() { // Intentionally empty } }'); $this->runWith(array($command->getClassName()), '', array(new RegisteredPropertySource('debug', Properties::fromString('[section] key=overwritten_value')), new FilesystemPropertySource(__DIR__))); $this->assertEquals('', $this->err->getBytes()); $this->assertEquals('Have overwritten_value', $this->out->getBytes()); }
public function equalsReturnsTrueForSameInnerPropertiesAndName() { $p1 = new RegisteredPropertySource('name1', Properties::fromString('[section]')); $p2 = new RegisteredPropertySource('name1', Properties::fromString('[section]')); $this->assertEquals($p1, $p2); }
/** * Create a new properties object from a string source * * @param string source * @return util.Properties */ protected function newPropertiesFrom($source) { return Properties::fromString($source); }
public function configureWithContext() { $this->logger->configure(Properties::fromString(trim(' [context] appenders="util.log.FileAppender" context="util.log.context.NestedLogContext" appender.util.log.FileAppender.params="filename" appender.util.log.FileAppender.param.filename="/var/log/xp/default.log" '))); with($cat = $this->logger->getCategory('context')); $this->assertTrue($cat->hasContext()); $this->assertInstanceOf('util.log.context.NestedLogContext', $cat->getContext()); }
public function addingToCompositeResetsIterationPointer() { $fixture = $this->getThirdSection(); $fixture->add(Properties::fromString('[unknown]')); $this->assertEquals(NULL, $fixture->getNextSection()); }
public function noApplication() { with($p = Properties::fromString('')); $p->writeSection('app'); $p->writeString('app', 'map.service', '/service'); $p->writeSection('app::service'); $r = new xp新criptlet愛unner('/htdocs'); $r->configure($p); $r->applicationAt('/'); }
fputs(STDERR, 'Uncaught exception: ' . xp::stringOf($e)); exit(0xff); } // }}} // Verify SAPI if ('cgi' === PHP_SAPI || 'cgi-fcgi' === PHP_SAPI) { ini_set('html_errors', 0); define('STDIN', fopen('php://stdin', 'rb')); define('STDOUT', fopen('php://stdout', 'wb')); define('STDERR', fopen('php://stderr', 'wb')); } else { if ('cli' !== PHP_SAPI) { trigger_error('[bootstrap] Cannot be run under ' . PHP_SAPI . ' SAPI', E_USER_ERROR); exit(0x3d); } } if (!(include __DIR__ . DIRECTORY_SEPARATOR . 'lang.base.php')) { trigger_error('[bootstrap] Cannot determine boot class path', E_USER_ERROR); exit(0x3d); } $home = getenv('HOME'); list($use, $include) = explode(PATH_SEPARATOR . PATH_SEPARATOR, get_include_path()); bootstrap(scanpath(explode(PATH_SEPARATOR, substr($use, 2) . PATH_SEPARATOR . '.'), $home) . $include); uses('util.cmd.ParamString', 'util.cmd.Console', 'util.Properties'); ini_set('error_prepend_string', EPREPEND_IDENTIFIER); set_exception_handler('__except'); ob_start('__output'); $cl = ClassLoader::registerLoader(new ArchiveClassLoader($argv[1])); $pr = Properties::fromString($cl->getResource('META-INF/manifest.ini')); array_shift($_SERVER['argv']); exit(XPClass::forName($pr->readString('archive', 'main-class'), $cl)->getMethod('main')->invoke(NULL, array(array_slice($argv, 2))));