The Config4GNU object model is a huge virtual XML document.
It is called a virtual document because the content of the XML
is generated on the fly as needed by "parsing" native configuration
files to XML and changes to the XML are automatically implemented
in the native configuration files.
The elements in this virtual XML documents are mapped to "objects"
in the Config4GNU system. The type of object represented by an
element depends on what kind of children the element has. If it
has only text, it is considered a "primitive" object. If it has
only child elements, it is considered a "normal" object. If it
has mixed text and child elements, it is considered a "complex"
element.
Primitive objects just contain some sort of a single value.
The value may be a string of any characters, or it may be a
number, a date, boolean, or of an enumerated type. Since the
underlying format is XML, the value is stored in its string
representation.
Here is an example of a primitive object, represented in XML.
It contains the date this part of the document was written.
Example 1. A primitive object |
<createdate>2002-12-12</createdate> |
Various front-ends will provide various widgets to display or
modify the content of primitive objects. At the very least, a
platform should allow a user to edit the string representation
of an object. Since objects inherit from one another, an
unrecognized object type can be displayed or edited as if it
was a member of the parent type. For instance, if a positive
number type was required, but the front-end did not know about
positive numbers, it could provide a control for entering any
number, since the "positive number" type would extend the
"any number" type.
Validation must be provided below the user interface layer.
If, as in the prior example, the user interface did not know
about "positive numbers", and instead used an "any number" widget,
it would be up to the layer below to reject negative numbers.
The Config4GNU system will define various primitive object types.
Widgets will be provided for these types when possible. Some
of the types that will be defined by Config4GNU are:
String
Number
Integer
Date/Time
Path (i.e. a filename)
Boolean
Since Config4GNU hopes to use XML Schema in various ways, and
the XML Schema specification defines various data types, the
data types used by Config4GNU will match with it.
Normal objects contain other objects. These child objects are
represented in XML as child elements and attributes. These
child objects are also called fields or
properties.
The names of these properties are the element names themselves.
The values of these properties are the content of the attributes
or child elements and may be normal objects themselves or
primitive objects, or complex objects.
Any whitespace that is found between child elements of a normal
object is ignored. Any text found between child elements is
considered invalid, and should be treated the same as a parsing
error.
Multi-valued properties are allowed using this model. Just have
a child element with the same name occur more than once and you
have multiple values.
This model has many of the features we want: it's simple,
flexible, easily allows multi-valued attributes, and is
extensible--all you need to do is add elements or attributes.
In the following example, an XML representation of a runlevel
configuration object--which is a normal object, we see
some of these concepts. The default-runlevel child element is
a simple text property of the runlevel configuration.
There are multiple service child elements, these are themselves
normal objects and there can be many of them in the
runlevel configuration. The service element has two properties
that are primitive objects: name and
runlevels.
Example 2. A normal object |
<runlevels-config>
<default-runlevel>default</default-runlevel>
<service>
<name>bootmisc</name>
<runlevels>boot</runlevels>
</service>
<service>
<name>samba</name>
<runlevels>default</runlevels>
</service>
</runlevels-config> |
Normal objects can also have methods. These are actions that can
be performed on an object. Since methods are not per-instance but
rather per-class, they are not defined in the XML data files but
in the XML type (or schema) definition files.
Some XML elements contain mixed text and elements. A great example
would be in XHTML, where a string of text might contain an
img element to insert an image in the middle
of some text. These objects are considered complex, because they
are more complicated to handle. As with other elements, widgets
can be defined to handle them. In the fallback case, the user
will have to edit the raw XML.
Very simply, the "name" of an object is the value of its
name property. This may be specified directly
in the instance
data, using the <name> tag, by a
default value in the Schema file, or by programmatically
overriding the "get" method for the "name" property.
The name of an object is used when displaying object among other
objects in the object tree (see Object Tree). There may be other uses as well.
The children of an object are a subset of an
object's properties. Children are those
properties that should be treated as separate objects from the
parent object but would be considered "contained" by the parent
object. In the GUI, child objects appear next to an object in
the configuration tree that appears in the left pane.
There are two ways to specify what the children of an
object are. Remember that children objects are properties as well,
because the children of an object are a subset of the properties
of an object. To identify children, a flag must be added to the
property definition to mark it as a child object.
The first type of child object is a property that acts as a
separate container for an object's children. A common way to use
this is with a "children" property. Any child objects of the
"children" property are child objects of this object.
Here is an example XML representation
that uses the children element.
Example 3. Identifying children using the
children property |
<samba-config>
<children>
<sambashare>
<name>public</name>
...
</sambashare>
<sambashare>
<name>ProjectFiles</name>
...
</sambashare>
<sambaprinter>
<name>Office Printer</name>
...
</sambaprinter>
</children>
</samba-config> |
This XML representation would generate the following tree
representation:
Samba configuration
public
ProjectFiles
Office Printer
In the current version of Config4GNU,
any property named children behaves this way.
In the future, there will be a flag that you can add to the
property definition of children which will
make it behave this way.
The other type of child object is a property that becomes a
child itself. Take this example:
Example 4. Properties as Children |
<runlevels-config>
<runlevels>
<runlevel>
<name>2</name>
<description>No network</description>
</runlevel>
<runlevel>
<name>3</name>
<description>Default</description>
</runlevel>
</runlevels>
<services>
<service>
<name>named</name>
<runlevels>3</runlevels>
</service>
</services>
</runlevels-config> |
The children of the runlevels-config object
should be "Runlevels" and "Services". The following list
shows how it would appear in a tree display. Assume that
we defined that the children of runlevels-conf
should be Runlevels and Services, and that we applied names to
elements that do not have name elements.
In the current version of Config4GNU,
identify this type of child object with an attribute
child="true" in the property
definition for the property that should become a child.
Links are connections between two objects in the configuration
system. Whenever an object references something that is another
object in the Config4GNU system, it
should identify it in the way that clients can connect it to
that object.
For example, if you are representing a filesystem, and you want
to identify the owner of the file, identify the owner of the
file not by specifying the username, but by identifying the
object that represents that user. For more information on
identifying objects, see
Identifying Objects below.
This may be complicated at times, particularly if the two objects
are located in separate documents. In this case, it may be
acceptable to use a less detailed method to identify the object.
However, when two objects are in the same document, they should
always refer to each other by object not by contents.
The Config4GNU system must define a way to globally identify a
specific aspect of configuration. This is important, for example,
to identify associations between different aspects of
configuration (e.g. access control lists).
An absolute path would have to include a mechanism to globally
identify a computer, perhaps using a fully qualified domain name
or an IP address, and then the specific configuration item on the
machine. However, because specific instances of configuration
should not be tailored to a specific machine but should be
transferrable to different environments, several shortcuts
should be available:
- FRAGMENT_ROOT
Identifies root of a particular aspect of
configuration. For example, the FRAGMENT_ROOT inside a
Samba configuration file would point to the root
of the Samba configuration file.
- LOCAL_COMPUTER_ROOT
Identifies root of configuration for the
local computer in which the context node exists
- ORGANIZATION_ROOT
Identifies a local root of a configuration
hierarchy including all the computers of a particular
organization
- GLOBAL_ROOT
Identifies the real root of the virtual XML
document which would conceptually include all
organizations in the world