diff --git a/library/log4php/renderers/LoggerRendererMap.php b/library/log4php/renderers/LoggerRendererMap.php new file mode 100644 --- /dev/null +++ b/library/log4php/renderers/LoggerRendererMap.php @@ -0,0 +1,186 @@ +reset(); + } + + /** + * Adds a renderer to the map. + * + * If a renderer already exists for the given $renderedClass it + * will be overwritten without warning. + * + * @param string $renderedClass The name of the class which will be + * rendered by the renderer. + * @param string $renderingClass The name of the class which will + * perform the rendering. + */ + public function addRenderer($renderedClass, $renderingClass) { + // Check the rendering class exists + if (!class_exists($renderingClass)) { + trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] not found."); + return; + } + + // Create the instance + $renderer = new $renderingClass(); + + // Check the class implements the right interface + if (!($renderer instanceof LoggerRenderer)) { + trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface."); + return; + } + + // Convert to lowercase since class names in PHP are not case sensitive + $renderedClass = strtolower($renderedClass); + + $this->map[$renderedClass] = $renderer; + } + + /** + * Sets a custom default renderer class. + * + * TODO: there's code duplication here. This method is almost identical to + * addRenderer(). However, it has custom error messages so let it sit for + * now. + * + * @param string $renderingClass The name of the class which will + * perform the rendering. + */ + public function setDefaultRenderer($renderingClass) { + // Check the class exists + if (!class_exists($renderingClass)) { + trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] not found."); + return; + } + + // Create the instance + $renderer = new $renderingClass(); + + // Check the class implements the right interface + if (!($renderer instanceof LoggerRenderer)) { + trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface."); + return; + } + + $this->defaultRenderer = $renderer; + } + + /** + * Returns the default renderer. + * @var LoggerRenderer + */ + public function getDefaultRenderer() { + return $this->defaultRenderer; + } + + /** + * Finds the appropriate renderer for the given input, and + * renders it (i.e. converts it to a string). + * + * @param mixed $input Input to render. + * @return string The rendered contents. + */ + public function findAndRender($input) { + if ($input === null) { + return null; + } + + // For objects, try to find a renderer in the map + if (is_object($input)) { + $renderer = $this->getByClassName(get_class($input)); + if (isset($renderer)) { + return $renderer->render($input); + } + } + + // Fall back to the default renderer + return $this->defaultRenderer->render($input); + } + + /** + * Returns the appropriate renderer for a given object. + * + * @param mixed $object + * @return LoggerRenderer Or null if none found. + */ + public function getByObject($object) { + if (!is_object($object)) { + return null; + } + return $this->getByClassName(get_class($object)); + } + + /** + * Returns the appropriate renderer for a given class name. + * + * If no renderer could be found, returns NULL. + * + * @param string $class + * @return LoggerRendererObject Or null if not found. + */ + public function getByClassName($class) { + for (; !empty($class); $class = get_parent_class($class)) { + $class = strtolower($class); + if (isset($this->map[$class])) { + return $this->map[$class]; + } + } + return null; + } + + /** Empties the renderer map. */ + public function clear() { + $this->map = array(); + } + + /** Resets the renderer map to it's default configuration. */ + public function reset() { + $this->defaultRenderer = new LoggerRendererDefault(); + $this->clear(); + $this->addRenderer('Exception', 'LoggerRendererException'); + } +}