XML-based configuration is a simple, easy and flexible way of configuring Dwarf-based applications. Generally, it is one or more XML documents describing service instances and their attributes as well as composition relationships between the servers and their contained services.
This document is a reference guide for the format of the XML configuration data required by the XMLConfiguration class, which is used to instantiate and setup the server applications.
The configuration data must be introduced by the following XML header:
<?xml version='1.0' encoding='us-ascii'?> <!DOCTYPE configuration SYSTEM "file:lib/xmlConfiguration.dtd">
The first line is the standard declaration of a XML document. The second line identifies the Document Type Definition (DTD) source. This file describes the exact format of the XML configuration data required by the XMLConfiguration class and resides in the "lib/" subdirectory of the Dwarf installation. It is used to automatically validate the syntax of the configuration files. The automatic validation can be globally turned on or off via the static XMLConfiguration.setValidation(boolean) method.
The single top-level configuration element represents the whole configuration data:
<configuration security="on" debug="tcp" trace="" verbose="off"> ... </configuration>
The following attributes are accepted for this element:
An arbitrary number of the property elements can be specified in the root element. These elements are used to set the system properties via the System.setProperty static method:
<configuration security="on" debug="tcp" trace="" verbose="off"> <property name="java.security.policy">file:conf/java.policy</property> <property name="java.security.auth.policy">file:conf/jaas.policy</property> ... </configuration>
The property tag expects the name attribute, which is the name of the system property to be set. The property value is specified via the content of the element, as you can see in the example.
Note 1: The property element is actually a shortened form of the full <property type="system" ...> form. Since the default value "system" for the attribute type is implied by the DTD, it is not required to be used explicitly.
Note 2: Java security manager is installed after all system properties have been set via the corresponding property elements.
The security properties can be set via the property element, too. In order to do this the attribute type must be specified, with the value equal to "security":
<property type="security" name="package.access">sun.,SK.gnome.dwarf.internal.</property>
Security properties are set via the Security.setProperty static method, after all system properties has been set and the security manager has been installed.
There is a little intelligence built into the XMLConfiguration class: the "xxxxx.url.n" security properties are set in a way that the number n is automatically adjusted to the first available number in the ordered sequence. The following example would set the "policy.url.3" and "policy.url.4" properties because the "policy.url.1" and "policy.url.2" are typically set by the default JVM configuration:
<property type="security" name="policy.url.">file:conf/java_http.policy</property> <property type="security" name="policy.url.">file:conf/java_mail.policy</property>
Warning: We use security properties in Dwarf mainly for setting the additional security policies as well as the login module configurations. But beware! Since the XMLConfiguration class uses the refresh() method of the java.security.Policy class, which may be implementation dependant, it is possible that it will not work on your platform as expected. In that case use the system properties only to set the security policies.
The configuration element can contain only one directly nested element other than the property elements. It is the service element and describes the top-level service beeing created and configured by the XMLConfiguration class. An object represented by the service element must be an implementation of the Service interface, and it must have a constructor with just one string argument - the name of the service:
<configuration security="on" debug="tcp" trace="" verbose="off"> <property name="java.security.policy">file:conf/java.policy</property> <property name="java.security.auth.policy">file:conf/jaas.policy</property> <service class="SK.gnome.dwarf.main.MainServer" name="Main Server"> ... </service> </configuration>
The service tag requires the following two attributes:
The service elements can be nested to an arbitrary level. If a service element contains another service elements, it represents a server containing another services. The nested services are added to the parent server via its addService(Service) method. Such a container object need no to implement the Server interface, but it must declare the proper addService method. Nesting of the service elements is the most important and useful feature provided by the XMLConfiguration class, because it allows to create a complex tree structures of servers and services:
<service class="SK.gnome.dwarf.main.MainServer" name="Main Server"> <service class="SK.gnome.dwarf.log.LogServer" name="Log Server"> <service class="SK.gnome.dwarf.log.SystemLogger" name="Console Logger"/> </service> </service>
The above example describes MainServer instance, which contains one another service - a LogServer instance, which in turn contains another service - a SystemLogger instance.
There is one optional attribute accepted by the service element - the classbase attribute. It affects the current service as well as all nested services, and tells the XMLConfiguration the base part of the class names. This base name will be prepended to all class attribute values, which start with a dot character:
<service classbase="SK.gnome.dwarf" class=".main.MainServer" name="Main Server"> <service class=".log.LogServer" name="Log Server"> <service class=".log.SystemLogger" name="Console Logger"/> </service> </service>
The above example describes exactly the same configuration as the previous one. The classbase attribute can be used to save the space and make your XML configuration more concise and readable.
Now we can describe an arbitrary hierarchy of the servers and services, but we still do not know how to configure the attributes of a single service. A service attributes are represented by its setter and getter methods. We know, for example, that the Console class has a method with the following signature:
public void setPrompt(boolean value);
This method sets the value of the corresponding prompt attribute. We can set the service attribute via the following XML syntax:
<service class="SK.gnome.dwarf.main.Console" name="Console"> <set name="prompt">true</set> </service>
The above example sets the prompt attribute by invoking the setPrompt(boolean) method on the currently created Console instance. The element content (i.e. the string "true") is automatically converted to the corresponding boolean value. The desired value type is distinguished from the setter method's argument type. All common data types will work, including boolean, integer, float, String, String array, Class, etc. See the XMLConfiguration.setAttribute(String, String) method for more information about the automatic data conversion and a list of the possible argument types.
The optional classbase attribute of the service element affects
also the service attributes whose names end with string "Class".
The attribute values are modified in the exact way as in the case of the class
attribute of the service element:
<service classbase="SK.gnome.dwarf.http" class=".HTTPServer" name="HTTP Server"> <set name="handlerClass">.HTTPHandler</set> </service>
In the above example, the ".HTTPHandler" value would be automatically converted to "SK.gnome.dwarf.http.HTTPHandler" before invoking the setHandlerClass method on the HTTP server instance.
Note: All set elements must be grouped together and placed before any subsequent service element. In other words, all attributes of a service must be set before any other service is added to it. (This rule is forced by the DTD, by the way.)
Since the XML configuration data can grow quickly and may become too complex for a larger application, there is a possibility how to split up a single configuration file to the separate parts. The include element tells the XMLConfiguration class to load a service from another source defined by its url atribute. That means the include element can be used at any place where the service element is expected:
<service classbase="SK.gnome.dwarf.main" class=".MainServer" name="Main Server"> <include url="file:conf/http.xml"/> </service>
The example above would create a MainServer instance first, and then another service from a different source would be created and configured according to the given URL, and added to the MainServer.
There is no difference between the syntax of non-included and included configuration files, except that you should avoid using the attributes of configuration element, as well as setting the system properties via the property element in the included files. It will work, but may lead to a confusion or misconfiguration if not used carefully.
Return to the main page.