function entry(&$argv) { if (is_file($argv[0])) { if (0 === substr_compare($argv[0], '.class.php', -10)) { $uri = realpath($argv[0]); if (null === ($cl = \lang\ClassLoader::getDefault()->findUri($uri))) { throw new \Exception('Cannot load ' . $uri . ' - not in class path'); } return $cl->loadUri($uri)->literal(); } else { if (0 === substr_compare($argv[0], '.xar', -4)) { $cl = \lang\ClassLoader::registerPath($argv[0]); if (!$cl->providesResource('META-INF/manifest.ini')) { throw new \Exception($cl->toString() . ' does not provide a manifest'); } $manifest = parse_ini_string($cl->getResource('META-INF/manifest.ini')); return strtr($manifest['main-class'], '.', '\\'); } else { array_unshift($argv, 'eval'); return 'xp\\runtime\\Evaluate'; } } } else { return strtr($argv[0], '.', '\\'); } }
/** * Constructor * * @param lang.ClassLoader classLoader */ public function __construct($classLoader = null) { if (null === $classLoader) { $this->classLoader = ClassLoader::getDefault(); } else { $this->classLoader = $classLoader; } }
/** * Creates a new class source * * @param string $class Dotted fully qualified name * @throws lang.ClassFormatException */ public function __construct($class) { $cl = ClassLoader::getDefault()->findClass($class); if ($cl instanceof IClassLoader) { $this->tokenize($cl->loadClassBytes($class), $class); } else { $this->tokens = null; } }
/** * Get all test cases * * @param var[] arguments * @return unittest.TestCase[] */ public function testCasesWith($arguments) { $uri = $this->file->getURI(); $cl = \lang\ClassLoader::getDefault()->findUri($uri); if (is(null, $cl)) { throw new IllegalArgumentException('Cannot load class from ' . $this->file->toString()); } return $this->testCasesInClass($cl->loadUri($uri), $arguments); }
/** * Creates a fixrture * * @return util.PropertyManager */ private function fixture() { $class = ClassLoader::getDefault()->defineClass('NonSingletonPropertyManager', PropertyManager::class, [], '{ public static function newInstance() { return new self(); } }'); return $class->getMethod('newInstance')->invoke(null); }
/** * Constructor * * @param io.File file * @throws lang.IllegalArgumentException if the given file does not exist */ public function __construct(File $file) { $uri = $file->getURI(); $cl = ClassLoader::getDefault()->findUri($uri); if ($cl === null) { throw new IllegalArgumentException('File "' . $uri . ($file->exists() ? '" is not in class path' : '" not found')); } $this->loader = $cl; $this->uri = $uri; }
/** * Locate a class * * @param string[] packages * @param string name * @return string qualified * @throws lang.ElementNotFoundException */ public function locateClass($packages, $local) { $cl = ClassLoader::getDefault(); foreach ($packages as $package) { $qualified = $package . '.' . $local; if (!$cl->providesClass($qualified) && !$this->manager->findClass($qualified)) { continue; } return $qualified; } throw new ElementNotFoundException('Could not locate class ' . $local . ' in ' . \xp::stringOf($packages)); }
/** * Setup method. * * @param string package * @param string stateName * @param string functionality * @param [:var] params default array() */ public function __construct($package, $stateName, $functionality, $params = []) { static $i = 0; parent::__construct($package); // Generate unique classname and put it into the environment // That way, the classloader will already know this class in // WorkflowScriptletRequest::initialize() and be able to load // and instantiate it. $stateName = 'Mock__' . $i++ . $stateName; $this->state = \lang\ClassLoader::getDefault()->defineClass($package . '.mock.state.' . $stateName . 'State', 'scriptlet.xml.workflow.AbstractState', [], $functionality)->newInstance(); $_SERVER['STATE'] = $stateName; // Set some defaults $_SERVER['PRODUCT'] = 'xp'; $_SERVER['LANGUAGE'] = 'en_US'; }
/** * Accessor method for a type matcher. * * @param typeName string */ public static function anyOfType($typeName) { $builder = new MockProxyBuilder(); $builder->setOverwriteExisting(false); $interfaces = [XPClass::forName('unittest.mock.arguments.IArgumentMatcher')]; $parentClass = null; $type = XPClass::forName($typeName); if ($type->isInterface()) { $interfaces[] = $type; } else { $parentClass = $type; } $proxyClass = $builder->createProxyClass(ClassLoader::getDefault(), $interfaces, $parentClass); return $proxyClass->newInstance(new TypeMatcher($typeName)); }
/** * Builds a stub instance for the specified type. * * @param string typeName * @param boolean overrideAll * @return lang.Object */ public function createMock($typeName, $overrideAll = true) { $type = Type::forName($typeName); if (!$type instanceof XPClass) { throw new IllegalArgumentException('Cannot mock other types than XPClass types.'); } $parentClass = null; $interfaces = [XPClass::forName('unittest.mock.IMock')]; if ($type->isInterface()) { $interfaces[] = $type; } else { $parentClass = $type; } $proxy = new MockProxyBuilder(); $proxy->setOverwriteExisting($overrideAll); $proxyClass = $proxy->createProxyClass(ClassLoader::getDefault(), $interfaces, $parentClass); $mock = $proxyClass->newInstance(new MockProxy()); $this->mocks[] = $mock; return $mock; }
/** * Constructor */ public function __construct() { $this->marshallers = create('new util.collections.HashTable<lang.Type, webservices.rest.TypeMarshaller>'); // Deprecated! if (PHP_VERSION < 7 && ClassLoader::getDefault()->providesPackage('lang.types')) { $strings = newinstance('webservices.rest.TypeMarshaller', [], ['marshal' => function ($t) { return $t->toString(); }, 'unmarshal' => function (Type $target, $in) { return $target->newInstance($in); }]); $integers = newinstance('webservices.rest.TypeMarshaller', [], ['marshal' => function ($t) { return $t->intValue(); }, 'unmarshal' => function (Type $target, $in) { return $target->newInstance($in); }]); $decimals = newinstance('webservices.rest.TypeMarshaller', [], ['marshal' => function ($t) { return $t->doubleValue(); }, 'unmarshal' => function (Type $target, $in) { return $target->newInstance($in); }]); $booleans = newinstance('webservices.rest.TypeMarshaller', [], ['marshal' => function ($t) { return (bool) $t->value; }, 'unmarshal' => function (Type $target, $in) { return $target->newInstance($in); }]); $this->marshallers[XPClass::forName('lang.types.String')] = $strings; $this->marshallers[XPClass::forName('lang.types.Character')] = $strings; $this->marshallers[XPClass::forName('lang.types.Long')] = $integers; $this->marshallers[XPClass::forName('lang.types.Integer')] = $integers; $this->marshallers[XPClass::forName('lang.types.Short')] = $integers; $this->marshallers[XPClass::forName('lang.types.Byte')] = $integers; $this->marshallers[XPClass::forName('lang.types.Float')] = $decimals; $this->marshallers[XPClass::forName('lang.types.Double')] = $decimals; $this->marshallers[XPClass::forName('lang.types.Boolean')] = $booleans; } $this->marshallers[XPClass::forName('lang.Enum')] = newinstance('webservices.rest.TypeMarshaller', [], ['marshal' => function ($t) { return $t->name(); }, 'unmarshal' => function (Type $target, $in) { return Enum::valueOf($target, (string) $in); }]); }
/** * Find a command by a given name * * @param string $name * @return lang.XPClass * @throws lang.ClassNotFoundException * @throws lang.IllegalArgumentException if class is not runnable */ public static function named($name) { $cl = ClassLoader::getDefault(); if (is_file($name)) { $class = $cl->loadUri($name); } else { if (strstr($name, '.')) { $class = $cl->loadClass($name); } else { if ($package = self::locateNamed($name)) { $class = $package->loadClass($name); } else { $class = $cl->loadClass($name); } } } // Check whether class is runnable if (!$class->isSubclassOf('lang.Runnable')) { throw new IllegalArgumentException($class->getName() . ' is not runnable'); } return $class; }
/** * Main * * @param string[] $args * @return int */ public static function main($args) { $name = array_shift($args); if (null === $name) { Console::$err->writeLine('*** No class or package name given'); return 1; } // Check whether a file, class or a package directory or name is given $cl = ClassLoader::getDefault(); try { if (strstr($name, \xp::CLASS_FILE_EXT)) { $info = new TypeInformation($cl->loadUri(realpath($name))); } else { if (is_dir($name)) { $info = new DirectoryInformation($name); } else { if ($cl->providesClass($name)) { $info = new TypeInformation($cl->loadClass($name)); } else { if ($cl->providesPackage($name)) { $info = new PackageInformation($name); } else { Console::$err->writeLine('*** No classloader provides ' . $name); return 2; } } } } } catch (IllegalArgumentException $e) { Console::$err->writeLine('*** ' . $e->getMessage()); return 2; } foreach ($info->sources() as $source) { Console::writeLine("[33m@", $source, "[0m"); } $info->display(new Highlighting(Console::$out, ['/(class|enum|trait|interface|package|directory) (.+)/' => "[1;35m\$1[0m \$2", '/(extends|implements) (.+)/' => "[1;35m\$1[0m \$2", '/(public|private|protected|abstract|final|static)/' => "[1;35m\$1[0m", '/(\\$[a-zA-Z0-9_]+)/' => "[1;31m\$1[0m"])); return 0; }
/** * Main * * @param string[] args */ public static function main(array $args) { if (sizeof($args) < 1 || '' == $args[0]) { Console::$err->writeLine('*** No class or package name given'); return 2; } // Check whether a file, class or a package directory or name is given $cl = \lang\ClassLoader::getDefault(); if (strstr($args[0], \xp::CLASS_FILE_EXT)) { $class = $cl->loadUri(realpath($args[0])); } else { if ($cl->providesClass($args[0])) { $class = XPClass::forName($args[0], $cl); } else { if (strcspn($args[0], '\\/') < strlen($args[0])) { $package = self::findPackageBy(new Folder($args[0])); } else { $package = $args[0]; } $provided = false; foreach (\lang\ClassLoader::getLoaders() as $loader) { if (!$loader->providesPackage($package)) { continue; } Console::writeLine('@', $loader); $provided = true; } if ($provided) { self::printPackage(\lang\reflect\Package::forName($package)); return 0; } // Not found Console::$err->writeLine('*** Failed to locate either a class or a package named "', $args[0], '", tried all of {'); foreach (\lang\ClassLoader::getLoaders() as $loader) { Console::$err->writeLine(' ', $loader); } Console::$err->writeLine('}'); return 1; } } Console::writeLine('@', $class->getClassLoader()); if ($class->isInterface()) { self::printInterface($class); } else { if ($class->isEnum()) { self::printEnum($class); } else { self::printClass($class); } } return 0; }
/** * Open a database * * @return info.keepass.KeePassDatabase */ protected function database() { return KeePassDatabase::open(ClassLoader::getDefault()->getResourceAsStream('fixtures/' . $this->fixture . '.kdbx')->in(), new Key($this->fixture)); }
/** * Changes the value of the field represented by this Field, on the * specified object. * * @param object instance * @param var value * @throws lang.IllegalArgumentException in case the passed object is not an instance of the declaring class * @throws lang.IllegalAccessException in case this field is not public */ public function set($instance, $value) { if (null !== $instance && !$instance instanceof $this->_class) { throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', XPClass::nameOf($this->_class), \xp::typeOf($instance))); } // Check modifiers. If scope is an instance of this class, allow // protected method invocation (which the PHP reflection API does // not). $m = $this->_reflect->getModifiers(); $public = $m & MODIFIER_PUBLIC; if (!$public && !$this->accessible) { $t = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1); $scope = $t[1]['class'] ?? \lang\ClassLoader::getDefault()->loadUri($t[0]['file'])->literal(); $decl = $this->_reflect->getDeclaringClass()->getName(); if ($m & MODIFIER_PROTECTED) { $allow = $scope === $decl || is_subclass_of($scope, $decl); } else { $allow = $scope === $decl; } if (!$allow) { throw new IllegalAccessException(sprintf('Cannot write %s %s::$%s from scope %s', Modifiers::stringOf($this->getModifiers()), XPClass::nameOf($this->_class), $this->_reflect->getName(), $scope)); } } try { $public || $this->_reflect->setAccessible(true); $this->_reflect->setValue($instance, $value); } catch (\lang\Throwable $e) { throw $e; } catch (\Throwable $e) { throw new \lang\XPException($e->getMessage()); } }
/** * Returns a class loader resource * * @param string $name * @return io.streams.InputStream */ private function resourceNamed($name) { return ClassLoader::getDefault()->getResourceAsStream($name)->in(); }
public function reserved_methods_should_not_be_overridden() { $proxyBuilder = new MockProxyBuilder(); $proxyBuilder->setOverwriteExisting(true); $class = $proxyBuilder->createProxyClass(\lang\ClassLoader::getDefault(), [], \lang\XPClass::forName('net.xp_framework.unittest.tests.mock.AbstractDummy')); $proxy = $class->newInstance($this->handler); $proxy->equals(new \lang\Object()); $this->assertFalse(isset($this->handler->invocations['equals_1'])); }
public function nullInterfaces7() { Proxy::getProxyClass(ClassLoader::getDefault(), null); }
/** * Returns details for a given package. Note: Results from this method * are cached. * * @param string package * @return [:var] details or NULL */ public static function detailsForPackage($package) { if (!isset(\xp::$meta[$package])) { $cl = ClassLoader::getDefault(); $info = strtr($package, '.', '/') . '/package-info.xp'; if (!$cl->providesResource($info)) { return null; } $tokens = token_get_all($cl->getResource($info)); $details = []; $comment = null; for ($i = 0, $s = sizeof($tokens); $i < $s; $i++) { switch ($tokens[$i][0]) { case T_DOC_COMMENT: $comment = $tokens[$i][1]; break; case T_STRING: if ('package' === $tokens[$i][1]) { $details[DETAIL_COMMENT] = trim(preg_replace('/\\n \\* ?/', "\n", "\n" . substr($comment, 4, strpos($comment, '* @') - 2))); } break; } } \xp::$meta[$package] = $details; } return \xp::$meta[$package]; }
public function nonExistantResourceStream() { \lang\ClassLoader::getDefault()->getResourceAsStream('::DOES-NOT-EXIST::'); }
public function default_classloader_provides_packaged_of_defined_type() { $this->assertTrue(ClassLoader::getDefault()->providesPackage($this->define()->getPackage()->getName())); }
public function templates_in_package($package) { $loader = new ResourcesIn(ClassLoader::getDefault()); $this->assertEquals(['com/github/mustache/unittest/template'], $loader->listing()->package($package)->templates()); }
/** * Sets up test */ public function setUp() { $this->fixture = ClassLoader::getDefault()->getResourceAsStream(self::DATABASE)->in(); }
public function withPositionalOptionListenerOption() { $class = ClassLoader::getDefault()->defineClass('unittest.tests.WithPositionalOptionTestFixture', 'xp.unittest.DefaultListener', [], '{ public static $options= []; #[@arg(position= 0)] public function setOption($value) { self::$options[__FUNCTION__]= $value; } }'); $return = $this->runner->run(['-l', $class->getName(), '-', '-o', 'value']); $this->assertEquals(['setOption' => 'value'], $class->getField('options')->get(null)); }
<?php namespace xp; if (version_compare(PHP_VERSION, '5.4.0', '<')) { trigger_error('This version of the XP Framework requires PHP 5.4.0+, have PHP ' . PHP_VERSION, E_USER_ERROR); exit(0x3d); } $p = max(strrpos(__FILE__, DIRECTORY_SEPARATOR), strrpos(__FILE__, '?')); require_once substr(__FILE__, 0, $p + 1) . 'lang.base.php'; \lang\ClassLoader::getDefault();
public function loadNonExistantUri() { \lang\ClassLoader::getDefault()->loadUri('non/existant/Class.class.php'); }
/** * 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) { return self::usage(); } // 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': \lang\ClassLoader::registerPath($params->list[$i + 1], null); $offset += 2; $i++; break; case '-v': $this->verbose = true; $offset += 1; $i++; break; case '-?': return self::usage(); 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 \io\File($classname); if (!$file->exists()) { self::$err->writeLine('*** Cannot load class from non-existant file ', $classname); return 1; } try { $class = \lang\ClassLoader::getDefault()->loadUri($file->getURI()); } catch (\lang\ClassNotFoundException $e) { self::$err->writeLine('*** ', $this->verbose ? $e : $e->getMessage()); return 1; } } else { try { $class = \lang\XPClass::forName($classname); } catch (\lang\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')); if (class_exists('rdbms\\DBConnection')) { // FIXME: Job of XPInjector? $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(\lang\System::getProperty('host.name')); $context->setRunner(nameof($this)); $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 = [$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 \util\PropertyAccess && !$p instanceof \util\Properties) { $convert = \util\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 = [$convert]; } else { $args = [$p]; } break; case 'util.log.LogCategory': $args = [$l->getCategory($inject['name'])]; break; default: self::$err->writeLine('*** Unknown injection type "' . $type . '" at method "' . $method->getName() . '"'); return 2; } $method->invoke($instance, $args); } catch (\lang\reflect\TargetInvocationException $e) { self::$err->writeLine('*** Error injecting ' . $type . ' ' . $inject['name'] . ': ' . $e->getCause()->compoundMessage()); return 2; } catch (\lang\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 = []; 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, [$pass]); } catch (\lang\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 = []; } else { if (!$classparams->exists($select, $short)) { list($first, ) = $method->getParameters(); if (!$first->isOptional()) { self::$err->writeLine('*** Argument ' . $name . ' does not exist!'); return 2; } $args = []; } else { $args = [$classparams->value($select, $short)]; } } try { $method->invoke($instance, $args); } catch (\lang\reflect\TargetInvocationException $e) { self::$err->writeLine('*** Error for argument ' . $name . ': ', $this->verbose ? $e->getCause() : $e->getCause()->compoundMessage()); return 2; } } } } try { $instance->run(); } catch (\lang\Throwable $t) { self::$err->writeLine('*** ', $t->toString()); return 70; // EX_SOFTWARE according to sysexits.h } return 0; }
/** * Finds a class by a given class name * * @param string classname * @return lang.IClassLoader the classloader providing the class */ public function findClass($classname) { foreach (\lang\ClassLoader::getDefault()->getLoaders() as $loader) { if ($loader->providesClass($classname)) { return $loader; } } return null; }
/** * Retrieve associated loader * * @return lang.IClassLoader */ protected function getLoader() { return ClassLoader::getDefault(); }