      1: <?php
      2: /**
      3:  * Licensed to the Apache Software Foundation (ASF) under one or more
      4:  * contributor license agreements. See the NOTICE file distributed with
      5:  * this work for additional information regarding copyright ownership.
      6:  * The ASF licenses this file to You under the Apache License, Version 2.0
      7:  * (the "License"); you may not use this file except in compliance with
      8:  * the License. You may obtain a copy of the License at
      9:  *
     10:  *     http://www.apache.org/licenses/LICENSE-2.0
     11:  *
     12:  * Unless required by applicable law or agreed to in writing, software
     13:  * distributed under the License is distributed on an "AS IS" BASIS,
     14:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15:  * See the License for the specific language governing permissions and
     16:  * limitations under the License.
     17:  *
     18:  * @package log4php
     19:  */
     20:
     21: /**
     22:  * Manages defined renderers and determines which renderer to use for a given
     23:  * input.
     24:  *
     25:  * @version $Revision: 1394956 $
     26:  * @package log4php
     27:  * @subpackage renderers
     28:  * @since 0.3
     29:  */
     30: class LoggerRendererMap {
     31:
     32:     /**
     33:      * Maps class names to appropriate renderers.
     34:      * @var array
     35:      */
     36:     private $map = array();
     37:
     38:     /**
     39:      * The default renderer to use if no specific renderer is found.
     40:      * @var LoggerRenderer
     41:      */
     42:     private $defaultRenderer;
     43:
     44:     public function __construct() {
     45:
     46:         // Set default config
     47:         $this->reset();
     48:     }
     49:
     50:     /**
     51:      * Adds a renderer to the map.
     52:      *
     53:      * If a renderer already exists for the given <var>$renderedClass</var> it
     54:      * will be overwritten without warning.
     55:      *
     56:      * @param string $renderedClass The name of the class which will be
     57:      *      rendered by the renderer.
     58:      * @param string $renderingClass The name of the class which will
     59:      *      perform the rendering.
     60:      */
     61:     public function addRenderer($renderedClass, $renderingClass) {
     62:         // Check the rendering class exists
     63:         if (!class_exists($renderingClass)) {
     64:             trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] not found.");
     65:             return;
     66:         }
     67:
     68:         // Create the instance
     69:         $renderer = new $renderingClass();
     70:
     71:         // Check the class implements the right interface
     72:         if (!($renderer instanceof LoggerRenderer)) {
     73:             trigger_error("log4php: Failed adding renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface.");
     74:             return;
     75:         }
     76:
     77:         // Convert to lowercase since class names in PHP are not case sensitive
     78:         $renderedClass = strtolower($renderedClass);
     79:
     80:         $this->map[$renderedClass] = $renderer;
     81:     }
     82:
     83:     /**
     84:      * Sets a custom default renderer class.
     85:      *
     86:      * TODO: there's code duplication here. This method is almost identical to
     87:      * addRenderer(). However, it has custom error messages so let it sit for
     88:      * now.
     89:      *
     90:      * @param string $renderingClass The name of the class which will
     91:      *      perform the rendering.
     92:      */
     93:     public function setDefaultRenderer($renderingClass) {
     94:         // Check the class exists
     95:         if (!class_exists($renderingClass)) {
     96:             trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] not found.");
     97:             return;
     98:         }
     99:
    100:         // Create the instance
    101:         $renderer = new $renderingClass();
    102:
    103:         // Check the class implements the right interface
    104:         if (!($renderer instanceof LoggerRenderer)) {
    105:             trigger_error("log4php: Failed setting default renderer. Rendering class [$renderingClass] does not implement the LoggerRenderer interface.");
    106:             return;
    107:         }
    108:
    109:         $this->defaultRenderer = $renderer;
    110:     }
    111:
    112:     /**
    113:      * Returns the default renderer.
    114:      * @var LoggerRenderer
    115:      */
    116:     public function getDefaultRenderer() {
    117:         return $this->defaultRenderer;
    118:     }
    119:
    120:     /**
    121:      * Finds the appropriate renderer for the given <var>input</var>, and
    122:      * renders it (i.e. converts it to a string).
    123:      *
    124:      * @param mixed $input Input to render.
    125:      * @return string The rendered contents.
    126:      */
    127:     public function findAndRender($input) {
    128:         if ($input === null) {
    129:             return null;
    130:         }
    131:
    132:         // For objects, try to find a renderer in the map
    133:         if(is_object($input)) {
    134:             $renderer = $this->getByClassName(get_class($input));
    135:             if (isset($renderer)) {
    136:                 return $renderer->render($input);
    137:             }
    138:         }
    139:
    140:         // Fall back to the default renderer
    141:         return $this->defaultRenderer->render($input);
    142:     }
    143:
    144:     /**
    145:      * Returns the appropriate renderer for a given object.
    146:      *
    147:      * @param mixed $object
    148:      * @return LoggerRenderer Or null if none found.
    149:      */
    150:     public function getByObject($object) {
    151:         if (!is_object($object)) {
    152:             return null;
    153:         }
    154:         return $this->getByClassName(get_class($object));
    155:     }
    156:
    157:     /**
    158:      * Returns the appropriate renderer for a given class name.
    159:      *
    160:      * If no renderer could be found, returns NULL.
    161:      *
    162:      * @param string $class
    163:      * @return LoggerRendererObject Or null if not found.
    164:      */
    165:     public function getByClassName($class) {
    166:         for(; !empty($class); $class = get_parent_class($class)) {
    167:             $class = strtolower($class);
    168:             if(isset($this->map[$class])) {
    169:                 return $this->map[$class];
    170:             }
    171:         }
    172:         return null;
    173:     }
    174:
    175:     /** Empties the renderer map. */
    176:     public function clear() {
    177:         $this->map = array();
    178:     }
    179:
    180:     /** Resets the renderer map to it's default configuration. */
    181:     public function reset() {
    182:         $this->defaultRenderer = new LoggerRendererDefault();
    183:         $this->clear();
    184:         $this->addRenderer('Exception', 'LoggerRendererException');
    185:     }
    186: }
    187: