Main
User's Guide
Administrator's Guide
Programmer's Corner
|
Introduction |
This HOWTO will try and fill in the gaps left between the Schema [xsd] [dtd]
[documentation] and the current slide configuration document. This document
will not explain how XML works or what XSD is. This document is for developers, primarily developers working with the Slide WebDAV servlet who want to know what kind of configuration options
are available.
Every Slide webapplication needs an XML configuration file. This document is normally referred to as the Domain.xml file.
|
slide - the top level XML element |
The top-level element in the Domain.xml file is slide .
The slide element support three attributes:
Attribute name |
Description |
Example |
Default value |
logger |
The Java classname for the logger object |
org.apache.slide.util.logger.SimpleLogger |
org.apache.slide.util.logger.SimpleLogger |
logger-level |
A numeric level indicator for the amount of data logged. These values range from 0 to 7, with 0 being the least amount of information logged |
4 (warnings and above) |
4 - INFO |
default |
This is the most critical attribute of the slide element. This attribute defines the default namespace in this Domain. The WebDAV servlet will use this value
when displaying the site to a standard web browser |
my-default-namespace |
slide |
Example: <slide logger="org.apache.slide.util.logger.SimpleLogger" logger-level="6" default="my-default-namespace">
|
parameter - general purpose tag for passing configuration information |
A parameter element is used in multiple places throughout the Domain.xml configuration file. Parameters are name/value pairs, similar to Java properties.
The parameter element supports one attribute:
Attribute name |
Description |
Example |
Default value |
name |
the name of the parameter in this name/value pair |
driver |
N/A | this attribute is required |
Example: <parameter name="driver">org.hsqldb.jdbcDriver</parameter>
|
namespace - the key to everything in Slide |
The slide top-level element contains a number of Namespaces. These namespaces are the backbone of Slide. When someone navigates through
a set of files provided by the Slide web application, they are walking through one of Slide's namespaces.
Attribute name |
Description |
Example |
Default value |
name |
Slide applications refer to Namespaces by name. This Namespace will be registered under this name. If two namespaces have the same name, the last one defined in the configuration file
will be references, and the other one will be lost. |
my-default-namespace |
Must be specified. If not, the WebDAV component will complain to the log before terminating. |
logger |
The Java classname for the logger object |
org.apache.slide.util.logger.SimpleLogger |
If unspecified, the slide-level logger will be used. This is a way to customize logging for a particular namespace |
logger-level |
A numeric level indicator for the amount of data logged. These values range from 0 to 7, with 0 being the least amount of information logged |
4 (warnings and above) |
If unspecified, the slide-level logger will be used. This is a way to customize logging for a particular namespace |
Example w/o logger: <namespace name="my-default-namespace">
|
store - contains the objects in this namespace |
A store is bound in the Domain by name; when there are multiple stores, a programmer
can ask for one by name. A store must support two categories of services: descriptors and data. Descriptors consist of path names to nodes, security information, locks, and change management. Data
is the raw information that a descriptor owns. Think of it as a filesystem: descriptors are the file metainformation (directories, modification times, access control, file locks, etc...) and
data is the content of the file.
Attribute name |
Description |
Example |
Default value |
name |
The name of this store within the domain |
my-first-store |
N/A | this attribute is required |
Example: <store name="database-store">
|
nodestore - provides structure for the namespace |
The nodestore service provides structure to the namespace. It manages the tree of nodes like a filesystem directory.
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.NodeStore interface |
slidestore.reference.MemoryDescriptorsStore |
N/A | this attribute is optional |
Example with parameters:
<nodestore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</nodestore>
Example with a reference to another store:
<nodestore><reference store="that-other-store"></nodestore>
|
reference - a pointer to another store instance |
A reference element informs Slide that this store's responsibilities should be forwarded to another store implementation. For example,
a single store instance could manage the services for nodestore, lockstore, and securitystore. In this case, the lockstore and securitystore definitions should contain a reference
element referring to the nodestore.
The reference element supports one attribute:
Attribute name |
Description |
Example |
Default value |
store |
refer my responsibilities to another store. Accepted values: "nodestore", "securitystore", "lockstore", "revisiondescriptorsstore", "revisiondescriptorstore", "contentstore" |
nodestore |
N/A | this attribute is required |
Example: <reference store="nodestore" />
|
securitystore - controls user access to nodes |
The securitystore service restricts access to nodes depending on the permissions. Think of it like the rwxrxwrxw permissions of Unix... except Slide is a bit more complicated.
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.SecurityStore interface |
slidestore.reference.MemoryDescriptorsStore |
N/A | this attribute is optional |
Example with parameters:
<securitystore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</securitystore>
Example with a reference to another store:
<securitystore><reference store="that-other-store"></securitystore>
|
lockstore - provides exclusive access to nodes |
The lockstore service guarantees upon request that a single user may access a resource without interruption.
Think of it like locking a file in Unix with exclusive access: fcntl ( some_file_descriptor, F_SETLK, some_struct_flock_ptr * ) .
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.LockStore interface |
slidestore.reference.MemoryDescriptorsStore |
N/A | this attribute is optional |
Example with parameters:
<lockstore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</lockstore>
Example with a reference to another store:
<lockstore><reference store="that-other-store"></lockstore>
|
revisiondescriptorsstore - gives access to all revision metainformation of a particular node |
The revisiondescriptorsstore service contains information about the different versions of a particular node, including the revision numbers, the latest revision, and any
branches. Information concerning a particular revision is not supporting by this service.
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.RevisionDescriptorsStore interface |
slidestore.reference.MemoryDescriptorsStore |
N/A | this attribute is optional |
Example with parameters:
<revisiondescriptorsstore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</revisiondescriptorsstore>
Example with a reference to another store:
<revisiondescriptorsstore><reference store="that-other-store"></revisiondescriptorsstore>
|
revisiondescriptorstore - gives access to revision information for a particular revision of a particular node |
The revisiondescriptorstore service contains information about a single revision of a particular node, including the revision number, an optional branch name, associated version labels,
properties, content length, content type, creation time, modified time, etc. Information concerning other revisions of the same node is not supporting by this service.
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.RevisionDescriptorStore interface |
slidestore.reference.MemoryDescriptorStore |
N/A | this attribute is optional |
Example with parameters:
<revisiondescriptorstore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</revisiondescriptorstore>
Example with a reference to another store:
<revisiondescriptorstore><reference store="that-other-store"></revisiondescriptorstore>
Note: take care when defining this element, as the difference between this service and the previous one differ by a single letter 's'.
|
contentstore - responsible for the data associated with a particular node |
The contentstore service provides the content of a particular node, accessible by revision number. Think of it as the stream of bytes from disk; once the node has been located
in the structure (NodeStore ), passed security checks (SecurityStore ), and is not locked by someone else (LockStore ), the contents of that node may be read from or
written to the content store.
Attribute name |
Description |
Example |
Default value |
classname |
The fully-qualified name of the Java class that implements the org.apache.slide.store.ContentStore interface |
slidestore.reference.MemoryDescriptorStore |
N/A | this attribute is optional |
Example with parameters:
<contentstore classname="slidestore.reference.JDBCDescriptorsStore">
<parameter name="driver">org.hsqldb.jdbcDriver</parameter>
<parameter name="url">jdbc:hsqldb:slidestructure</parameter>
<parameter name="user">sa</parameter>
<parameter name="password"></parameter>
</contentstore>
Example with a reference to another store:
<contentstore><reference store="that-other-store"></contentstore>
|
scope - maps a namespace onto the domain |
The scope element maps a store onto the structure provided by the Domain. Think of it like an entry in the Unix fstab
file, where a store is a filesystem mapped onto the file system tree maintained by the operating system. One and only one store can be mounted to the root ("/ ").
When a complete path is handed to the Domain during a call, the Domain is responsible for choosing the right store to handle the call. For example, if store 'memory' has a scope
referencing / , and store 'database' has a scope referencing /db , a request to read from node /db/chris/some_file will be passed to the 'database' store.
In addition, for each scope element, a new instance of the store is created and mapped into the Domain on the provided URI. This means that a single store definition may be
instantiated multiple times, but exist at different places on the Domain structure.
Attribute name |
Description |
Example |
Default value |
store |
The name of the store mapped to the URI described in the match attribute |
my-first-store |
N/A | this attribute is required |
match |
Where the namespace referenced by the store attribute will be mapped on the Domain structure. Must be an absolute path starting with '/' |
/database |
N/A | this attribute is required |
Example:
<scope store="my-database-store" match="/" />
|
configuration - the catchall element for configuring Slide |
A configuration element makes changes to Slide settings outside of a particular namespace or node. The configuration is split into six sections:
- actions
- paths
- parameters
- roles
- default properties
- content-interceptor definitions
All of the sections except default-action are optional.
Example: <configuration>
|
default-action - the action called when no other action is available |
The default-action is called when no element is configured for the operation in question.
What is an action? Slide supplies several standard actions for use with the WebDAV network protocol. For example, reading the contents of a file requires a successful read-revision-content
action. The configuration element lists these actions by name, each containing a reference to an ActionNode somewhere else in the Domain structure.
An ActionNode , defined in the data section of the Domain.xml file, can have any name that you wish. Common examples are read for
read actions like read-revision-content , write for write actions like modify-revision-content and remove-revision-content , and manage
for administration actions like revoke-permission , but these names are not required, just suggested.
Multiple actions can refer to the same action node, and any actions not defined in the configuration element are assigned the value of the default-action tag.
Example: <default-action>/actions/not-permitted</default-action>
|
read-object - can you look up the node? |
The read-object action is called when someone wants to find a node in the structure. Successfully calling a read-object action doesn't mean
the user can do anything else with the Node, but without a successful read-object action, no other operations on the Node are possible.
Example: <read-object>/actions/read</read-object>
|
create-object - can you insert a new node in the Domain? |
The create-object action is called when someone wants to insert a node into the Domain structure, including locks on other nodes. Successfully calling a create-object action doesn't mean
the user can do anything else with the Node, but without a successful create-object action, no locking operations are permitted.
Example: <create-object>/actions/write</create-object>
|
grant-permission - can you add a new permission record to a node in the Domain? |
The grant-permission action is called when someone wants to add a new permission record to an existing node in the Domain structure.
This is a dangerous action, so only authorized users should be allowed to call it, since
successfully calling a grant-permission action gives the user control over other operations on that node. grant-permission does not remove existing permissions from the
node.
Example: <grant-permission>/actions/manage</grant-permission>
|
revoke-permission - can you remove an existing permission record from a node in the Domain? |
The grant-permission action is called when someone wants to remove an existing permission record from an existing node in the Domain structure.
This is a dangerous action, so only authorized users should be allowed to call it, since
successfully calling a revoke-permission action gives the user control over other operations on that node. For example, a user could remove a "deny write" permission from the
node, giving the user access that it did not already have. revoke-permission does not add new permissions to the node.
Example: <revoke-permission>/actions/manage</revoke-permission>
|
read-permissions - can you read existing permission records from a node in the Domain? |
The read-permissions action is called when someone wants to enumerate the existing permission records of an existing node in the Domain structure.
This can be a dangerous action, so only authorized users should be allowed to call it, since
successfully calling a read-permissions action gives the user information about other operations on that node. read-permissions does not modify the permission records of the node.
Example: <read-permissions>/actions/manage</read-permissions>
|
modify-revision-content - can you modify an existing revision of a node? |
The modify-revision-content action is called before modifying an existing revision of a particular node's content.
What is the difference between creating a new revision of a node's contents and simply modifying a node's existing revision?
As you can see from the above illustration, creating a new content revision means creating new revision metadata. This means that the previous revision may be retrieved intact. When
modifying an existing revision's content, the old content associated with that revision is irretrievably lost.
Example: <modify-revision-content>/actions/write</modify-revision-content>
|
guestpath - the SubjectNode for unauthenticated users |
All unauthenticated users are represented by a single SubjectNode in Slide: the value of guestpath .
Note: In Slide v1.0, the guest path must be a relative URI (no leading '/' ), because the code appends the value of guestpath to the value of
userspath .
Example: <guestpath>guest</guestpath>
|
role - are you this type of user? |
All Nodes in the Domain structure have an associated role . Roles are like primary groups in Unix or Windows: all nodes must have one and only one
associated role. If a node does not have a role specifically assigned to it, it will have the special role nobody. Roles simplify configuration: groups of users in the same role will
have the same security settings. When a new user is added to Slide, simply add them to the appropriate role and no other changes need to be made.
There are three roles built into the Slide framework:
- slideroles.basic.GuestRole
- slideroles.basic.RootRole
- slideroles.basic.UserRole
Developer's can add their own additional role classes as needed.
Note: When using an external Realm for authentication, the Slide role names must match those understood by the Realm.
Attribute name |
Description |
Example |
Default value |
name |
the alias for this role: must follow the Realm role stated above |
slideroles.basic.RootRole |
N/A | this attribute is required |
In Slide v1.0, things are a little more complicated. SubjectNodes that represent each user in the Domain aren't associated with a role; they are the role. For example, a user with
the RootRole wouldn't be a standard SubjectNode; instead, it is an instance of the slideroles.basic.RootRole class, which means that changing a user's role while the server
is running is almost impossible.
Example for root role: <role name="root">slideroles.basic.RootRole</role>
Example for user role: <role name="user">slideroles.basic.UserRole</role>
Example for guest role: <role name="guest">slideroles.basic.GuestRole</role>
|
auto-create-users - what happens when a user logs in but no SubjectNode exists? |
When a user successfully logs into Slide, their username is matched to a corresponding SubjectNode in the userspath .
That SubjectNode represents them within Slide. But what happens if a user's SubjectNode does not exist in the Domain structure? A new node will be created for them if the value of this
element is true. Otherwise the login will be rejected.
Example for "yes, automatically create user SubjectNodes" : <auto-create-users>true</auto-create-users>
Example for "no, do not automatically create user SubjectNodes" : <auto-create-users>false</auto-create-users>
|
auto-create-users-role - the role of new SubjectNodes |
When a user successfully logs into Slide, their username is matched to a corresponding SubjectNode in the userspath .
That SubjectNode represents them within Slide. But what happens if a user's SubjectNode does not exist in the Domain structure?
If the value of auto-create-users is true, the default Java class slideroles.basic.UserRoleImpl will created as the SubjectNode.
You can override this default behavior with the auto-create-users-role element.
Note: See the difference between UserRole and UserRoleImpl ? The UserRole is a Java interface, so it cannot be instatiated. The mapping between the roles
listed in role section and the implementations are listed below:
-
slideroles.basic.RootRole - slideroles.basic.RootRoleImpl
-
slideroles.basic.UserRole - slideroles.basic.UserRoleImpl
-
slideroles.basic.GuestRole - slideroles.basic.GuestRoleImpl
For additional roles, a developer needs to follow the same pattern of class/interface.
Example for GuestRole : <auto-create-users-role>slideroles.basic.GuestRoleImpl</auto-create-users-role>
|
default-property - adding default properties to a SubjectNode |
Properties are an important part of the WebDAV standard. For a complete explanation of what properties
are, I recommend reading the WebDAV specification, but briefly a property is:
- a piece of information related to a URI within a WebDAV collection
- can be "live" or "dead"
- Live properties can be changed automatically by the server
- Dead properties are stored by the server but completely managed by the client
- can be associated with XML namespaces
In short, a Java programmer can think of WebDAV properties like they would a java.util.Properties object managed by the server. Each property must have a unique name (a combination
of the common name and the optional XML namespace) and contains a value. Properties can appear or disappear depending on server conditions (if the properties are "live"), and the values of these
properties can change (again, if the properties are "live"). Clients may also add or remove dead properties to a URI resource if they have the appropriate privileges.
One example of a live property is getlastmodified , which contains the time the associated resource was modified.
Use default-property tags for adding default properties to particular roles. There are four well-known roles in Slide:
-
root | root role
-
user | user role
-
guest | guest role
-
nobody | nobody role
Example default-property tag :
<default-property name="my-first-property-name" namespace="http://www.java-internals.com/slide/properties" value="my-first-property-default-value" role="nobody" />
The combination of the name and namespace attributes must not conflict with other properties of the same node. However, the names of two properties may be equal
as long as they have different values for the namespace attribute. I recommend using a URL to your personal home page as the URI in the namespace attribute.
Attribute name |
Description |
Example |
Default value |
name |
the local name of this WebDAV property. Used with the optional namespace attribute to form the complete name of the property |
my-first-property-name |
N/A | this attribute is required |
namespace |
the optional XML namespace for this WebDAV property. Used with the mandatory name attribute to form the complete name of the property |
http://www.java-internals.com/slide/properties |
"" the empty namespace |
value |
the optional default value of this property. Clients may change this value later. |
my-first-property-default-value |
"" the empty value |
role |
this default property and value is associated with all nodes of this role (root|user|guest|nobody) |
nobody |
N/A | this attribute is required |
Note: the nobody role is a special role that applies to all nodes created in the Namespace. For example, if we add a new file to the /files area of the structure,
that node will have all of the associated nobody role default properties.
|
content-interceptor - plug yourself in with custom handlers |
Content interceptors are called by Slide during various stages of a request. Developing content interceptors is outside the scope of this configuration
document, but in summary a content interceptor must:
- implement the
org.apache.slide.content.ContentInterceptor interface
- override the methods in the interface
Child Element Name |
Minimum |
Maximum |
parameter |
0 |
unlimited |
Attribute name |
Description |
Example |
Default value |
class |
the fully-qualified Java class name of the ContentInterceptor to install into the Slide runtime |
com.java_internals.slide.intercept.MyFirstInterceptor |
N/A | this attribute is required |
Example content interceptor w/o parameters:
<content-interceptor class="com.java_internals.slide.intercept.MyFirstInterceptor" />
Example content interceptor with parameters:
<content-interceptor class="com.java_internals.slide.intercept.MyFirstInterceptor">
<parameter name="some-name">some value</parameter> </content-interceptor>
|
ObjectNode - declaring nodes in the namespace |
ObjectNodes give us a way to define the namespace tree structure within the configuration file. Each ObjectNode has several associated properties:
Attribute name |
Description |
Example |
Default value |
classname |
the fully-qualified Java class name of the ObjectNode |
org.apache.slide.structure.SubjectNode |
N/A | this attribute is required |
uri |
path to this node within the collection |
/users/GroupA |
N/A | this attribute is required |
linkedUri |
only used with link nodes. The path to the actual node in the structure |
/users/foobar |
N/A | this attribute is required |
LinkNodes give us a way of placing dummy nodes in the namespace that refer to other real nodes:
As you can see from the above image, the green foobar node in GroupA links to the foobar node in the Users portion of the tree.
Example of a regular SubjectNode:
<objectnode
classname="org.apache.slide.structure.SubjectNode"
uri="/users/foobar" />
Example of a LinkNode:
<objectnode
classname="org.apache.slide.structure.LinkNode"
uri="/users/GroupA/foobar"
linkedUri="/users/foobar" />
ObjectNode elements may contain other ObjectNodes as well:
<objectnode classname="org.apache.slide.structure.SubjectNode" uri="/users">
<objectnode classname="org.apache.slide.structure.SubjectNode" uri="/users/foobar" />
</objectnode>
|
revision - declaring revisions of an ObjectNode in the configuration file |
You can list revisions of an ObjectNode with the revision element.
Attribute name |
Description |
Example |
Default value |
number |
the revisions's tag number |
2 |
N/A | this attribute is required |
uri |
path to this node within the collection |
/users/GroupA |
N/A | this attribute is required |
linkedUri |
only used with link nodes. The path to the actual node in the structure |
/users/foobar |
N/A | this attribute is required |
Example of a revision: <revision number="1" />
|
permission - controlling access to an ObjectNode |
Slide controls access to ObjectNodes through permissions . A permission consists of four components:
- what (action)
- who (subject)
- grant/deny (negative)
- affect child nodes (inheritable)
Attribute name |
Description |
Example |
Default value |
action |
path to the ActionNode |
/actions/write |
N/A | this attribute is required |
subject |
name of the subject or role who will be affected by this rule |
root |
N/A | this attribute is required |
negative |
if true, deny the user access to this action |
true |
false |
inherit |
if true, all child nodes of this SubjectNode receive the same permission |
true |
false |
Example of permission: <permission action="/actions/manage" subject="foobar" negative="false" inherit="true" />
How is the above permission evaluated? Whenever the foobar (subject) attempts the manage (action) action on the files (the ObjectNode containing the permission object)
node or its children (inherit), the action is permitted.
|
|