NGObjWeb WebDAV Implementation for SoObjects
============================================

This subproject contains a WebDAV implementation for SOPE which is based on top
of the SoObjectRequestHandler.

The central point where processing starts once the request is received by the
handler, is the

  SoObjectWebDAVDispatcher

class. This class knows about the various WebDAV HTTP methods and takes
appropriate actions by calling specified methods on either the SoObject which
is targetted by the URL or on one of the maintenance objects. Eg WebDAV 
locking and notification is handled by the

  SoDAVLockManager
  SoSubscriptionManager

classes, so the targetted object itself doesn't need to concern itself about
that.

Once a WebDAV action has been performed, the

  SoWebDAVRenderer

class is used to turn the result value of the HTTP method in a suitable WebDAV
XML representation. To support non basic XML properties there is also a helper
class

  SoWebDAVValue


PROPFIND/SEARCH Queries
=======================

The payload of both, WebDAV PROPFIND and SEARCH methods are represented as a
regular EOControl EOFetchSpecification. The fetchspec is annotated with various
hints to add additional WebDAV information. This includes the required depth
of the query as well as the properties being requested.

In case a SEARCH query is decoded, a regular EOQualifier/EOSortOrdering is
used for representing that query.

To perform a query, the layer will call:

  - (id)performWebDAVQuery:(EOFetchSpecification *)_fetchSpecification
    inContext:(WOContext *)_context;

on the target object.

Note that there are default implementations for queries based on KVC
(see below)


A special feature is that an object can make the WebDAV layer "remap" the 
public WebDAV property names to internal names, for example KVC keys. To do so
the object needs to implement

  - (NSDictionary *)davAttributeMapInContext:(WOContext *)_context;

For example this can be used to map the "davDisplayName" to the "title" of a
given object.


Default Query Implementation
============================

The default implementation is done in the NSObject(SoDAVQuery) category which
requires an NSObject conforming to the "So" model of doing things. A query is
initiated by

  - (id)performWebDAVQuery:(EOFetchSpecification *)_fetchSpecification
    inContext:(WOContext *)_context;

The method then splits the operation based on the depth into one of those
methods for 'self'(0) or 'deep'(infinity) queries:

  - (id)davQueryOnSelf:(EOFetchSpecification *)_fs inContext:(WOContext *)_ctx;
  - (id)performWebDAVDeepQuery:((EOFetchSpecification *)_fs 
    inContext:(WOContext *)_ctx;

For 'flat'(1) queries it uses a datasource to fetch the content and the
-davQueryOnSelf:inContext: method to retrieve info on the object itself
(required by WebDAV, but buggy in some implementations, eg WebFolders). The
datasource is determined by

  - (EODataSource *)contentDataSourceInContext:(WOContext *)_context;

Per default this returns the SoObjectDataSource which performs KVC / EOControl
based filtering and sorting.

Besides those standard queries, the default implementations also deals with
bulk queries as generated by either BPROPFIND or by the _range_ URI hack for
ZideLook. Those will call

  - (id)performWebDAVBulkQuery:(EOFetchSpecification *)_fetchSpec
    inContext:(WOContext *)_context;

Its discouraged to use bulk queries, since they are non-standard.


In case no specific property names are requested (<allprop/> or a propfind
without a body), the toolkit is going to query the available property set
using:

  - (NSArray *)defaultWebDAVPropertyNamesInContext:(WOContext *)_context;
  TODO: check for soClass slots

Note that this is just the set used for allprop queries, you can still support
more properties than that (not sure whether that would be valid WebDAV though).



Special Features
================

The dispatcher supports various Exchange WebDAV enhancements, eg bulk queries
like BPROPFIND.

Further it supports so called "ZideStore range" queries which are treated
similiar to BPROPFIND and catches URLs starting with _range.


TODO
====

REPORT
- find a good way to represent arbitary reports

extended ops: ACL, CHECKOUT etc

- check for default property names (allprop) in SoClass slots

- add support for DAV:supportedlock property

- add support for property level 404 status
  - currently we just deliver empty tags or none (if the brief header is set)

- add Apache2 like typing namespaces on DAV:creationdate and 
  DAV:getlastmodified

Notes
=====

DASL:
  ---snip---
  <?xml version="1.0" encoding="utf-8" ?>
  <D:searchrequest xmlns:D="DAV:">
    <D:basicsearch>
      <D:select><D:allprop/></D:select>
      <D:from>
        <D:scope>
          <D:href>/evo/dav/helge/Private.plist/</D:href>
          <D:depth>infinity</D:depth>
        </D:scope>
      </D:from>
      <D:where>
        <D:eq>
          <D:prop><D:sn/></D:prop>
          <D:literal>Mueller</D:literal>
        </D:eq>
      </D:where>
    </D:basicsearch>
  </D:searchrequest>
  ---snap---
  SQL-search queries use
    <D:searchrequest><D:sql>
  instead of
    <D:searchrequest><D:basicsearch>