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 @@ +<?php +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @package log4php + */ + +/** + * Manages defined renderers and determines which renderer to use for a given + * input. + * + * @version $Revision: 1394956 $ + * @package log4php + * @subpackage renderers + * @since 0.3 + */ +class LoggerRendererMap { + + /** + * Maps class names to appropriate renderers. + * @var array + */ + private $map = array(); + + /** + * The default renderer to use if no specific renderer is found. + * @var LoggerRenderer + */ + private $defaultRenderer; + + public function __construct() { + + // Set default config + $this->reset(); + } + + /** + * Adds a renderer to the map. + * + * If a renderer already exists for the given <var>$renderedClass</var> 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 <var>input</var>, 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'); + } +}