Overview

Packages

  • log4php
    • appenders
    • configurators
    • filters
    • helpers
    • layouts
    • pattern
    • renderers

Classes

  • LoggerConfigurationAdapterINI
  • LoggerConfigurationAdapterPHP
  • LoggerConfigurationAdapterXML

Interfaces

  • LoggerConfigurationAdapter
  • Overview
  • Package
  • Class
  • Tree
  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:  * Converts XML configuration files to a PHP array.
 23:  * 
 24:  * @package log4php
 25:  * @subpackage configurators
 26:  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 27:  * @version $Revision: 1394956 $
 28:  * @since 2.2
 29:  */
 30: class LoggerConfigurationAdapterXML implements LoggerConfigurationAdapter
 31: {
 32:     /** Path to the XML schema used for validation. */
 33:     const SCHEMA_PATH = '/../xml/log4php.xsd';
 34:     
 35:     private $config = array(
 36:         'appenders' => array(),
 37:         'loggers' => array(),
 38:         'renderers' => array(),
 39:     );
 40:     
 41:     public function convert($url) {
 42:         $xml = $this->loadXML($url);
 43:         
 44:         $this->parseConfiguration($xml);
 45: 
 46:         // Parse the <root> node
 47:         if (isset($xml->root)) {        
 48:             $this->parseRootLogger($xml->root);
 49:         }
 50:         
 51:         // Process <logger> nodes
 52:         foreach($xml->logger as $logger) {
 53:             $this->parseLogger($logger);
 54:         } 
 55:         
 56:         // Process <appender> nodes
 57:         foreach($xml->appender as $appender) {
 58:             $this->parseAppender($appender);
 59:         }
 60:         
 61:         // Process <renderer> nodes
 62:         foreach($xml->renderer as $rendererNode) {
 63:             $this->parseRenderer($rendererNode);
 64:         }
 65: 
 66:         // Process <defaultRenderer> node
 67:         foreach($xml->defaultRenderer as $rendererNode) {
 68:             $this->parseDefaultRenderer($rendererNode);
 69:         }
 70: 
 71:         return $this->config;
 72:     }
 73:     
 74:     /**
 75:      * Loads and validates the XML.
 76:      * @param string $url Input XML.
 77:      */
 78:     private function loadXML($url) {
 79:         if (!file_exists($url)) {
 80:             throw new LoggerException("File [$url] does not exist.");
 81:         }
 82: 
 83:         libxml_clear_errors();
 84:         $oldValue = libxml_use_internal_errors(true);
 85:         
 86:         // Load XML
 87:         $xml = @simplexml_load_file($url);
 88:         if ($xml === false) {
 89:             
 90:             $errorStr = "";
 91:             foreach(libxml_get_errors() as $error) {
 92:                 $errorStr .= $error->message;
 93:             }
 94:             
 95:             throw new LoggerException("Error loading configuration file: " . trim($errorStr));
 96:         }
 97:         
 98:         libxml_clear_errors();
 99:         libxml_use_internal_errors($oldValue);
100:         
101:         return $xml;
102:     }
103:     
104:     /**
105:      * Parses the <configuration> node.
106:      */
107:     private function parseConfiguration(SimpleXMLElement $xml) {
108:         $attributes = $xml->attributes();
109:         if (isset($attributes['threshold'])) {
110:             $this->config['threshold'] = (string) $attributes['threshold'];
111:         }
112:     }
113:     
114:     /** Parses an <appender> node. */
115:     private function parseAppender(SimpleXMLElement $node) {
116:         $name = $this->getAttributeValue($node, 'name');
117:         if (empty($name)) {
118:             $this->warn("An <appender> node is missing the required 'name' attribute. Skipping appender definition.");
119:             return;
120:         }
121:         
122:         $appender = array();
123:         $appender['class'] = $this->getAttributeValue($node, 'class');
124:         
125:         if (isset($node['threshold'])) {
126:             $appender['threshold'] = $this->getAttributeValue($node, 'threshold');
127:         }
128:         
129:         if (isset($node->layout)) {
130:             $appender['layout']= $this->parseLayout($node->layout, $name);
131:         }
132:         
133:         if (count($node->param) > 0) {
134:             $appender['params'] = $this->parseParameters($node);
135:         }
136:         
137:         foreach($node->filter as $filterNode) {
138:             $appender['filters'][] = $this->parseFilter($filterNode);
139:         }
140:         
141:         $this->config['appenders'][$name] = $appender;
142:     }
143:     
144:     /** Parses a <layout> node. */
145:     private function parseLayout(SimpleXMLElement $node, $appenderName) {
146:         $layout = array();
147:         $layout['class'] = $this->getAttributeValue($node, 'class');
148:         
149:         if (count($node->param) > 0) {
150:             $layout['params'] = $this->parseParameters($node);
151:         }
152:         
153:         return $layout;
154:     }
155: 
156:     /** Parses any <param> child nodes returning them in an array. */
157:     private function parseParameters($paramsNode) {
158:         $params = array();
159: 
160:         foreach($paramsNode->param as $paramNode) {
161:             if (empty($paramNode['name'])) {
162:                 $this->warn("A <param> node is missing the required 'name' attribute. Skipping parameter.");
163:                 continue;
164:             }
165:             
166:             $name = $this->getAttributeValue($paramNode, 'name');
167:             $value = $this->getAttributeValue($paramNode, 'value');
168:             
169:             $params[$name] = $value;
170:         }
171: 
172:         return $params;
173:     }
174:     
175:     /** Parses a <root> node. */
176:     private function parseRootLogger(SimpleXMLElement $node) {
177:         $logger = array();
178:         
179:         if (isset($node->level)) {
180:             $logger['level'] = $this->getAttributeValue($node->level, 'value');
181:         }
182:         
183:         $logger['appenders'] = $this->parseAppenderReferences($node);
184:         
185:         $this->config['rootLogger'] = $logger;
186:     }
187:     
188:     /** Parses a <logger> node. */
189:     private function parseLogger(SimpleXMLElement $node) {
190:         $logger = array();
191:         
192:         $name = $this->getAttributeValue($node, 'name');
193:         if (empty($name)) {
194:             $this->warn("A <logger> node is missing the required 'name' attribute. Skipping logger definition.");
195:             return;
196:         }
197:         
198:         if (isset($node->level)) {
199:             $logger['level'] = $this->getAttributeValue($node->level, 'value');
200:         }
201:         
202:         if (isset($node['additivity'])) {
203:             $logger['additivity'] = $this->getAttributeValue($node, 'additivity');
204:         }
205:         
206:         $logger['appenders'] = $this->parseAppenderReferences($node);
207: 
208:         // Check for duplicate loggers
209:         if (isset($this->config['loggers'][$name])) {
210:             $this->warn("Duplicate logger definition [$name]. Overwriting.");
211:         }
212:         
213:         $this->config['loggers'][$name] = $logger;
214:     }
215:     
216:     /** 
217:      * Parses a <logger> node for appender references and returns them in an array.
218:      * 
219:      * Previous versions supported appender-ref, as well as appender_ref so both
220:      * are parsed for backward compatibility.
221:      */
222:     private function parseAppenderReferences(SimpleXMLElement $node) {
223:         $refs = array();
224:         foreach($node->appender_ref as $ref) {
225:             $refs[] = $this->getAttributeValue($ref, 'ref');
226:         }
227:         
228:         foreach($node->{'appender-ref'} as $ref) {
229:             $refs[] = $this->getAttributeValue($ref, 'ref');
230:         }
231: 
232:         return $refs;
233:     }
234:     
235:     /** Parses a <filter> node. */
236:     private function parseFilter($filterNode) {
237:         $filter = array();
238:         $filter['class'] = $this->getAttributeValue($filterNode, 'class');
239:         
240:         if (count($filterNode->param) > 0) {
241:             $filter['params'] = $this->parseParameters($filterNode);
242:         }
243:         
244:         return $filter;
245:     }
246:     
247:     /** Parses a <renderer> node. */
248:     private function parseRenderer(SimpleXMLElement $node) {
249:         $renderedClass = $this->getAttributeValue($node, 'renderedClass');
250:         $renderingClass = $this->getAttributeValue($node, 'renderingClass');
251:         
252:         $this->config['renderers'][] = compact('renderedClass', 'renderingClass');
253:     }
254:     
255:     /** Parses a <defaultRenderer> node. */
256:     private function parseDefaultRenderer(SimpleXMLElement $node) {
257:         $renderingClass = $this->getAttributeValue($node, 'renderingClass');
258:         
259:         // Warn on duplicates
260:         if(isset($this->config['defaultRenderer'])) {
261:             $this->warn("Duplicate <defaultRenderer> node. Overwriting.");
262:         }
263:         
264:         $this->config['defaultRenderer'] = $renderingClass; 
265:     }
266:     
267:     // ******************************************
268:     // ** Helper methods                       **
269:     // ******************************************
270:     
271:     private function getAttributeValue(SimpleXMLElement $node, $name) {
272:         return isset($node[$name]) ? (string) $node[$name] : null;
273:     }
274:     
275:     private function warn($message) {
276:         trigger_error("log4php: " . $message, E_USER_WARNING);
277:     }
278: }
279: 
280: 
Apache log4php API documentation generated by ApiGen 2.8.0