/**
  * @param string $name_
  * @param array $args_
  *
  * @return \Components\Enumeration
  *
  * @throws \Components\Runtime_Exception
  */
 public static function __callStatic($name_, array $args_ = [])
 {
     $type = get_called_class();
     if (__CLASS__ === $type) {
         throw new Exception_Abstract_Type('components/enumeration', 'Enumeration can not be invoked directly.');
     }
     if (isset(self::$m_enumInstances[$type][$name_])) {
         return self::$m_enumInstances[$type][$name_];
     }
     if (false === isset(self::$m_enums[$type])) {
         self::initializeType($type);
     }
     if (false === array_key_exists($name_, self::$m_enums[$type])) {
         $trace = debug_backtrace(false);
         $caller = $trace[1];
         throw new Exception_NotImplemented('components/enumeration', sprintf('Call to undefined method %1$s::%2$s() in %3$s on line %4$d.', $type, $name_, $caller['file'], $caller['line']));
     }
     if (!($concrete = Runtime_Classloader::lookup(String::typeToNamespace($type) . '/' . String::typeToPath($name_)))) {
         $concrete = $type;
     }
     if (0 < count($args_)) {
         array_unshift($args_, constant("{$type}::{$name_}"));
         array_unshift($args_, self::$m_enums[$type][$name_]);
         $class = new \ReflectionClass($concrete);
         return $class->newInstanceArgs($args_);
     }
     // Cache simple enum instances.
     // XXX Instances MUST be state-less.
     return self::$m_enumInstances[$type][$name_] = new $concrete(self::$m_enums[$type][$name_], constant("{$type}::{$name_}"));
 }
 /**
  * @GET
  * @POST
  */
 public function update()
 {
     foreach (Runtime_Classloader::get()->getClasspaths() as $type => $path) {
         if (Entity_Default::TYPE !== $type) {
             $class = new \ReflectionClass($type);
             if ($class->isSubclassOf('Components\\Entity')) {
                 $this->updateForEntity($type);
             }
         }
     }
 }
 private static function initializeMethods()
 {
     if (false === (self::$m_methods = Cache::get('components/rest/methods'))) {
         self::$m_methods = [];
     }
     foreach (self::$m_resources as $resource) {
         if (isset(self::$m_methods[$resource])) {
             continue;
         }
         $annotations = Annotations::get($resource);
         foreach ($annotations->getMethodAnnotations() as $methodName => $methodAnnotations) {
             $httpMethods = [];
             foreach ($methodAnnotations as $methodAnnotationName => $methodAnnotation) {
                 if ($methodAnnotation instanceof Annotation_Method) {
                     $httpMethods[$methodAnnotationName] = $methodAnnotationName;
                 }
             }
             if (count($httpMethods)) {
                 $type = new \ReflectionClass($resource);
                 $method = $type->getMethod($methodName);
                 $parameters = $method->getParameters();
                 $path = [];
                 $query = [];
                 foreach ($parameters as $parameter) {
                     $parameterAnnotations = $annotations->getParameterAnnotations($methodName, $parameter->name);
                     if (isset($parameterAnnotations[Annotation_Param_Query::NAME])) {
                         if (isset($parameterAnnotations[Annotation_Param_Query::NAME]->name)) {
                             $name = $parameterAnnotations[Annotation_Param_Query::NAME]->name;
                         } else {
                             $name = $parameter->name;
                         }
                         if (isset($parameterAnnotations[Annotation_Param_Query::NAME]->type)) {
                             $type = $parameterAnnotations[Annotation_Param_Query::NAME]->type;
                             if (Primitive::isNative($type)) {
                                 $type = Primitive::asBoxed($type);
                             } else {
                                 if ($lookupType = Runtime_Classloader::lookup($type)) {
                                     $type = $lookupType;
                                 }
                             }
                         } else {
                             if ($type = $parameter->getClass()) {
                                 $type = $type->name;
                             } else {
                                 $type = String::TYPE;
                             }
                         }
                         if (isset($parameterAnnotations[Annotation_Param_Query::NAME]->default)) {
                             $value = $parameterAnnotations[Annotation_Param_Query::NAME]->default;
                         } else {
                             $value = null;
                         }
                         $query[$parameter->name] = ['name' => $name, 'type' => $type, 'value' => $value];
                     } else {
                         if ($parameter->isOptional()) {
                             if ($type = $parameter->getClass()) {
                                 $query[$parameter->name] = $type->name;
                             } else {
                                 $query[$parameter->name] = String::TYPE;
                             }
                         } else {
                             if (isset($parameterAnnotations[Annotation_Param_Path::NAME]->type)) {
                                 $type = $parameterAnnotations[Annotation_Param_Path::NAME]->type;
                                 if (Primitive::isNative($type)) {
                                     $type = Primitive::asBoxed($type);
                                 } else {
                                     if ($lookupType = Runtime_Classloader::lookup($type)) {
                                         $type = $lookupType;
                                     }
                                 }
                                 $path[$parameter->name] = $type;
                             } else {
                                 if ($type = $parameter->getClass()) {
                                     $path[$parameter->name] = $type->name;
                                 } else {
                                     $path[$parameter->name] = String::TYPE;
                                 }
                             }
                         }
                     }
                 }
                 $matches = [];
                 preg_match('/\\@return\\s+([\\a-z]+)\\n/i', $method->getDocComment(), $matches);
                 $return = null;
                 if (isset($matches[1])) {
                     $return = $matches[1];
                 }
                 self::$m_methods[$resource][$methodName] = ['name' => $methodName, 'methods' => $httpMethods, 'path' => $path, 'query' => $query, 'return' => $return];
             }
         }
     }
     Cache::set('components/rest/methods', self::$m_methods);
 }
 /**
  * Parses and caches annotations for given name of an annotated type if
  * not already cached.
  *
  * Retrieves neccessary information from cache and builds & returns
  * an instance of Annotations.
  *
  * @param string $type_ Name of annotated type.
  *
  * @return \Components\Annotations
  */
 private static function resolveInstance($type_)
 {
     if (0 === strpos($type_, '\\')) {
         $type_ = ltrim($type_, '\\');
     }
     $cacheKeyType = 'components/type/annotations/' . md5($type_);
     if (false === ($cached = Cache::get($cacheKeyType))) {
         // Pays off if classloader cache is built sufficiently ...
         if (!($typeLocation = Runtime_Classloader::get()->getClasspath($type_))) {
             $cacheKeyTypeLocation = "{$cacheKeyType}/file";
             // ... yet requires fallback for out-of-control classloaders (e.g. during unit test execution).
             if (false === ($typeLocation = Cache::get($cacheKeyTypeLocation))) {
                 $type = new \ReflectionClass($type_);
                 $typeLocation = $type->getFileName();
                 Cache::set($cacheKeyTypeLocation, $typeLocation);
             }
         }
         $annotations = self::parseAnnotations($typeLocation);
         foreach ($annotations as $type => $typeAnnotations) {
             Cache::set($cacheKeyType, $typeAnnotations);
         }
         $instance = new self($type_);
         $instance->m_annotations = $annotations[$type_];
     } else {
         $instance = new self($type_);
         $instance->m_annotations = $cached;
     }
     return $instance;
 }
 protected function initialize()
 {
     $a = Annotations::get($this->entityType);
     $this->entityName = Runtime_Classloader::lookupName($this->entityType);
     if ($annotation = $a->getTypeAnnotation(Annotation_Name::NAME)) {
         $this->collectionName = $a->getTypeAnnotation(Annotation_Name::NAME)->value;
     } else {
         $this->collectionName = strtolower(substr($this->entityType, strrpos($this->entityType, '_') + 1));
     }
     if ($annotation = $a->getTypeAnnotation(Annotation_Collection::NAME)) {
         $this->collectionType = Runtime_Classloader::lookup($annotation->value);
     } else {
         $this->collectionType = Entity_Collection::TYPE;
     }
     $this->autoIncrement = true;
     foreach ($a->getPropertyAnnotations() as $property => $annotations) {
         if (isset($annotations[Annotation_Id::NAME])) {
             $this->collectionPrimaryKey = $property;
             $this->collectionPrimaryKeyAutoIncrement = Boolean::valueIsTrue($annotations[Annotation_Id::NAME]->auto);
         }
     }
 }
 /**
  * Generates EMMA code coverage report.
  *
  * @param array $xDebugReport_
  *
  * @todo Implement
  */
 protected function report(Test_Runner $runner_, array $xDebugReport_)
 {
     $testPaths = $runner_->getTestPaths();
     $classpaths = [];
     foreach (Runtime_Classloader::getClassloaders() as $classloader) {
         $classpaths = array_merge($classpaths, $classloader->getClasspaths());
     }
     $emmaReport = [];
     foreach ($classpaths as $clazz => $path) {
         if (isset($testPaths[$path])) {
             continue;
         }
         $this->reportForClass($clazz, $path, $xDebugReport_, $emmaReport);
     }
     $document = new \DOMDocument('1.0', 'utf-8');
     $document->formatOutput = true;
     $report = $document->createElement('report');
     $document->appendChild($report);
     $stats = $document->createElement('stats');
     $report->appendChild($stats);
     $statsPackages = $document->createElement('packages');
     $statsPackages->setAttribute('value', count($this->m_packages));
     $stats->appendChild($statsPackages);
     $statsClasses = $document->createElement('classes');
     $statsClasses->setAttribute('value', count($this->m_classes));
     $stats->appendChild($statsClasses);
     $statsMethods = $document->createElement('methods');
     $statsMethods->setAttribute('value', count($this->m_methods));
     $stats->appendChild($statsMethods);
     $statsFiles = $document->createElement('srcfiles');
     $statsFiles->setAttribute('value', count($this->m_files));
     $stats->appendChild($statsFiles);
     $statsLines = $document->createElement('srclines');
     $statsLines->setAttribute('value', $this->m_lines);
     $stats->appendChild($statsLines);
     $data = $document->createElement('data');
     $report->appendChild($data);
     $all = $document->createElement('all');
     $all->setAttribute('name', 'all classes');
     $data->appendChild($all);
     $countLines = 0;
     $countLinesCovered = 0;
     $countClasses = 0;
     $countClassesCovered = 0;
     $countMethods = 0;
     $countMethodsCovered = 0;
     foreach ($emmaReport as $package) {
         foreach ($package as $files) {
             foreach ($files as $clazz) {
                 $countClasses++;
                 $countLines += $clazz['lines'];
                 $countLinesCovered += $clazz['covered'];
                 if (0 < $clazz['covered']) {
                     $countClassesCovered++;
                 }
                 foreach ($clazz['methods'] as $method) {
                     $countMethods++;
                     if (0 < $method['covered']) {
                         $countMethodsCovered++;
                     }
                 }
             }
         }
     }
     $this->appendCoverage($document, $all, 'class, %', $countClasses, $countClassesCovered);
     $this->appendCoverage($document, $all, 'method, %', $countMethods, $countMethodsCovered);
     $this->appendCoverage($document, $all, 'block, %', $countMethods, $countMethodsCovered);
     $this->appendCoverage($document, $all, 'line, %', $countLines, $countLinesCovered);
     foreach (array_keys($emmaReport) as $package) {
         $this->appendPackage($document, $all, $package, $emmaReport[$package]);
     }
     $document->save($this->m_buildPath);
 }