You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oodt.apache.org by ke...@apache.org on 2010/07/28 01:03:48 UTC

svn commit: r979904 [1/5] - in /incubator/oodt/tools/oodtsite.publisher/trunk: ./ docs/ oodtsite/ oodtsite/publisher/ oodtsite/publisher/rules/ oodtsite/publisher/tests/ oodtsite/publisher/tests/data/ oodtsite/publisher/tests/data/oodt/ oodtsite/publis...

Author: kelly
Date: Tue Jul 27 23:03:44 2010
New Revision: 979904

URL: http://svn.apache.org/viewvc?rev=979904&view=rev
Log:
OODT Site Publisher: initial implementation

Added:
    incubator/oodt/tools/oodtsite.publisher/trunk/MANIFEST.in
    incubator/oodt/tools/oodtsite.publisher/trunk/NOTICE.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/README.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py
    incubator/oodt/tools/oodtsite.publisher/trunk/docs/
    incubator/oodt/tools/oodtsite.publisher/trunk/docs/HISTORY.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/docs/INSTALL.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/docs/LICENSE.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/__init__.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/__init__.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/artifacts.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/errors.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/main.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/publishers.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/globalnav.xml
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/head.xml
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/home.xml
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/maven.xml
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/standard.xml
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/__init__.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/base.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/bad.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/empty.txt
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/core/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/core/target/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/core/target/site/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/apidocs/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/apidocs/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/apidocs/package-list
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/checkstyle.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/checkstyle.rss
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/css/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/css/maven-base.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/css/maven-theme.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/css/print.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/css/site.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/dependencies.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/dependency-convergence.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/findbugs.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/close.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/collapsed.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/delegation.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/delegation.psd   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/expanded.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/external.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/grid-product.jpg   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/icon_error_sml.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/icon_info_sml.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/icon_success_sml.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/icon_warning_sml.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/logos/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/logos/build-by-maven-black.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/logos/build-by-maven-white.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/logos/maven-feather.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/newwindow.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/images/rss.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/integration.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/issue-tracking.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/license.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/mail-lists.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/plugin-management.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/plugins.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/project-info.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/project-reports.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/project-summary.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/rat-report.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/servlet/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/servlet/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/source-repository.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/surefire-report.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/team-list.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/xref/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/xref-test/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/xref-test/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/primary/target/site/xref/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/subdir/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/subdir/secondary/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/subdir/secondary/target/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/subdir/secondary/target/site/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/target/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/target/site/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/target/site/apidocs/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/target/site/xref/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/oodt/target/site/xref-test/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/referenceless.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/referenceless.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/about/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/about/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/about/test.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/components/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/components/cas/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/components/cas/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/components/cas/misc.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/components/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/contact/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/contact/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/development/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/development/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/downloads/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/downloads/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/static/index.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.jpg   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.mp3   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.pdf   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/test.psd   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/data/unknown.dat
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/test_artifacts.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/test_publishers.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/tests/test_transformers.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/apacheOODT.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/bannerTile.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/error.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/headerBGTile.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-agility.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-cas.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-common.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-grid.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-query.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/icon-rss.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/iconNews.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/info.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/oodtBanner.jpg   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/simpleApacheOODT.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/sprite-ploneorg.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/subBannerTile.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/success.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/vertSep.gif   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/images/warning.png   (with props)
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/oodt.css
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/themes/standard.html
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/transformers.py
    incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/utils.py
    incubator/oodt/tools/oodtsite.publisher/trunk/setup.cfg
    incubator/oodt/tools/oodtsite.publisher/trunk/setup.py
Modified:
    incubator/oodt/tools/oodtsite.publisher/trunk/   (props changed)

Propchange: incubator/oodt/tools/oodtsite.publisher/trunk/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jul 27 23:03:44 2010
@@ -0,0 +1,9 @@
+._*
+.DS_Store
+*.log
+*.pyc
+*.pyo
+*.egg-info
+dist
+build
+target

Added: incubator/oodt/tools/oodtsite.publisher/trunk/MANIFEST.in
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/MANIFEST.in?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/MANIFEST.in (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/MANIFEST.in Tue Jul 27 23:03:44 2010
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+recursive-include oodtsite *
+global-exclude *pyc *pyo
+

Added: incubator/oodt/tools/oodtsite.publisher/trunk/NOTICE.txt
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/NOTICE.txt?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/NOTICE.txt (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/NOTICE.txt Tue Jul 27 23:03:44 2010
@@ -0,0 +1,7 @@
+Apache OODT Site Publisher (OODT)
+Copyright 2010 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This is licensed software; see the docs/LICENSE.txt file.

Added: incubator/oodt/tools/oodtsite.publisher/trunk/README.txt
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/README.txt?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/README.txt (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/README.txt Tue Jul 27 23:03:44 2010
@@ -0,0 +1,17 @@
+The Apache OODT Site Publisher is a utility that lets members of the Apache
+OODT_ team publish and maintain our public website_.  Although the general
+public is probably far more interested in Apache OODT itself than this site
+publication utility, it too is Apache open source.
+
+.. This is licensed software; see the files NOTICE.txt and docs/LICENSE.txt.
+
+.. For installation instructions, see docs/INSTALL.txt.
+
+.. References:
+.. _OODT: http://incubator.apache.org/projects/oodt.html
+.. _website:  http://incubator.apache.org/projects/oodt.html
+
+.. meta::
+    :keywords: Apache OODT, site, content management, web content
+    :description lang=en: Apache OODT website publication utility for public
+        image maintenance

Added: incubator/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/distribute_setup.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,485 @@
+#!python
+"""Bootstrap distribute installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from distribute_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import os
+import sys
+import time
+import fnmatch
+import tempfile
+import tarfile
+from distutils import log
+
+try:
+    from site import USER_SITE
+except ImportError:
+    USER_SITE = None
+
+try:
+    import subprocess
+
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        return subprocess.call(args) == 0
+
+except ImportError:
+    # will be used for python 2.3
+    def _python_cmd(*args):
+        args = (sys.executable,) + args
+        # quoting arguments if windows
+        if sys.platform == 'win32':
+            def quote(arg):
+                if ' ' in arg:
+                    return '"%s"' % arg
+                return arg
+            args = [quote(arg) for arg in args]
+        return os.spawnl(os.P_WAIT, sys.executable, *args) == 0
+
+DEFAULT_VERSION = "0.6.14"
+DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/"
+SETUPTOOLS_FAKED_VERSION = "0.6c11"
+
+SETUPTOOLS_PKG_INFO = """\
+Metadata-Version: 1.0
+Name: setuptools
+Version: %s
+Summary: xxxx
+Home-page: xxx
+Author: xxx
+Author-email: xxx
+License: xxx
+Description: xxx
+""" % SETUPTOOLS_FAKED_VERSION
+
+
+def _install(tarball):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # installing
+        log.warn('Installing Distribute')
+        if not _python_cmd('setup.py', 'install'):
+            log.warn('Something went wrong during the installation.')
+            log.warn('See the error message above.')
+    finally:
+        os.chdir(old_wd)
+
+
+def _build_egg(egg, tarball, to_dir):
+    # extracting the tarball
+    tmpdir = tempfile.mkdtemp()
+    log.warn('Extracting in %s', tmpdir)
+    old_wd = os.getcwd()
+    try:
+        os.chdir(tmpdir)
+        tar = tarfile.open(tarball)
+        _extractall(tar)
+        tar.close()
+
+        # going in the directory
+        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
+        os.chdir(subdir)
+        log.warn('Now working in %s', subdir)
+
+        # building an egg
+        log.warn('Building a Distribute egg in %s', to_dir)
+        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
+
+    finally:
+        os.chdir(old_wd)
+    # returning the result
+    log.warn(egg)
+    if not os.path.exists(egg):
+        raise IOError('Could not build the egg.')
+
+
+def _do_download(version, download_base, to_dir, download_delay):
+    egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg'
+                       % (version, sys.version_info[0], sys.version_info[1]))
+    if not os.path.exists(egg):
+        tarball = download_setuptools(version, download_base,
+                                      to_dir, download_delay)
+        _build_egg(egg, tarball, to_dir)
+    sys.path.insert(0, egg)
+    import setuptools
+    setuptools.bootstrap_install_from = egg
+
+
+def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                   to_dir=os.curdir, download_delay=15, no_fake=True):
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    was_imported = 'pkg_resources' in sys.modules or \
+        'setuptools' in sys.modules
+    try:
+        try:
+            import pkg_resources
+            if not hasattr(pkg_resources, '_distribute'):
+                if not no_fake:
+                    _fake_setuptools()
+                raise ImportError
+        except ImportError:
+            return _do_download(version, download_base, to_dir, download_delay)
+        try:
+            pkg_resources.require("distribute>="+version)
+            return
+        except pkg_resources.VersionConflict:
+            e = sys.exc_info()[1]
+            if was_imported:
+                sys.stderr.write(
+                "The required version of distribute (>=%s) is not available,\n"
+                "and can't be installed while this script is running. Please\n"
+                "install a more recent version first, using\n"
+                "'easy_install -U distribute'."
+                "\n\n(Currently using %r)\n" % (version, e.args[0]))
+                sys.exit(2)
+            else:
+                del pkg_resources, sys.modules['pkg_resources']    # reload ok
+                return _do_download(version, download_base, to_dir,
+                                    download_delay)
+        except pkg_resources.DistributionNotFound:
+            return _do_download(version, download_base, to_dir,
+                                download_delay)
+    finally:
+        if not no_fake:
+            _create_fake_setuptools_pkg_info(to_dir)
+
+def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL,
+                        to_dir=os.curdir, delay=15):
+    """Download distribute from a specified location and return its filename
+
+    `version` should be a valid distribute version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download
+    attempt.
+    """
+    # making sure we use the absolute path
+    to_dir = os.path.abspath(to_dir)
+    try:
+        from urllib.request import urlopen
+    except ImportError:
+        from urllib2 import urlopen
+    tgz_name = "distribute-%s.tar.gz" % version
+    url = download_base + tgz_name
+    saveto = os.path.join(to_dir, tgz_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            log.warn("Downloading %s", url)
+            src = urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = src.read()
+            dst = open(saveto, "wb")
+            dst.write(data)
+        finally:
+            if src:
+                src.close()
+            if dst:
+                dst.close()
+    return os.path.realpath(saveto)
+
+def _no_sandbox(function):
+    def __no_sandbox(*args, **kw):
+        try:
+            from setuptools.sandbox import DirectorySandbox
+            if not hasattr(DirectorySandbox, '_old'):
+                def violation(*args):
+                    pass
+                DirectorySandbox._old = DirectorySandbox._violation
+                DirectorySandbox._violation = violation
+                patched = True
+            else:
+                patched = False
+        except ImportError:
+            patched = False
+
+        try:
+            return function(*args, **kw)
+        finally:
+            if patched:
+                DirectorySandbox._violation = DirectorySandbox._old
+                del DirectorySandbox._old
+
+    return __no_sandbox
+
+def _patch_file(path, content):
+    """Will backup the file then patch it"""
+    existing_content = open(path).read()
+    if existing_content == content:
+        # already patched
+        log.warn('Already patched.')
+        return False
+    log.warn('Patching...')
+    _rename_path(path)
+    f = open(path, 'w')
+    try:
+        f.write(content)
+    finally:
+        f.close()
+    return True
+
+_patch_file = _no_sandbox(_patch_file)
+
+def _same_content(path, content):
+    return open(path).read() == content
+
+def _rename_path(path):
+    new_name = path + '.OLD.%s' % time.time()
+    log.warn('Renaming %s into %s', path, new_name)
+    os.rename(path, new_name)
+    return new_name
+
+def _remove_flat_installation(placeholder):
+    if not os.path.isdir(placeholder):
+        log.warn('Unkown installation at %s', placeholder)
+        return False
+    found = False
+    for file in os.listdir(placeholder):
+        if fnmatch.fnmatch(file, 'setuptools*.egg-info'):
+            found = True
+            break
+    if not found:
+        log.warn('Could not locate setuptools*.egg-info')
+        return
+
+    log.warn('Removing elements out of the way...')
+    pkg_info = os.path.join(placeholder, file)
+    if os.path.isdir(pkg_info):
+        patched = _patch_egg_dir(pkg_info)
+    else:
+        patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO)
+
+    if not patched:
+        log.warn('%s already patched.', pkg_info)
+        return False
+    # now let's move the files out of the way
+    for element in ('setuptools', 'pkg_resources.py', 'site.py'):
+        element = os.path.join(placeholder, element)
+        if os.path.exists(element):
+            _rename_path(element)
+        else:
+            log.warn('Could not find the %s element of the '
+                     'Setuptools distribution', element)
+    return True
+
+_remove_flat_installation = _no_sandbox(_remove_flat_installation)
+
+def _after_install(dist):
+    log.warn('After install bootstrap.')
+    placeholder = dist.get_command_obj('install').install_purelib
+    _create_fake_setuptools_pkg_info(placeholder)
+
+def _create_fake_setuptools_pkg_info(placeholder):
+    if not placeholder or not os.path.exists(placeholder):
+        log.warn('Could not find the install location')
+        return
+    pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1])
+    setuptools_file = 'setuptools-%s-py%s.egg-info' % \
+            (SETUPTOOLS_FAKED_VERSION, pyver)
+    pkg_info = os.path.join(placeholder, setuptools_file)
+    if os.path.exists(pkg_info):
+        log.warn('%s already exists', pkg_info)
+        return
+
+    log.warn('Creating %s', pkg_info)
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+
+    pth_file = os.path.join(placeholder, 'setuptools.pth')
+    log.warn('Creating %s', pth_file)
+    f = open(pth_file, 'w')
+    try:
+        f.write(os.path.join(os.curdir, setuptools_file))
+    finally:
+        f.close()
+
+_create_fake_setuptools_pkg_info = _no_sandbox(_create_fake_setuptools_pkg_info)
+
+def _patch_egg_dir(path):
+    # let's check if it's already patched
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    if os.path.exists(pkg_info):
+        if _same_content(pkg_info, SETUPTOOLS_PKG_INFO):
+            log.warn('%s already patched.', pkg_info)
+            return False
+    _rename_path(path)
+    os.mkdir(path)
+    os.mkdir(os.path.join(path, 'EGG-INFO'))
+    pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO')
+    f = open(pkg_info, 'w')
+    try:
+        f.write(SETUPTOOLS_PKG_INFO)
+    finally:
+        f.close()
+    return True
+
+_patch_egg_dir = _no_sandbox(_patch_egg_dir)
+
+def _before_install():
+    log.warn('Before install bootstrap.')
+    _fake_setuptools()
+
+
+def _under_prefix(location):
+    if 'install' not in sys.argv:
+        return True
+    args = sys.argv[sys.argv.index('install')+1:]
+    for index, arg in enumerate(args):
+        for option in ('--root', '--prefix'):
+            if arg.startswith('%s=' % option):
+                top_dir = arg.split('root=')[-1]
+                return location.startswith(top_dir)
+            elif arg == option:
+                if len(args) > index:
+                    top_dir = args[index+1]
+                    return location.startswith(top_dir)
+        if arg == '--user' and USER_SITE is not None:
+            return location.startswith(USER_SITE)
+    return True
+
+
+def _fake_setuptools():
+    log.warn('Scanning installed packages')
+    try:
+        import pkg_resources
+    except ImportError:
+        # we're cool
+        log.warn('Setuptools or Distribute does not seem to be installed.')
+        return
+    ws = pkg_resources.working_set
+    try:
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools',
+                                  replacement=False))
+    except TypeError:
+        # old distribute API
+        setuptools_dist = ws.find(pkg_resources.Requirement.parse('setuptools'))
+
+    if setuptools_dist is None:
+        log.warn('No setuptools distribution found')
+        return
+    # detecting if it was already faked
+    setuptools_location = setuptools_dist.location
+    log.warn('Setuptools installation detected at %s', setuptools_location)
+
+    # if --root or --preix was provided, and if
+    # setuptools is not located in them, we don't patch it
+    if not _under_prefix(setuptools_location):
+        log.warn('Not patching, --root or --prefix is installing Distribute'
+                 ' in another location')
+        return
+
+    # let's see if its an egg
+    if not setuptools_location.endswith('.egg'):
+        log.warn('Non-egg installation')
+        res = _remove_flat_installation(setuptools_location)
+        if not res:
+            return
+    else:
+        log.warn('Egg installation')
+        pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO')
+        if (os.path.exists(pkg_info) and
+            _same_content(pkg_info, SETUPTOOLS_PKG_INFO)):
+            log.warn('Already patched.')
+            return
+        log.warn('Patching...')
+        # let's create a fake egg replacing setuptools one
+        res = _patch_egg_dir(setuptools_location)
+        if not res:
+            return
+    log.warn('Patched done.')
+    _relaunch()
+
+
+def _relaunch():
+    log.warn('Relaunching...')
+    # we have to relaunch the process
+    # pip marker to avoid a relaunch bug
+    if sys.argv[:3] == ['-c', 'install', '--single-version-externally-managed']:
+        sys.argv[0] = 'setup.py'
+    args = [sys.executable] + sys.argv
+    sys.exit(subprocess.call(args))
+
+
+def _extractall(self, path=".", members=None):
+    """Extract all members from the archive to the current working
+       directory and set owner, modification time and permissions on
+       directories afterwards. `path' specifies a different directory
+       to extract to. `members' is optional and must be a subset of the
+       list returned by getmembers().
+    """
+    import copy
+    import operator
+    from tarfile import ExtractError
+    directories = []
+
+    if members is None:
+        members = self
+
+    for tarinfo in members:
+        if tarinfo.isdir():
+            # Extract directories with a safe mode.
+            directories.append(tarinfo)
+            tarinfo = copy.copy(tarinfo)
+            tarinfo.mode = 448 # decimal for oct 0700
+        self.extract(tarinfo, path)
+
+    # Reverse sort directories.
+    if sys.version_info < (2, 4):
+        def sorter(dir1, dir2):
+            return cmp(dir1.name, dir2.name)
+        directories.sort(sorter)
+        directories.reverse()
+    else:
+        directories.sort(key=operator.attrgetter('name'), reverse=True)
+
+    # Set correct owner, mtime and filemode on directories.
+    for tarinfo in directories:
+        dirpath = os.path.join(path, tarinfo.name)
+        try:
+            self.chown(tarinfo, dirpath)
+            self.utime(tarinfo, dirpath)
+            self.chmod(tarinfo, dirpath)
+        except ExtractError:
+            e = sys.exc_info()[1]
+            if self.errorlevel > 1:
+                raise
+            else:
+                self._dbg(1, "tarfile: %s" % e)
+
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    tarball = download_setuptools()
+    _install(tarball)
+
+
+if __name__ == '__main__':
+    main(sys.argv[1:])

Added: incubator/oodt/tools/oodtsite.publisher/trunk/docs/HISTORY.txt
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/docs/HISTORY.txt?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/docs/HISTORY.txt (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/docs/HISTORY.txt Tue Jul 27 23:03:44 2010
@@ -0,0 +1,13 @@
+Changelog
+=========
+
+What follows is a history of changes to this software.
+
+
+0.0.0 - Initial
+---------------
+
+Initial release for testing and development.
+
+
+.. This is licensed software; see the files NOTICE.txt and docs/LICENSE.txt.

Added: incubator/oodt/tools/oodtsite.publisher/trunk/docs/INSTALL.txt
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/docs/INSTALL.txt?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/docs/INSTALL.txt (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/docs/INSTALL.txt Tue Jul 27 23:03:44 2010
@@ -0,0 +1,44 @@
+Installation
+============
+
+What follows are the installation instructions for the OODT Site Publisher.
+
+
+Quick Instructions
+------------------
+
+You'll probably want to use a virtualenv_ or a buildout_ to use this software.
+But if you prefer, you can run::
+
+    pip oodsite.publisher
+
+or, if you're *really* old fashioned, try::
+
+    easy_install oodtsite.publisher
+
+And you're done.
+
+
+For More Information
+--------------------
+
+Visit any of the following links for additional information, to ask questions,
+report bugs, and so forth:
+
+OODT Home Page
+    http://incubator.apache.org/oodt/
+Mailing List for OODT Development
+    mailto:oodt-dev@incubator.apache.org
+Package Page (Cheese Shop)
+    http://pypi.python.org/pypi/oodtsite.publisher/
+Issue Tracker (submit bug reports here)
+    https://issues.apache.org/jira/browse/OODT
+
+.. This is licensed software; see the files NOTICE.txt and docs/LICENSE.txt.
+
+.. References:
+.. _buildout: http://www.buildout.org
+.. _EasyInstall: http://packages.python.org/distribute/easy_install.html
+.. _Pip: http://pip.openplans.org/
+.. _Python: http://python.org/
+.. _virtualenv: http://pypi.python.org/pypi/virtualenv

Added: incubator/oodt/tools/oodtsite.publisher/trunk/docs/LICENSE.txt
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/docs/LICENSE.txt?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/docs/LICENSE.txt (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/docs/LICENSE.txt Tue Jul 27 23:03:44 2010
@@ -0,0 +1,179 @@
+License, Terms, and Conditions
+==============================
+
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/__init__.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/__init__.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/__init__.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/__init__.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,22 @@
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+#
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/__init__.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/__init__.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/__init__.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/__init__.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,19 @@
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+'''OODT Site Publisher'''
+
+__docformat__ = 'restructuredtext en'

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/artifacts.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/artifacts.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/artifacts.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/artifacts.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,179 @@
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+'''Artifacts that can be published for the Apache OODT site.  Artifacts come
+in various kinds represented by concrete subclasses.  Each artifact knows how
+to:
+
+* Adjust absolute RUI references that it may have to external artifacts by
+  prepending a base URL
+* Transform itself from an artifact-specific HTML style into the OODT-specific
+  HTML style
+* Write itself out to disk.
+'''
+
+__docformat__ = 'restructuredtext en'
+
+import os.path, re, shutil, logging
+from utils import forciblyClose, parseHTML
+
+_logger = logging.getLogger(__name__)
+
+# Regexp that matches URLs in CSS files that are absolute (start with /) but not external.
+_absoluteCSSURLRE = re.compile(ur'''url\(["']?/([^"')]+)["']?\)''', re.IGNORECASE)
+
+# Regexp for opaque files
+_opaqueFileRE = ur'\.(png|gif|jpe?g|js(on)?|mov|mp4[a-z]?|ogg|pdf|pgp|asc|sig|torrent|hdf|mp3|jar|txt|h26[0-9]|mpeg)|package-list$'
+
+class _Artifact(object):
+    '''An abstract publication artifact: such as HTML, image, etc.'''
+    def __init__(self, name):
+        '''Every artifact gets a name.'''
+        self.name = name
+    def adjustReferences(self, baseURL):
+        '''Modify any references in this artifact to take advantage of the ``baseURL``, if necessary.
+        By default, we do nothing.'''
+        pass
+    def transform(self, xformer):
+        '''Transform this artifact using the given ``xformer``.  By default, we ignore the given
+        ``xformer`` and do nothing.'''
+        pass
+    def write(self, targetDir):
+        '''Write the contents of this artifact to the given ``targetDir``.  Subclasses must implement
+        this method.'''
+        raise NotImplementedError('Subclasses must implement the "write" method')
+    def __cmp__(self, other):
+        '''Compare this artifact with another object.'''
+        rc = cmp(self.__class__, other.__class__)
+        if rc == 0:
+            return cmp(self.name, other.name)
+        return rc
+    def __hash__(self):
+        '''Hash this artifact'''
+        return hash(self.name)
+    def __repr__(self):
+        '''Programmer-friendly representation'''
+        return '%s(name=%s)' % (self.__class__.__name__, self.name)
+    
+
+class PageArtifact(_Artifact):
+    '''A web page artifact that contains HTML.'''
+    def __init__(self, name, filename=None, tree=None):
+        super(PageArtifact, self).__init__(name)
+        assert filename is None or tree is None
+        self.tree = filename and parseHTML(filename) or tree
+    def transform(self, xformer):
+        # TODO: warn or ignore if xformer is None? And what if tree is empty?
+        _logger.info('Transforming %s HTML using %s', self.name, xformer)
+        self.tree = xformer(self.tree)
+    def adjustReferences(self, baseURL):
+        _logger.info('Adjusting references to point to %s', baseURL)
+        for elem in self.tree.getroot().iter():
+            attributes = elem.attrib
+            for a in ('src', 'href'):
+                if a in attributes:
+                    value = attributes[a]
+                    if value.startswith(u'/'):
+                        attributes[a] = baseURL + value
+    def write(self, targetDir):
+        target = os.path.join(targetDir, self.name)
+        _logger.info('Writing HTML to "%s"', target)
+        self.tree.write(target, encoding='utf-8', xml_declaration=True, pretty_print=False)
+    
+
+class OpaqueArtifact(_Artifact):
+    '''An opaque artifact like an image, audio file, etc.'''
+    def __init__(self, name, filename=None, data=None):
+        super(OpaqueArtifact, self).__init__(name)
+        self.filename, self.data = filename, data
+        assert filename is None or data is None
+    def write(self, targetDir):
+        dst = os.path.join(targetDir, self.name)
+        if self.filename:
+            _logger.info('Directly copying "%s" to "%s"', self.filename, dst)
+            shutil.copyfile(self.filename, dst)
+        else:
+            _logger.info('Writing opaque data to "%s"', dst)
+            o = None
+            try:
+                o = open(dst, 'w')
+                o.write(self.data)
+            finally:
+                o.close()
+    
+
+class StyleArtifact(_Artifact):
+    '''A cascading style sheet artifact'''
+    def __init__(self, name, filename=None, css=None):
+        super(StyleArtifact, self).__init__(name)
+        assert filename is None or css is None
+        if filename:
+            i = None
+            try:
+                i = open(filename)
+                self.css = i.read()
+            finally:
+                forciblyClose(i)
+        else:
+            self.css = css
+    def adjustReferences(self, baseURL):
+        if not baseURL.endswith('/'):
+            baseURL = baseURL + '/'
+        self.css = re.sub(_absoluteCSSURLRE, u'url("%s\\1")' % baseURL, self.css)
+    def write(self, targetDir):
+        o = None
+        try:
+            target = os.path.join(targetDir, self.name)
+            _logger.info('Writing CSS to "%s"', target)
+            o = open(target, 'w')
+            o.write(self.css)
+        finally:
+            forciblyClose(o)
+    
+
+class IgnoredArtifact(_Artifact):
+    '''An artifact we ignore and otherwise do nothing with'''
+    def __init__(self, name, filename=None):
+        self.name, self.filename = name, filename
+    def write(self, targetDir):
+        _logger.info('Blithely ignoring "%s" by NOT writing it to "%s"', self.name, targetDir)
+    
+
+# Sequence of ``(r, a)`` pairs where ``r`` is a regular expression matching an artifact file path
+# and ``a`` is an ``_Artifact`` class tailored for those kinds of files.
+_artifactClasses = [
+    (re.compile(ur'\.(html?|xml|rdf|rss)$', re.IGNORECASE), PageArtifact),
+    (re.compile(ur'\.css$', re.IGNORECASE),                 StyleArtifact),
+    (re.compile(_opaqueFileRE, re.IGNORECASE),              OpaqueArtifact),
+    (re.compile(ur'(\.DS_Store|.*\.psd)$', re.IGNORECASE),  IgnoredArtifact),
+]
+
+def constructArtifact(filename):
+    '''Construct an appropriate artifact object for the given ``filename``.  Returns ``None``
+    if the artifact is unknown.'''
+    if filename is None: return None
+    if not isinstance(filename, basestring): raise TypeError('String filename required: %r is not' % filename)
+    base, obj = os.path.basename(filename), None
+    for regexp, artifactClass in _artifactClasses:
+        if regexp.search(base):
+            obj = artifactClass(base, filename)
+            break
+    if not obj:
+        _logger.debug('No matching artifact class for file "%s" (from "%s")', base, filename)
+    else:
+        _logger.debug('File "%s" gets a "%s" artifact class', filename, obj.__class__.__name__)
+    return obj
+    

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/errors.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/errors.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/errors.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/errors.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,45 @@
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+'''Errors and exceptions that can occur when publishing the Apache OODT site.'''
+
+__docformat__ = 'restructuredtext en'
+
+class PublicationError(Exception):
+    '''Exception indicating a publication error'''
+
+class _PublicationFilesystemEntryError(PublicationError):
+    '''Abstract exception indicating that a required entry in the filesystem is missing'''
+    def __init__(self, path, kind):
+        super(_PublicationFilesystemEntryNotFound, self).__init__('Required "%s" not found (or is not a %s)' % (path, kind))
+
+class PublicationFileNotFound(_PublicationFilesystemEntryError):
+    '''Exception indicating a file is missing'''
+    def __init__(self, filePath):
+        super(PublicationFileNotFound, self).__init__(filePath, 'file')
+
+class PublicationDirNotFound(_PublicationFilesystemEntryError):
+    '''Exception indicating a required directory is missing'''
+    def __init__(self, dirPath):
+        super(PublicationDirNotFound, self).__init__(dirPath, 'directory')
+
+class UnexpectedFilesystemEntryError(PublicationError):
+    '''Exception indicating we found something in the filesystem we shouldn't have'''
+
+class PublicationTransformerNotFound(PublicationError):
+    '''Exception indicating that a named publication transformer does not exist'''
+    def __init__(self, transformerName):
+        super(PublicationTransformerNotFound, self).__init__('Transformer "%s" does not exist' % transformerName)

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/main.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/main.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/main.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/main.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+'''OODT Site Publisher: main entry point.'''
+
+__docformat__ = 'restructuredtext en'
+
+import optparse, sys, os, os.path, publishers, pkg_resources, artifacts, logging
+from utils import copyStreamToFile, forciblyClose
+
+_logger = logging.getLogger('oodtsite.publisher')
+
+_blacklistedComponents = ('oodt', 'core', 'skin')
+
+_version = '%prog 0.0.0'
+_description = '''FIXME: %prog takes a top-level CONTENT-DIR specified and traverses it, looking for HTML
+files and other web artifacts, and publishes them to the TARGET directory (defaulting to "site" in the
+current directory).  It transforms the plain HTML into the Apache OODT style along the way, while also
+rewriting URL references (image, style, and other sources as well as anchor hrefs) so that they're all
+absolutely correct.  It then does that with Maven-generated site content found under the OODT-DIR, as
+well as arranging special locations for the API documentation and other cross-component artifacts.
+
+Normally you can run this with no options and pass "src/content" as the CONTENT-DIRECTORY and get the
+Apache OODT site published in the right place.  However, during testing, you can use the --base option
+to get a different BASE URL (such as a file: URL for testing the site by having your browser open files
+on the filesystem).  You can also use the --target option to have output written to a scratch or other
+non-Subversion-controlled directory.'''
+
+_usage = 'Usage: %prog [options] CONTENT-DIR OODT-DIR'
+_op = optparse.OptionParser(usage=_usage, version=_version, description=_description)
+_op.add_option(
+    '-b', '--base', type='string', default='http://incubator.apache.org/oodt',
+    help='Use URL "BASE" to generate all hyper-references; use a file:-style URL for testing, use http:-style for a web server'
+)
+_op.add_option(
+    '-t', '--target', type='string', default='site',
+    help='Write site in directory TARGET; use a scratch directory for testing or use "site" dir in svn for live publication'
+)
+
+def publishOODTStyleSheet(target, base):
+    oodtStyleSheet = artifacts.StyleArtifact('oodt.css', css=pkg_resources.resource_string(__name__, 'themes/oodt.css'))
+    oodtStyleSheet.adjustReferences(base)
+    oodtStyleSheet.write(target)
+
+def publishStandardImagery(target, base):
+    targetImageDir = os.path.join(target, 'images')
+    if not os.path.isdir(targetImageDir):
+        os.makedirs(targetImageDir)
+    for fn in pkg_resources.resource_listdir(__name__, 'themes/images'):
+        i = None
+        try:
+            i = pkg_resources.resource_stream(__name__, 'themes/images/%s' % fn)
+            copyStreamToFile(i, os.path.join(targetImageDir, fn))
+        finally:
+            forciblyClose(i)
+
+def publishOODTSite(top, oodt, target, base):
+    if not os.path.isdir(target):
+        os.makedirs(target)
+    publishOODTStyleSheet(target, base)
+    publishStandardImagery(target, base)
+    p = publishers.HomePublisher()
+    p.publish(top, target, base)
+    componentsDir = os.path.join(target, 'components', 'maven')
+    # FIXME: count, log, warn, error if no target/site dirs?
+    for dirpath, dirnames, filenames in os.walk(oodt):
+        siteDir = os.path.join(dirpath, 'target', 'site')
+        if not os.path.isdir(siteDir): continue # No xxx/component/site? Skip it
+        componentName, dst = os.path.basename(dirpath), os.path.join(componentsDir, dirpath[len(oodt)+1:])
+        _logger.debug('CONSIDERING "%s" against "%r": skippage? %r', componentName, _blacklistedComponents,
+            componentName in _blacklistedComponents)
+        if componentName in _blacklistedComponents:
+            _logger.info('Skipping blacklisted %s', componentName)
+            continue
+        publishers.MavenPublisher().publish(siteDir, dst, base)
+    for dirname in ('apidocs', 'xref', 'xref-test'):
+        sourcedir = os.path.join(oodt, 'target', 'site', dirname)
+        destdir = os.path.join(componentsDir, dirname)
+        publishers.JavaDocsPublisher().publish(sourcedir, destdir, base)
+    # TODO: Python components . . .
+    # TODO: News items
+
+def setupLogging():
+    logger = logging.getLogger('oodtsite.publisher')
+    logger.setLevel(logging.WARNING)
+    # TODO: be more sophisticated?
+
+def main(argv=None):
+    options, args = _op.parse_args(argv)
+    if len(args) != 2:
+        _op.error('You must specify *both* a top-level content directory and the OODT code directory')
+    top, oodt, base, target = os.path.abspath(args[0]), os.path.abspath(args[1]), options.base, os.path.abspath(options.target)
+    if not os.path.exists(top):
+        _op.error('The top-level content directory "%s" doesn\'t even exist' % top)
+    if not os.path.isdir(top):
+        _op.error('I cannot use "%s" as a content directory, because it\'s not a directory' % top)
+    if not os.path.exists(oodt):
+        _op.error('The OODT project directory "%s" doesn\'t even exist' % oodt)
+    if not os.path.isdir(oodt):
+        _op.error('I cannot use "%s" as the OODT project directory, because it\'s not a directory' % oodt)
+    setupLogging()
+    publishOODTSite(top, oodt, target, base)
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
+

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/publishers.py
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/publishers.py?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/publishers.py (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/publishers.py Tue Jul 27 23:03:44 2010
@@ -0,0 +1,151 @@
+# encoding: utf-8
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE.txt file distributed with
+# this work for additional information regarding copyright ownership.  The ASF
+# licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.    
+
+'''OODT Site Publisher: publishers'''
+
+__docformat__ = 'restructuredtext en'
+
+from errors import PublicationDirNotFound, PublicationFileNotFound, UnexpectedFilesystemEntryError
+import os, os.path, transformers, artifacts, logging
+
+_logger = logging.getLogger(__name__)
+
+# Revision control systems that we should ignore
+_revisionControl = ('.svn', 'CVS')
+
+# Items to skip in project-level target/site directories
+_mavenBlacklist = ('apidocs', 'css', 'xref', 'xref-test')
+
+class _Publisher(object):
+    '''Abstract publisher.'''
+    def __init__(self, xform):
+        '''All publishers need a transformer or ``xform``.'''
+        self.xform = xform
+    def publish(self, contentDir, targetDir, baseURL):
+        '''Publish the content of ``contentDir`` to ``targetDir``, changing URL references as
+        needed to reference resources from the ``baseURL``.'''
+        self.checkDirs(contentDir, targetDir)
+        generatedArtifacts = self.generateArtifacts(contentDir, targetDir, baseURL)
+        for artifact in generatedArtifacts:
+            artifact.transform(self.xform)
+            artifact.adjustReferences(baseURL)
+            artifact.write(targetDir)
+        # TODO: svn-remove any extra artifacts in the targetDir?
+    def checkDirs(self, contentDir, targetDir):
+        '''Check if the ``contentDir`` and ``targetDir`` exist.  If ``contentDir`` doesn't exist, that's bad,
+        and we throw a ``PublicationDirNotFound`` exception.  If the ``targetDir`` doesn't exist, that's OK,
+        we just create it.'''
+        if not os.path.isdir(contentDir):
+            raise PublicationDirNotFound(contentDir)
+        if not os.path.isdir(targetDir):
+            _logger.info("Creating directory %s", targetDir)
+            os.makedirs(targetDir)
+    def generateArtifacts(self, contentDir, targetDir, baseURL):
+        '''Generate artifacts found in ``contentDir`` to be placed in ``targetDir`` and possibly
+        modified by ``baseURL``.  This method must return a sequence of ``Artifact`` objects.'''
+        raise NotImplementedError('Subclasses must implement the "generateArtifacts" method')
+
+class HomePublisher(_Publisher):
+    '''Where it all begins: Apache OODT's home page'''
+    def __init__(self):
+        super(HomePublisher, self).__init__(transformers.getTransformer('home'))
+    def generateArtifacts(self, contentDir, targetDir, baseURL):
+        # Handle child directories
+        for fn in os.listdir(contentDir):
+            if fn in _revisionControl: continue
+            path = os.path.join(contentDir, fn)
+            if os.path.isdir(path):
+                dst = os.path.join(targetDir, fn)
+                subdirPub = PagePublisher()
+                subdirPub.publish(path, dst, baseURL)
+        # Handle the home page
+        indexPath = os.path.join(contentDir, 'index.html')
+        if not os.path.isfile(indexPath):
+            raise PublicationFileNotFound(indexPath)
+        # TODO: handle graphics on the home page; so far, we don't have any.
+        a = artifacts.constructArtifact(indexPath);
+        assert a is not None
+        return [a]
+            
+class PagePublisher(_Publisher):
+    '''A publisher that handles HTML files, images, and other web assets and also recursively
+    handles subdirectories.'''
+    def __init__(self):
+        super(PagePublisher, self).__init__(transformers.getTransformer('standard'))
+    def generateArtifacts(self, contentDir, targetDir, baseURL):
+        generatedArtifacts = []
+        # TODO: warn if no index.html?
+        for fn in os.listdir(contentDir):
+            if fn in _revisionControl: continue
+            path = os.path.join(contentDir, fn)
+            if os.path.isdir(path):
+                dst = os.path.join(targetDir, fn)
+                subdirPub = PagePublisher()
+                subdirPub.publish(path, dst, baseURL)
+            elif os.path.isfile(path):
+                a = artifacts.constructArtifact(path)
+                assert a is not None, 'Unknown artifact "%s"' % path
+                generatedArtifacts.append(a)
+            else:
+                _logger.warn('PagePublisher ignoring unknown filesystem entry "%s"', path)
+        return generatedArtifacts
+
+class MavenPublisher(_Publisher):
+    '''A publisher that handles a ``site`` content directory generated by Maven.'''
+    def __init__(self):
+        super(MavenPublisher, self).__init__(transformers.getTransformer('maven'))
+    def generateArtifacts(self, contentDir, targetDir, baseURL):
+        '''The ``contentDir`` should point to the "target/site" directory generated by Maven.'''
+        generatedArtifacts = []
+        for fn in os.listdir(contentDir):
+            if fn in _revisionControl:
+                raise UnexpectedFilesystemEntryError(
+                    'Maven-generated artifacts should NOT be checked into revision control; found "%s" in "%s"' % (fn, contentDir)
+                )
+            path = os.path.join(contentDir, fn)
+            if os.path.isdir(path):
+                # Skip art
+                if fn in _mavenBlacklist:
+                    _logger.debug("MavenPublisher: For %s I am skipping %s", contentDir, fn)
+                    continue
+                dst = os.path.join(targetDir, fn)
+                subdirPub = MavenPublisher()
+                subdirPub.publish(path, dst, baseURL)
+            elif os.path.isfile(path):
+                artifact = artifacts.constructArtifact(path)
+                if artifact is None:
+                    _logger.warn('No idea how to handle Maven-generated artifact at "%s"; I will ignore it', path)
+                else:
+                    generatedArtifacts.append(artifact)
+            else:
+                _logger.info('Skipping non-file and non-directory "%s"', path)
+        return generatedArtifacts
+
+class JavaDocsPublisher(_Publisher):
+    '''A publisher that handles API documentation as well as source cross-references.'''
+    def __init__(self):
+        super(JavaDocsPublisher, self).__init__(transformers.getTransformer('null'))
+    def generateArtifacts(self, contentDir, targetDir, baseURL):
+        generatedArtifacts = []
+        for fn in os.listdir(contentDir):
+            path = os.path.join(contentDir, fn)
+            if os.path.isdir(path):
+                dst = os.path.join(targetDir, fn)
+                subdirPub = JavaDocsPublisher()
+                subdirPub.publish(path, dst, baseURL)
+            elif os.path.isfile(path):
+                generatedArtifacts.append(artifacts.constructArtifact(path))
+        return generatedArtifacts

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/globalnav.xml
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/globalnav.xml?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/globalnav.xml (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/globalnav.xml Tue Jul 27 23:03:44 2010
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements.  See the NOTICE.txt file distributed with this work for
+additional information regarding copyright ownership.  The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License.  You may obtain a copy of
+the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+License for the specific language governing permissions and limitations under
+the License.
+
+XDV rules that highlight a globalnav tab based on the first DC.subject keyword, if any.
+-->
+<xdv:rules
+    xmlns:xdv='http://namespaces.plone.org/xdv'
+    xmlns:css='http://namespaces.plone.org/xdv+css'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+    <xdv:prepend css:theme='#tab-contact' if-content='string(/html/head/meta[@name="DC.subject"]/@content)="contact"'>
+        <xsl:attribute name='class'>currentNavTab</xsl:attribute>
+    </xdv:prepend>
+    <xdv:prepend css:theme='#tab-development' if-content='string(/html/head/meta[@name="DC.subject"]/@content)="development"'>
+        <xsl:attribute name='class'>currentNavTab</xsl:attribute>
+    </xdv:prepend>
+    <xdv:prepend css:theme='#tab-components' if-content='string(/html/head/meta[@name="DC.subject"]/@content)="components"'>
+        <xsl:attribute name='class'>currentNavTab</xsl:attribute>
+    </xdv:prepend>
+    <xdv:prepend css:theme='#tab-about' if-content='string(/html/head/meta[@name="DC.subject"]/@content)="about"'>
+        <xsl:attribute name='class'>currentNavTab</xsl:attribute>
+    </xdv:prepend>
+    <xdv:prepend css:theme='#tab-home' if-content='string(/html/head/meta[@name="DC.subject"]/@content)="home"'>
+        <xsl:attribute name='class'>currentNavTab</xsl:attribute>
+    </xdv:prepend>
+</xdv:rules>

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/head.xml
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/head.xml?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/head.xml (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/head.xml Tue Jul 27 23:03:44 2010
@@ -0,0 +1,33 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements.  See the NOTICE.txt file distributed with this work for
+additional information regarding copyright ownership.  The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License.  You may obtain a copy of
+the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+License for the specific language governing permissions and limitations under
+the License.
+
+XDV rules to handle the <head> of HTML.
+-->
+<xdv:rules
+    xmlns:xdv='http://namespaces.plone.org/xdv'
+    xmlns:css='http://namespaces.plone.org/xdv+css'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+    <!-- Insert all link tags (FIXME: any we want to filter?) -->
+    <xdv:append theme='/html/head' content='/html/head/link' />
+
+    <!-- Insert certain meta tags -->
+    <xdv:drop content='/html/head/meta[@http-equiv="Content-Type"]' />
+    <xdv:append theme='/html/head' content='/html/head/meta' />
+    <xdv:drop theme='/html/head/meta[@http-equiv="Content-Type"]' />
+
+</xdv:rules>

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/home.xml
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/home.xml?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/home.xml (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/home.xml Tue Jul 27 23:03:44 2010
@@ -0,0 +1,49 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements.  See the NOTICE.txt file distributed with this work for
+additional information regarding copyright ownership.  The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License.  You may obtain a copy of
+the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+License for the specific language governing permissions and limitations under
+the License.
+
+Special HTML page transformation for the home page only of the Apache OODT website.
+-->
+<xdv:rules
+    xmlns:xdv='http://namespaces.plone.org/xdv'
+    xmlns:css='http://namespaces.plone.org/xdv+css'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+    xmlns:xi='http://www.w3.org/2001/XInclude'>
+
+    <xi:include href='head.xml' />
+
+    <!-- Make the 'Home' globalnav tab the current -->
+    <xdv:prepend css:theme='#tab-home'><xsl:attribute name='class'>currentNavTab</xsl:attribute></xdv:prepend>
+
+    <!-- Add the large Apache OODT banner image here (it appears only on the home page) -->
+    <xdv:after css:theme='.visualHeaderWrapper'>
+        <div class='productBanner'>
+            <a href='/'>
+                <img
+                    src='/images/oodtBanner.jpg'
+                    alt='Apache OODT is Cataloging, Archiving, Metadata, and Grid Services for Science'
+                />
+            </a>
+        </div>
+    </xdv:after>
+
+    <!-- The large Apache OODT banner replaces the regular product/component/section wrapper -->
+    <xdv:drop css:theme='.subProductWrapper'/>
+
+    <!-- Everything from the body goes into the #content div -->
+    <xdv:copy css:theme='#content' content='/html/body/*'/>
+
+</xdv:rules>

Added: incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/maven.xml
URL: http://svn.apache.org/viewvc/incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/maven.xml?rev=979904&view=auto
==============================================================================
--- incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/maven.xml (added)
+++ incubator/oodt/tools/oodtsite.publisher/trunk/oodtsite/publisher/rules/maven.xml Tue Jul 27 23:03:44 2010
@@ -0,0 +1,46 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements.  See the NOTICE.txt file distributed with this work for
+additional information regarding copyright ownership.  The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License.  You may obtain a copy of
+the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+License for the specific language governing permissions and limitations under
+the License.
+
+Rules to transform a Maven-generated project site into an OODT component site.
+-->
+<xdv:rules
+    xmlns:xdv='http://namespaces.plone.org/xdv'
+    xmlns:css='http://namespaces.plone.org/xdv+css'
+    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
+    xmlns:xi='http://www.w3.org/2001/XInclude'>
+
+    <xi:include href='head.xml' />
+
+    <!-- Make the 'Components' globalnav tab the current one -->
+    <xdv:prepend css:theme='#tab-components'><xsl:attribute name='class'>currentNavTab</xsl:attribute></xdv:prepend>
+
+    <!-- Sub-page product banner: bannerLeft text in the product name, first h2 as subheading -->
+    <xdv:copy css:theme='#productNameSlot' css:content='#bannerLeft'/>
+    <xdv:copy css:theme='#productSubheadSlot' content='//div[@id="contentBox"]/div/h2'/>
+
+    <xdv:copy css:theme='#rightPlate' css:content='#navcolumn'/>
+    <xdv:drop css:content='.poweredBy'/>
+    <xdv:copy css:theme='#leftPlate' content='//div[@id="contentBox"]/div[1]/*[position()&gt;1]'/>
+    <xdv:append css:theme='#leftPlate' content='//div[@id="contentBox"]/*[position()&gt;1]'/>
+
+    <!-- FIXME: -->
+    <!-- Bleh.  The FindBugs report is fairly invalid HTML. (Bogus </p></div> coming outta left field) -->
+    <!-- jira-report and source-repository all stick text outside of a <p>...</p> (or div) container -->
+    <!-- team-list needs serious cleanup (table too wide) -->
+    <!-- Consider custom Publisher classes for those (along with custom rules xml) -->
+
+</xdv:rules>