Author: ihabunek
Date: Thu Aug 25 06:45:54 2011
New Revision: 1161411
URL: http://svn.apache.org/viewvc?rev=1161411&view=rev
Log:
Initial work on config adapters.
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd
Removed:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorBasic.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorIni.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorPhp.php
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfiguratorXml.php
Modified:
logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd
Modified:
logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php?rev=1161411&r1=1161410&r2=1161411&view=diff
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php
(original)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/Logger.php
Thu Aug 25 06:45:54 2011
@@ -53,11 +53,10 @@ class Logger {
'LoggerMDC' => '/LoggerMDC.php',
'LoggerNDC' => '/LoggerNDC.php',
'LoggerReflectionUtils' => '/LoggerReflectionUtils.php',
- 'LoggerConfigurator' => '/LoggerConfigurator.php',
- 'LoggerConfiguratorBasic' =>
'/configurators/LoggerConfiguratorBasic.php',
- 'LoggerConfiguratorIni' =>
'/configurators/LoggerConfiguratorIni.php',
- 'LoggerConfiguratorPhp' =>
'/configurators/LoggerConfiguratorPhp.php',
- 'LoggerConfiguratorXml' =>
'/configurators/LoggerConfiguratorXml.php',
+ 'LoggerConfigurator' => '/configurators/LoggerConfigurator.php',
+ 'LoggerConfigurationAdapter' =>
'/configurators/LoggerConfigurationAdapter.php',
+ 'LoggerConfigurationAdapterINI' =>
'/configurators/LoggerConfigurationAdapterINI.php',
+ 'LoggerConfigurationAdapterXML' =>
'/configurators/LoggerConfigurationAdapterXML.php',
'LoggerRoot' => '/LoggerRoot.php',
'LoggerAppender' => '/LoggerAppender.php',
'LoggerAppenderPool' => '/LoggerAppenderPool.php',
@@ -154,17 +153,7 @@ class Logger {
/** The logger hierarchy used by log4php. */
private static $hierarchy;
- /**
- * Name of the configurator class used to configure log4php.
- * Populated by {@link configure()} and used in {@link initialize()}.
- */
- private static $configurationClass = 'LoggerConfiguratorBasic';
-
- /**
- * Path to the configuration file which may be used by the configurator.
- * Populated by {@link configure()} and used in {@link initialize()}.
- */
- private static $configurationFile;
+ private static $configurator;
/** Inidicates if log4php has been initialized */
private static $initialized = false;
@@ -564,7 +553,7 @@ class Logger {
}
/**
- * Configures log4php by defining a configuration file and/or class.
+ * Configures log4php.
*
* This method needs to be called before the first logging event has
* occured. If this method is not called before then, the standard
@@ -581,25 +570,12 @@ class Logger {
* @param string $configurationFile path to the configuration file
* @param string $configurationClass name of the custom configurator
class
*/
- public static function configure($configurationFile = null,
$configurationClass = null ) {
- if($configurationClass === null && $configurationFile === null)
{
- self::$configurationClass = 'LoggerConfiguratorBasic';
- return;
- }
-
- if($configurationClass !== null) {
- self::$configurationFile = $configurationFile;
- self::$configurationClass = $configurationClass;
- return;
+ public static function configure($configuration) {
+ if (!isset(self::$configurator)) {
+ self::$configurator = new LoggerConfigurator();
}
- if (strtolower(substr( $configurationFile, -4 )) == '.xml') {
- self::$configurationFile = $configurationFile;
- self::$configurationClass = 'LoggerConfiguratorXml';
- } else {
- self::$configurationFile = $configurationFile;
- self::$configurationClass = 'LoggerConfiguratorIni';
- }
+ self::$configurator->configure(self::getHierarchy(),
$configuration);
}
/**
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php?rev=1161411&view=auto
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php
(added)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapter.php
Thu Aug 25 06:45:54 2011
@@ -0,0 +1,10 @@
+<?php
+
+interface LoggerConfigurationAdapter
+{
+ /** Converts the configuration file to PHP format usable by the
configurator. */
+ public function convert($input);
+
+}
+
+?>
\ No newline at end of file
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php?rev=1161411&view=auto
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php
(added)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterINI.php
Thu Aug 25 06:45:54 2011
@@ -0,0 +1,247 @@
+<?php
+
+class LoggerConfigurationAdapterINI implements LoggerConfigurationAdapter {
+
+ const ROOT_LOGGER_NAME = "root";
+
+ const THRESHOLD_PREFIX = "log4php.threshold";
+ const ROOT_LOGGER_PREFIX = "log4php.rootLogger";
+ const LOGGER_PREFIX = "log4php.logger.";
+
+// const CATEGORY_PREFIX = "log4php.category.";
+// const FACTORY_PREFIX = "log4php.factory";
+ const ADDITIVITY_PREFIX = "log4php.additivity.";
+ const ROOT_CATEGORY_PREFIX = "log4php.rootCategory";
+ const APPENDER_PREFIX = "log4php.appender.";
+ const RENDERER_PREFIX = "log4php.renderer.";
+
+ private $config = array();
+
+ private $properties;
+
+ /**
+ * Loads and parses the INI configuration file.
+ *
+ * INI_SCANNER_RAW is used here because otherwise parse_ini_file() will
+ * try to parse all values, with some strange results. For example,
"true"
+ * will become "1", while "false" and "null" will become "" (empty
string).
+ *
+ * @see http://php.net/manual/en/function.parse-ini-file.php
+ *
+ * @param string $path Path to the config file.
+ * @throws LoggerException
+ */
+ private function load($path) {
+ if(!file_exists($path)) {
+ throw new LoggerException("Config file not found on
given path: [$path].");
+ }
+
+ $properties = @parse_ini_file($path, true, INI_SCANNER_RAW);
+ if ($properties === false) {
+ $error = error_get_last();
+ throw new LoggerException("Error parsing configuration
file: {$error['message']}");
+ }
+
+ $this->properties = $properties;
+ }
+
+ /**
+ * Converts the provided INI configuration file to a PHP array config.
+ *
+ * @param string $path Path to the config file.
+ * @throws LoggerException If the file cannot be loaded or parsed.
+ */
+ public function convert($path) {
+ // Load the configuration
+ $this->load($path);
+
+ // Parse threshold
+ if (isset($this->properties[self::THRESHOLD_PREFIX])) {
+ $this->config['threshold'] =
$this->properties[self::THRESHOLD_PREFIX];
+ }
+
+ // Parse root logger
+ if (isset($this->properties[self::ROOT_LOGGER_PREFIX])) {
+
$this->parseLogger($this->properties[self::ROOT_LOGGER_PREFIX],
self::ROOT_LOGGER_NAME);
+ }
+
+ $appenders = array();
+
+ foreach($this->properties as $key => $value) {
+ // Parse loggers
+ if ($this->beginsWith($key, self::LOGGER_PREFIX)) {
+ $name = substr($key,
strlen(self::LOGGER_PREFIX));
+ $this->parseLogger($property, $name);
+ }
+
+ // Parse appenders
+ else if ($this->beginsWith($key,
self::APPENDER_PREFIX)) {
+ $this->parseAppender($key, $value);
+ }
+ }
+
+ }
+
+
+ /**
+ * Parses a logger property.
+ *
+ * Loggers are defined in the following manner:
+ * <pre>
+ * log4php.logger.<name> = [<level>], [<appender-ref>, <appender-ref>,
...]
+ * </pre>
+ *
+ * Where:
+ * - level - level to assign to the logger (optional)
+ * - appender-ref - name of the appenders to attach to the logger
(optional)
+ *
+ * @param string $property
+ * @param string $loggerName
+ */
+ private function parseLogger($property, $loggerName) {
+ // Values are divided by commas
+ $values = explode(',', $property);
+
+ if (empty($property) || empty($values)) {
+ return;
+ }
+
+ // The first value is the logger level
+ $level = array_shift($values);
+
+ // The remaining values are appender references
+ $appenders = array();
+ while($appender = array_shift($values)) {
+ $appender = trim($appender);
+ if (!empty($appender)) {
+ $appenders[] = trim($appender);
+ }
+ }
+
+ $config = array(
+ 'level' => trim($level),
+ 'appenders' => $appenders
+ );
+
+ if ($loggerName == self::ROOT_LOGGER_NAME) {
+ $this->config['rootLogger'] = $config;
+ } else {
+ $this->config['loggers'][$loggerName] = $config;
+ }
+ }
+
+
+ /**
+ * Parses an appender.
+ *
+ * Appenders are defined:
+ * <pre>
+ * log4php.appender.<appender> = <class>
+ * log4php.appender.<appender>.<param> = <value>
+ * </pre>
+ *
+ * Appender layout is defined:
+ * <pre>
+ * log4php.appender.<appender>.layout = <layoutClass>
+ * log4php.appender.<appender>.layout.<param> = <value>
+ * </pre>
+ *
+ * Legend:
+ * - appender - name of the appender
+ * - class - the appender class to use
+ * - param - name of a configurable parameter
+ * - value - value of the configurable parameter
+ *
+ * For example, a full appender config might look like:
+ * <pre>
+ * log4php.appender.myAppender = LoggerAppenderConsole
+ * log4php.appender.myAppender.target = STDOUT
+ * log4php.appender.myAppender.layout = LoggerLayoutSimple
+ * </pre>
+ *
+ * @param unknown_type $key
+ * @param unknown_type $value
+ */
+ private function parseAppender($key, $value) {
+
+ // Remove the appender prefix from key
+ $subKey = substr($key, strlen(self::APPENDER_PREFIX));
+
+ // Divide the string by dots
+ $parts = explode('.', $subKey);
+ $count = count($parts);
+
+ // The first part is always the appender name
+ $name = trim($parts[0]);
+
+ // No dots in key - this line defines the appender class
+ if ($count == 1) {
+ $name = trim($parts[0]);
+ $this->config['appenders'][$name]['class'] = $value;
+ }
+
+ // Dot(s) in key - this line defines an appender property.
+ else {
+
+ // Layouts may have their own properties
+ if ($parts[0] == 'layout') {
+
+
+ }
+
+
+
+ }
+
+ // No dot in key - this is the appender class
+ if (!strpos($appenderKey, '.')) {
+
+ }
+
+ // Dot in key - this is an appender property.
+ else {
+
+ }
+
+
+
+
+ // Remove the appender prefix from key to get name
+ $appenderName = substr($key, strlen(self::APPENDER_PREFIX));
+
+ if (strpos($appenderName, '.')) {
+ return;
+ }
+
+ $appender = array(
+ 'class' => $value
+ );
+
+ // Iterate over params and search for params linked to this
appender
+ foreach($this->properties as $pKey => $pValue) {
+
+ // Detect layout
+ if($pKey == $appenderName . '.layout') {
+ $layout = $this->parseLayout($pKey, $pValue);
+ }
+
+ // Detect other parameters
+ else if ($this->beginsWith($pKey, $key) && $pKey !=
$key) {
+ $paramName = substr($pKey, strlen($key) + 1);
+ $appender[$paramName] = $pValue;
+ }
+ }
+
+ $this->config['appenders'][$appenderName] = $appender;
+
+
+ }
+
+ private function beginsWith($str, $sub) {
+ return (strncmp($str, $sub, strlen($sub)) == 0);
+ }
+
+
+}
+
+?>
\ No newline at end of file
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php?rev=1161411&view=auto
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php
(added)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterPHP.php
Thu Aug 25 06:45:54 2011
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * Loads configuration from an PHP file and parses it to a PHP array.
+ */
+class LoggerConfigurationAdapterPHP implements LoggerConfigurationAdapter
+{
+ public function convert($url)
+ {
+ if (!file_exists($url)) {
+ throw new LoggerException("Invalid configuration file:
does not exist.");
+ }
+
+ $data = @include($url);
+
+ if ($config === false) {
+ $error = error_get_last();
+ throw new LoggerException("Error loading PHP
configuration file: " . $error['message']);
+ }
+
+ if (empty($config)) {
+ throw new LoggerException("Invalid PHP configuration
file: does not return any data.");
+ }
+
+ if (!is_array($config)) {
+ throw new LoggerException("Invalid PHP configuration
file: does not return an array.");
+ }
+
+ return $config;
+ }
+
+}
+
+?>
\ No newline at end of file
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php?rev=1161411&view=auto
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php
(added)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/configurators/LoggerConfigurationAdapterXML.php
Thu Aug 25 06:45:54 2011
@@ -0,0 +1,247 @@
+<?php
+
+/**
+ * Loads configuration from an XML file and converts it to a PHP array.
+ */
+class LoggerConfigurationAdapterXML implements LoggerConfigurationAdapter
+{
+ /** Path to the XML schema used for validation. */
+ const SCHEMA_PATH = '/../xml/log4php.xsd';
+
+ private $config = array(
+ 'appenders' => array(),
+ 'loggers' => array(),
+ 'renderers' => array(),
+ );
+
+ public function convert($url)
+ {
+ $xml = $this->loadXML($url);
+
+ $this->parseConfiguration($xml);
+
+ // Parse the <root> node
+ if (isset($xml->root)) {
+ $this->parseRootLogger($xml->root);
+ }
+
+ // Process <logger> nodes
+ foreach($xml->logger as $logger) {
+ $this->parseLogger($logger);
+ }
+
+ // Process <appender> nodes
+ foreach($xml->appender as $appender) {
+ $this->parseAppender($appender);
+ }
+
+ // Process <renderer> nodes
+ foreach($xml->renderer as $rendererNode) {
+ $this->parseRenderer($rendererNode);
+ }
+
+ return $this->config;
+ }
+
+ /**
+ * Loads and validates the XML.
+ * @param string $url Input XML.
+ */
+ private function loadXML($url) {
+
+ // Load the config file
+ $config = @file_get_contents($url);
+ if ($config === false) {
+ $error = error_get_last();
+ throw new LoggerException("Cannot load config file:
{$error['message']}");
+ }
+
+ // Validate XML against schema
+ $internal = libxml_use_internal_errors(true);
+
+ $this->validateXML($config);
+
+ libxml_clear_errors();
+ libxml_use_internal_errors($internal);
+
+ // Load XML
+ $xml = simplexml_load_string($config);
+ if ($xml === false) {
+ throw new LoggerException("Failed parsing XML
configuration file.");
+ }
+ return $xml;
+ }
+
+ /**
+ * DOMDocument is used here for validation because SimpleXML doesn't
+ * implement this feature.
+ * @param string $input The configuration XML.
+ */
+ private function validateXML($url) {
+ $schema = dirname(__FILE__) . self::SCHEMA_PATH;
+ try {
+ $dom = new DOMDocument();
+ $dom->loadXML($url);
+ } catch(Exception $e) {
+ throw new LoggerException("Failed parsing XML
configuration file.");
+ }
+
+ $success = $dom->schemaValidate($schema);
+ if ($success === false) {
+ $errors = libxml_get_errors();
+ foreach($errors as $error) {
+ $message = trim($error->message) . " On line
{$error->line} of the configuration file.";
+ $this->warn($message);
+ }
+ throw new LoggerException("The XML configuration file
failed validation.");
+ }
+ }
+
+ /**
+ * Parses the <configuration> node.
+ */
+ private function parseConfiguration(SimpleXMLElement $xml) {
+ $attributes = $xml->attributes();
+ if (isset($attributes['threshold'])) {
+ $this->config['threshold'] = (string)
$attributes['threshold'];
+ }
+ }
+
+ /** Parses an <appender> node. */
+ private function parseAppender(SimpleXMLElement $node) {
+ $name = $this->getAttributeValue($node, 'name');
+
+ $appender = array();
+ $appender['class'] = $this->getAttributeValue($node, 'class');
+
+ $attrs = $node->attributes();
+ if (isset($attrs['threshold'])) {
+ $appender['threshold'] = (string) $attrs['threshold'];
+ }
+
+ if (isset($node->layout)) {
+ $appender['layout']= $this->parseLayout($node->layout,
$name);
+ }
+
+ if (count($node->param) > 0) {
+ $appender['params'] = $this->parseParameters($node);
+ }
+
+ foreach($node->filter as $filterNode) {
+ $appender['filters'][] =
$this->parseFilter($filterNode);
+ }
+
+ $this->config['appenders'][$name] = $appender;
+ }
+
+ /** Parses a <layout> node. */
+ private function parseLayout(SimpleXMLElement $node, $appenderName) {
+ $layout = array();
+ $layout['class'] = $this->getAttributeValue($node, 'class');
+
+ if (count($node->param) > 0) {
+ $layout['params'] = $this->parseParameters($node);
+ }
+
+ return $layout;
+ }
+ /** Parses any <param> child nodes returning them in an array. */
+ private function parseParameters($node) {
+ $params = array();
+
+ foreach($node->param as $paramNode) {
+ $attrs = $paramNode->attributes();
+ $name = (string) $attrs['name'];
+ $value = (string) $attrs['value'];
+
+ $params[$name] = $value;
+ }
+
+ return $params;
+ }
+
+ /** Parses a <root> node. */
+ private function parseRootLogger(SimpleXMLElement $node) {
+ $logger = array();
+
+ var_dump($node->level['value']);
+
+ if (isset($node->level)) {
+ $logger['level'] =
$this->getAttributeValue($node->level, 'value');
+ }
+
+ $logger['appenders'] = array();
+ foreach($node->appender_ref as $appender) {
+ $logger['appenders'][] =
$this->getAttributeValue($appender, 'ref');
+ }
+
+ $this->config['rootLogger'] = $logger;
+ }
+
+ /** Parses a <logger> node. */
+ private function parseLogger(SimpleXMLElement $node) {
+ $logger = array();
+ $attributes = $node->attributes();
+
+ $name = (string) $attributes['name'];
+
+ if (isset($node->level)) {
+ $logger['level'] =
$this->getAttributeValue($node->level, 'value');
+ }
+
+ $logger['appenders'] = $this->parseAppenderReferences($node,
$name);
+
+ if (isset($this->config['loggers'][$name])) {
+ $this->warn("Duplicate logger definition for $name.
Overwriting.");
+ }
+
+ $this->config['loggers'][$name] = $logger;
+ }
+
+ /**
+ * Parses a <logger> node for appender references and returns them in
an array.
+ */
+ private function parseAppenderReferences(SimpleXMLElement $node, $name)
{
+ $refs = array();
+ foreach($node->appender_ref as $ref) {
+ $refs[] = $this->getAttributeValue($ref, 'ref');
+ }
+
+ return $refs;
+ }
+
+ private function parseFilter($filterNode) {
+ $filter = array();
+ $filter['class'] = $this->getAttributeValue($filterNode,
'class');
+
+ if (count($filterNode->param) > 0) {
+ $filter['params'] = $this->parseParameters($filterNode);
+ }
+
+ return $filter;
+ }
+
+ /** Parses a <renderer> node. */
+ private function parseRenderer(SimpleXMLElement $node) {
+ $renderedClass = $this->getAttributeValue($node,
'renderedClass');
+ $renderingClass = $this->getAttributeValue($node,
'renderingClass');
+
+ $this->config['renderers'][] = compact('renderedClass',
'renderingClass');
+ }
+
+ // ******************************************
+ // ** Helper methods **
+ // ******************************************
+
+ private function getAttributeValue(SimpleXMLElement $node, $name) {
+ $attrs = $node->attributes();
+ return isset($attrs[$name]) ? (string) $attrs[$name] : null;
+ }
+
+ private function warn($message) {
+ trigger_error("log4php: " . $message, E_USER_WARNING);
+ }
+
+}
+
+?>
\ No newline at end of file
Modified:
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd?rev=1161411&r1=1161410&r2=1161411&view=diff
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd
(original)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.dtd
Thu Aug 25 06:45:54 2011
@@ -46,7 +46,7 @@ element. -->
<!-- keeps its old value. -->
<!ATTLIST log4php:configuration
- xmlns:log4php CDATA #FIXED "http://logging.apache.org/log4php"
+ xmlns CDATA #FIXED "http://logging.apache.org/log4php"
threshold (all|debug|info|warn|error|fatal|off|null) "null"
>
@@ -64,7 +64,7 @@ element. -->
<!-- [log4php] -->
<!-- error handler tag has no effects since log4php does not handle errors.
Defintion deleted. -->
<!-- [/log4php] -->
-<!ELEMENT appender (param*, layout?, filter*, appender-ref*)>
+<!ELEMENT appender (param*, layout?, filter*, appender_ref*)>
<!ATTLIST appender
name ID #REQUIRED
class CDATA #REQUIRED
@@ -99,21 +99,21 @@ element. -->
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named logger. -->
-<!ELEMENT logger (level?,appender-ref*)>
+<!ELEMENT logger (level?,appender_ref*)>
<!ATTLIST logger
name ID #REQUIRED
additivity (true|false) "true"
>
-<!ELEMENT appender-ref EMPTY>
-<!ATTLIST appender-ref
+<!ELEMENT appender_ref EMPTY>
+<!ATTLIST appender_ref
ref IDREF #REQUIRED
>
<!-- If no priority element is specified, then the configurator MUST not -->
<!-- touch the priority of root. -->
<!-- The root category always exists and cannot be subclassed. -->
-<!ELEMENT root (param*, (priority|level)?, appender-ref*)>
+<!ELEMENT root (param*, (priority|level)?, appender_ref*)>
<!-- ==================================================================== -->
@@ -121,7 +121,7 @@ element. -->
<!-- ==================================================================== -->
<!ELEMENT log4php:eventSet (log4php:event*)>
<!ATTLIST log4php:eventSet
- xmlns:log4php CDATA #FIXED "http://www.vxr.it/log4php/"
+ xmlns:log4php CDATA #FIXED "http://logging.apache.org/log4php"
version (0.2|0.3) "0.3"
includesLocationInfo (true|false) "true"
>
Added:
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd
URL:
http://svn.apache.org/viewvc/logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd?rev=1161411&view=auto
==============================================================================
---
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd
(added)
+++
logging/log4php/branches/experimental/config-adapters/src/main/php/xml/log4php.xsd
Thu Aug 25 06:45:54 2011
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="unqualified"
+ targetNamespace="http://logging.apache.org/log4php"
+ xmlns="http://logging.apache.org/log4php">
+
+ <xs:element name="configuration">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="renderer" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="appender" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="logger" />
+ <xs:element minOccurs="0" ref="root" />
+ </xs:sequence>
+ <xs:attribute name="threshold" type="level"
default="null" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="renderer">
+ <xs:complexType>
+ <xs:attribute name="renderedClass" use="required" />
+ <xs:attribute name="renderingClass" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="appender">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="layout" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="param" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="filter" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="appender_ref" />
+ </xs:sequence>
+ <xs:attribute name="name" use="required" type="xs:ID" />
+ <xs:attribute name="class" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="layout">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="param" />
+ </xs:sequence>
+ <xs:attribute name="class" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="filter">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="param" />
+ </xs:sequence>
+ <xs:attribute name="class" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="param">
+ <xs:complexType>
+ <xs:attribute name="name" use="required" />
+ <xs:attribute name="value" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="priority">
+ <xs:complexType>
+ <xs:attribute name="value" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="level">
+ <xs:complexType>
+ <xs:attribute name="value" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="logger">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" ref="level" />
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="appender_ref" />
+ </xs:sequence>
+ <xs:attribute name="name" use="required" type="xs:ID" />
+ <xs:attribute name="additivity" type="xs:boolean"
default="true" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="appender_ref">
+ <xs:complexType>
+ <xs:attribute name="ref" use="required" type="xs:IDREF"
/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="root">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="param" />
+ <xs:choice minOccurs="0">
+ <xs:element ref="priority" />
+ <xs:element ref="level" />
+ </xs:choice>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="appender_ref" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="eventSet">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded"
ref="event" />
+ </xs:sequence>
+ <xs:attribute name="version" default="0.3">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="0.2" />
+ <xs:enumeration value="0.3" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ <xs:attribute name="includesLocationInfo"
default="true">
+ <xs:simpleType>
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="true" />
+ <xs:enumeration value="false" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="event">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element ref="message" />
+ <xs:element minOccurs="0" ref="locationInfo" />
+ </xs:sequence>
+ <xs:attribute name="logger" use="required" />
+ <xs:attribute name="level" use="required" />
+ <xs:attribute name="thread" use="required" />
+ <xs:attribute name="timestamp" use="required" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="message" type="xs:string" />
+ <xs:element name="NDC" type="xs:string" />
+ <xs:element name="locationInfo">
+ <xs:complexType>
+ <xs:attribute name="class" use="required" />
+ <xs:attribute name="method" use="required" />
+ <xs:attribute name="file" use="required" />
+ <xs:attribute name="line" use="required" />
+ </xs:complexType>
+ </xs:element>
+
+ <!-- ============================================== -->
+ <!-- Types -->
+ <!-- ============================================== -->
+
+ <xs:simpleType name="level">
+ <xs:restriction base="xs:token">
+ <xs:enumeration value="all" />
+ <xs:enumeration value="debug" />
+ <xs:enumeration value="info" />
+ <xs:enumeration value="warn" />
+ <xs:enumeration value="error" />
+ <xs:enumeration value="fatal" />
+ <xs:enumeration value="off" />
+ <xs:enumeration value="null" />
+ </xs:restriction>
+ </xs:simpleType>
+</xs:schema>