Index: /waeup/branches/ulif-rewrite/src/waeup/datacenter.txt
===================================================================
--- /waeup/branches/ulif-rewrite/src/waeup/datacenter.txt	(revision 4169)
+++ /waeup/branches/ulif-rewrite/src/waeup/datacenter.txt	(revision 4169)
@@ -0,0 +1,146 @@
+WAeUP Data Center
+*****************
+
+The WAeUP data center cares for managing CSV files and importing then.
+
+:Test-Layer: unit
+
+Creating a data center
+======================
+
+A data center can be created easily:
+
+    >>> from waeup.datacenter import DataCenter
+    >>> mydatacenter = DataCenter()
+    >>> mydatacenter
+    <waeup.datacenter.DataCenter object at 0x...>
+
+Each data center has a location in file system where files are stored:
+
+    >>> storagepath = mydatacenter.storage
+    >>> storagepath
+    '/.../src/waeup/files'
+
+
+Uploading files
+===============
+
+We can get a list of files stored in that location:
+
+    >>> mydatacenter.getFiles()
+    []
+
+Let's put some file in the storage:
+
+    >>> import os
+    >>> filepath = os.path.join(storagepath, 'data.csv')
+    >>> open(filepath, 'wb').write('Some Content\n')
+
+Now we can find a file:
+
+    >>> mydatacenter.getFiles()
+    [<waeup.datacenter.DataCenterFile object at 0x...>]
+
+As we can see, the actual file is wrapped by a convenience wrapper,
+that enables us to fetch some data about the file. The data returned
+is formatted in strings, so that it can easily be put into output
+pages:
+
+    >>> datafile = mydatacenter.getFiles()[0]
+    >>> datafile.getSize()
+    '13 bytes'
+
+    >>> datafile.getDate() # Nearly current datetime...
+    '...'
+
+Clean up:
+
+    >>> os.unlink(filepath)
+
+
+Handling imports
+================
+
+Data centers can find objects ready for CSV imports and associate
+appropriate importers with them.
+
+To do so, data centers look up their parents for the nearest ancestor,
+that implements `ICSVDataReceivers` and grab all attributes, that
+provide some importer.
+
+We therefore have to setup a proper scenario first.
+
+We start by creating a simple thing that is ready for receiving CSV
+data:
+
+    >>> class MyCSVReceiver(object):
+    ...   pass
+
+Then we create a container for such a CSV receiver:
+
+    >>> import grok
+    >>> from waeup.interfaces import ICSVDataReceivers
+    >>> from waeup.datacenter import DataCenter
+    >>> class SomeContainer(grok.Container):
+    ...   grok.implements(ICSVDataReceivers)
+    ...   def __init__(self):
+    ...     self.some_receiver = MyCSVReceiver()
+    ...     self.other_receiver = MyCSVReceiver()
+    ...     self.datacenter = DataCenter()
+
+By implementing `ICSVDataReceivers`, a pure marker interface, we
+indicate, that we want instances of this class to be searched for CSV
+receivers.
+
+This root container has two CSV receivers.
+
+The datacenter is also an attribute of our root container.
+
+Before we can go into action, we also need an importer, that is able
+to import data into instances of MyCSVReceiver:
+
+    >>> from waeup.utils.importexport import CSVImporter
+    >>> class MyCSVImporter(CSVImporter):
+    ...   grok.context(MyCSVReceiver)
+    ...   datatype = u'My Stuff'
+    ...   column_terms = ['col1']
+    ...   def doImport(self, filepath, clear_old_data=True,
+    ...                                overwrite=True):
+    ...     print "Data imported!"
+
+We grok the components to get the importer (which is actually an
+adapter) registered with the component architechture:
+
+    >>> grok.testing.grok('waeup')
+    >>> grok.testing.grok_component('MyCSVImporter', MyCSVImporter)
+    True
+
+Now we can create an instance of `SomeContainer`:
+
+    >>> mycontainer = SomeContainer()
+
+As we are not creating real sites and the objects are 'placeless' from
+the ZODB point of view, we fake a location by telling the datacenter,
+that its parent is the container:
+
+    >>> mycontainer.datacenter.__parent__ = mycontainer
+    >>> datacenter = mycontainer.datacenter
+
+When a datacenter is stored in the ZODB, this step will happen
+automatically.
+
+The datacenter is now able to find the CSV receivers in its parents:
+
+    >>> datacenter.getImporters()
+    [<MyCSVImporter object at 0x...>, <MyCSVImporter object at 0x...>]
+
+
+Imports with the WAeUP portal
+-----------------------------
+
+The examples above look complicated, but this is the price for
+modularity. If you create a new container type, you can define an
+importer and it will be used automatically by other components.
+
+In the WAeUP portal the only component that actually provides CSV data
+importables is the `University` object.
