diff --git a/livesupport/products/scheduler/bin/autogen.sh b/livesupport/products/scheduler/bin/autogen.sh
new file mode 100755
index 000000000..88b0f43a7
--- /dev/null
+++ b/livesupport/products/scheduler/bin/autogen.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+#-------------------------------------------------------------------------------
+# Copyright (c) 2004 Media Development Loan Fund
+#
+# This file is part of the LiveSupport project.
+# http://livesupport.campware.org/
+# To report bugs, send an e-mail to bugs@campware.org
+#
+# LiveSupport is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LiveSupport is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LiveSupport; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# Author : $Author: maroy $
+# Version : $Revision: 1.1 $
+# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/bin/autogen.sh,v $
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Run this to set up the build system: configure, makefiles, etc.
+# (based on the version in enlightenment's cvs)
+#-------------------------------------------------------------------------------
+
+package="Scheduler"
+
+# assume we're in $basedir/bin
+basedir=`dirname $0`/..
+test -z "$basedir" && basedir=.
+
+tmpdir=$basedir/tmp
+
+cd "$tmpdir"
+DIE=0
+
+# look at all other directories as seen from ${basedir}/tmp
+tmpdir=.
+bindir=../bin
+etcdir=../etc
+
+(autoheader --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $package."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "You must have autoconf installed to compile $package."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "I am going to run ./configure with no arguments - if you wish "
+ echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+echo "Generating configuration files for $package, please wait...."
+
+configure_ac=${etcdir}/configure.ac
+configure=${tmpdir}/configure
+
+#echo " aclocal $ACLOCAL_FLAGS"
+#aclocal $ACLOCAL_FLAGS
+echo " autoheader ${configure_ac}"
+autoheader ${configure_ac}
+echo " autoconf -o ${configure} ${configure_ac}"
+autoconf -o ${configure} ${configure_ac}
+
+${configure} "$@" && echo
diff --git a/livesupport/products/scheduler/doc/doxygen/.keepme b/livesupport/products/scheduler/doc/doxygen/.keepme
new file mode 100644
index 000000000..e0808fa16
--- /dev/null
+++ b/livesupport/products/scheduler/doc/doxygen/.keepme
@@ -0,0 +1 @@
+keep me
diff --git a/livesupport/products/scheduler/etc/Makefile.in b/livesupport/products/scheduler/etc/Makefile.in
new file mode 100644
index 000000000..60d0877aa
--- /dev/null
+++ b/livesupport/products/scheduler/etc/Makefile.in
@@ -0,0 +1,185 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2004 Media Development Loan Fund
+#
+# This file is part of the LiveSupport project.
+# http://livesupport.campware.org/
+# To report bugs, send an e-mail to bugs@campware.org
+#
+# LiveSupport is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LiveSupport is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LiveSupport; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# Author : $Author: maroy $
+# Version : $Revision: 1.1 $
+# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/Makefile.in,v $
+#
+# @configure_input@
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# General command definitions
+#-------------------------------------------------------------------------------
+MKDIR = mkdir -p
+RM = rm -f
+RMDIR = rm -rf
+DOXYGEN = doxygen
+
+
+#-------------------------------------------------------------------------------
+# Basic directory and file definitions
+#-------------------------------------------------------------------------------
+BASE_DIR = @builddir@
+DOC_DIR = ${BASE_DIR}/doc
+DOXYGEN_DIR = ${DOC_DIR}/doxygen
+ETC_DIR = ${BASE_DIR}/etc
+SRC_DIR = ${BASE_DIR}/src
+TMP_DIR = ${BASE_DIR}/tmp
+
+USR_DIR = ${BASE_DIR}/../../usr
+USR_INCLUDE_DIR = ${USR_DIR}/include
+USR_LIB_DIR = ${USR_DIR}/lib
+BOOST_INCLUDE_DIR = ${USR_INCLUDE_DIR}/boost-1_31
+LIBXMLPP_INCLUDE_DIR = ${USR_INCLUDE_DIR}/libxml++-1.0
+
+VPATH = ${SRC_DIR}
+
+MODULES_DIR = ${BASE_DIR}/../../modules
+
+CORE_DIR = ${MODULES_DIR}/core
+CORE_INCLUDE_DIR = ${CORE_DIR}/include
+CORE_LIB_DIR = ${CORE_DIR}/lib
+CORE_LIB = livesupport_core
+CORE_LIB_FILE = ${CORE_LIB_DIR}/lib${CORE_LIB}.a
+
+DB_DIR = ${MODULES_DIR}/db
+DB_INCLUDE_DIR = ${DB_DIR}/include
+DB_LIB_DIR = ${DB_DIR}/lib
+DB_LIB = livesupport_db
+DB_LIB_FILE = ${DB_LIB_DIR}/lib${DB_LIB}.a
+
+STORAGE_DIR = ${MODULES_DIR}/storage
+STORAGE_INCLUDE_DIR = ${STORAGE_DIR}/include
+STORAGE_LIB_DIR = ${STORAGE_DIR}/lib
+STORAGE_LIB = livesupport_storage
+STORAGE_LIB_FILE = ${STORAGE_LIB_DIR}/lib${STORAGE_LIB}.a
+
+SCHEDULER_EXE = ${TMP_DIR}/scheduler
+TEST_RUNNER = ${TMP_DIR}/testRunner
+
+DOXYGEN_CONFIG = ${ETC_DIR}/doxygen.config
+
+
+#-------------------------------------------------------------------------------
+# Configuration parameters
+#-------------------------------------------------------------------------------
+CPPFLAGS = @CPPFLAGS@
+CXXFLAGS = @CXXFLAGS@ @DEFS@ -pedantic -Wall -Wno-long-long \
+ -I${USR_INCLUDE_DIR} \
+ -I${BOOST_INCLUDE_DIR} \
+ -I${LIBXMLPP_INCLUDE_DIR} \
+ -I${CORE_INCLUDE_DIR} \
+ -I${DB_INCLUDE_DIR} \
+ -I${STORAGE_INCLUDE_DIR} \
+ -I${TMP_DIR}
+LDFLAGS = @LDFLAGS@ -L${USR_LIB_DIR} \
+ -L${CORE_LIB_DIR} \
+ -L${DB_LIB_DIR} \
+ -L${STORAGE_LIB_DIR}
+
+
+#-------------------------------------------------------------------------------
+# Dependencies
+#-------------------------------------------------------------------------------
+SCHEDULER_OBJS = ${TMP_DIR}/SignalDispatcher.o \
+ ${TMP_DIR}/XmlRpcDaemon.o \
+ ${TMP_DIR}/SchedulerDaemon.o \
+ ${TMP_DIR}/UploadPlaylistMethod.o \
+ ${TMP_DIR}/ScheduleFactory.o \
+ ${TMP_DIR}/PostgresqlSchedule.o
+
+SCHEDULER_EXE_OBJS = ${SCHEDULER_OBJS} \
+ ${TMP_DIR}/main.o
+SCHEDULER_EXE_LIBS = -l${STORAGE_LIB} -l${DB_LIB} -l${CORE_LIB} \
+ -lodbc++ -lboost_date_time-gcc \
+ -lxmlrpc++ -lssl -lxml++-1.0
+
+TEST_RUNNER_OBJS = ${SCHEDULER_OBJS} \
+ ${TMP_DIR}/SchedulerDaemonTest.o \
+ ${TMP_DIR}/UploadPlaylistMethodTest.o \
+ ${TMP_DIR}/PostgresqlScheduleTest.o \
+ ${TMP_DIR}/TestRunner.o
+TEST_RUNNER_LIBS = ${SCHEDULER_EXE_LIBS} -lcppunit -ldl
+
+
+#-------------------------------------------------------------------------------
+# Targets
+#-------------------------------------------------------------------------------
+.PHONY: all dir_setup doc clean docclean depclean distclean
+
+all: dir_setup ${SCHEDULER_EXE}
+
+dir_setup: ${TMP_DIR} ${DOXYGEN_DIR}
+
+doc:
+ ${DOXYGEN} ${DOXYGEN_CONFIG}
+
+clean:
+ ${RM} ${SCHEDULER_EXE_OBJS} ${SCHEDULER_EXE}
+ ${RM} ${TEST_RUNNER_OBJS} ${TEST_RUNNER}
+
+docclean:
+ ${RMDIR} ${DOXYGEN_DIR}/html
+
+depclean: clean
+
+distclean: clean docclean
+ ${RMDIR} ${TMP_DIR}/config* ${TMP_DIR}/autom4te*
+
+check: all ${TEST_RUNNER}
+ LD_LIBRARY_PATH=${USR_LIB_DIR} ${TEST_RUNNER}
+
+
+#-------------------------------------------------------------------------------
+# Specific targets
+#-------------------------------------------------------------------------------
+${SCHEDULER_EXE}: ${CORE_LIB_FILE} ${DB_LIB_FILE} ${STORAGE_LIB_FILE} \
+ ${SCHEDULER_EXE_OBJS}
+ ${CXX} ${LDFLAGS} -o $@ $^ ${SCHEDULER_EXE_LIBS}
+
+${TMP_DIR}:
+ ${MKDIR} ${TMP_DIR}
+
+${DOXYGEN_DIR}:
+ ${MKDIR} ${DOXYGEN_DIR}
+
+${TEST_RUNNER}: ${CORE_LIB_FILE} ${DB_LIB_FILE} ${STORAGE_LIB_FILE} \
+ ${TEST_RUNNER_OBJS}
+ ${CXX} ${LDFLAGS} -o $@ ${TEST_RUNNER_OBJS} ${TEST_RUNNER_LIBS}
+
+${CORE_LIB_FILE}:
+ ${MAKE} -C ${CORE_DIR}
+
+${DB_LIB_FILE}:
+ ${MAKE} -C ${DB_DIR}
+
+${STORAGE_LIB_FILE}:
+ ${MAKE} -C ${STORAGE_DIR}
+
+
+#-------------------------------------------------------------------------------
+# Pattern rules
+#-------------------------------------------------------------------------------
+${TMP_DIR}/%.o : ${SRC_DIR}/%.cxx
+ ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c -o $@ $<
+
diff --git a/livesupport/products/scheduler/etc/configure.ac b/livesupport/products/scheduler/etc/configure.ac
new file mode 100644
index 000000000..747ecef7a
--- /dev/null
+++ b/livesupport/products/scheduler/etc/configure.ac
@@ -0,0 +1,49 @@
+dnl-----------------------------------------------------------------------------
+dnl Copyright (c) 2004 Media Development Loan Fund
+dnl
+dnl This file is part of the LiveSupport project.
+dnl http://livesupport.campware.org/
+dnl To report bugs, send an e-mail to bugs@campware.org
+dnl
+dnl LiveSupport is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl LiveSupport is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with LiveSupport; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+dnl
+dnl
+dnl Author : $Author: maroy $
+dnl Version : $Revision: 1.1 $
+dnl Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/configure.ac,v $
+dnl-----------------------------------------------------------------------------
+
+dnl-----------------------------------------------------------------------------
+dnl NOTE: Run all configure related scripts from the tmp directory of the
+dnl project.
+dnl This is due to the fact that configure spreads a lot of trash around,
+dnl like atom4te cache directories, config.* files, etc. into the directory
+dnl it is being run from. We clearly don't want these in our base directory.
+dnl-----------------------------------------------------------------------------
+AC_INIT(Scheduler, 0.1, bugs@campware.org)
+AC_PREREQ(2.59)
+AC_COPYRIGHT([Copyright (c) 2004 Media Development Loan Fund under the GNU GPL])
+AC_REVISION($Revision: 1.1 $)
+
+AC_CONFIG_SRCDIR(../src/main.cxx)
+
+AC_CONFIG_HEADERS(configure.h)
+AC_PROG_CXX()
+
+AC_CHECK_HEADERS(sys/types.h unistd.h getopt.h signal.h sys/stat.h time.h)
+
+AC_CONFIG_FILES(../Makefile:../etc/Makefile.in)
+
+AC_OUTPUT()
diff --git a/livesupport/products/scheduler/etc/connectionManagerFactory.xml b/livesupport/products/scheduler/etc/connectionManagerFactory.xml
new file mode 100644
index 000000000..0eb143638
--- /dev/null
+++ b/livesupport/products/scheduler/etc/connectionManagerFactory.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+]>
+
+
+
diff --git a/livesupport/products/scheduler/etc/doxygen.config b/livesupport/products/scheduler/etc/doxygen.config
new file mode 100644
index 000000000..9b0c37ea4
--- /dev/null
+++ b/livesupport/products/scheduler/etc/doxygen.config
@@ -0,0 +1,1144 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2004 Media Development Loan Fund
+#
+# This file is part of the LiveSupport project.
+# http://livesupport.campware.org/
+# To report bugs, send an e-mail to bugs@campware.org
+#
+# LiveSupport is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# LiveSupport is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with LiveSupport; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+#
+# Author : $Author: maroy $
+# Version : $Revision: 1.1 $
+# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/doxygen.config,v $
+#-------------------------------------------------------------------------------
+
+# Doxyfile 1.3.6
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = LiveSupport
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.0
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc/doxygen
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = YES
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = src
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command , where
+# is the value of the INPUT_FILTER tag, and is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/livesupport/products/scheduler/etc/scheduleFactory.xml b/livesupport/products/scheduler/etc/scheduleFactory.xml
new file mode 100644
index 000000000..a89f05373
--- /dev/null
+++ b/livesupport/products/scheduler/etc/scheduleFactory.xml
@@ -0,0 +1,10 @@
+
+
+
+
+]>
+
+
+
diff --git a/livesupport/products/scheduler/etc/scheduler.xml b/livesupport/products/scheduler/etc/scheduler.xml
new file mode 100644
index 000000000..54bc5f931
--- /dev/null
+++ b/livesupport/products/scheduler/etc/scheduler.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+]>
+
+
+
diff --git a/livesupport/products/scheduler/etc/storageClient.xml b/livesupport/products/scheduler/etc/storageClient.xml
new file mode 100644
index 000000000..15600dfed
--- /dev/null
+++ b/livesupport/products/scheduler/etc/storageClient.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
diff --git a/livesupport/products/scheduler/src/PostgresqlSchedule.cxx b/livesupport/products/scheduler/src/PostgresqlSchedule.cxx
new file mode 100644
index 000000000..ac2d79820
--- /dev/null
+++ b/livesupport/products/scheduler/src/PostgresqlSchedule.cxx
@@ -0,0 +1,251 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlSchedule.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+#include
+#include
+
+#include "LiveSupport/Db/Conversion.h"
+#include "PostgresqlSchedule.h"
+
+using namespace odbc;
+
+using namespace LiveSupport::Core;
+using namespace LiveSupport::Db;
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/*------------------------------------------------------------------------------
+ * The name of the config element for this class
+ *----------------------------------------------------------------------------*/
+const std::string PostgresqlSchedule::configElementNameStr =
+ "postgresqlSchedule";
+
+/*------------------------------------------------------------------------------
+ * The SQL create statement, used for installation.
+ *----------------------------------------------------------------------------*/
+const std::string PostgresqlSchedule::createStmt =
+ "CREATE TABLE schedule\n"
+ "(\n"
+ " id INT NOT NULL,\n"
+ " playlist INT NOT NULL,\n"
+ " starts TIMESTAMP NOT NULL,\n"
+ " ends TIMESTAMP NOT NULL,\n"
+ "\n"
+ " PRIMARY KEY(id)\n"
+ ");";
+
+/*------------------------------------------------------------------------------
+ * The SQL create statement, used for installation.
+ *----------------------------------------------------------------------------*/
+const std::string PostgresqlSchedule::dropStmt =
+ "DROP TABLE schedule;";
+
+/*------------------------------------------------------------------------------
+ * The SQL statement for querying if a timeframe is available.
+ * The parameters for this call are: starts, starts, ends, ends, starts, ends,
+ * and returns the number of items falling into the quieried timeframe.
+ * Basically checks if the starts or ends value falls within the queried frame
+ * or starts before and ends after the queried timeframe.
+ *----------------------------------------------------------------------------*/
+const std::string PostgresqlSchedule::isTimeframaAvailableStmt =
+ "SELECT COUNT(*) FROM schedule WHERE "
+ "((starts <= ? AND ? < ends) OR (starts < ? AND ? <= ends)) "
+ "OR (? <= starts AND ends <= ?)";
+
+/*------------------------------------------------------------------------------
+ * The SQL statement for scheduling a playlist.
+ * It's a simple insert.
+ *----------------------------------------------------------------------------*/
+const std::string PostgresqlSchedule::schedulePlaylistStmt =
+ "INSERT INTO schedule(id, playlist, starts, ends) VALUES(?, ?, ?, ?)";
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Configure the schedule.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlSchedule :: configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error)
+{
+ if (element.get_name() != configElementNameStr) {
+ std::string eMsg = "Bad configuration element ";
+ eMsg += element.get_name();
+ throw std::invalid_argument(eMsg);
+ }
+
+ // nothing to do here, really
+}
+
+
+/*------------------------------------------------------------------------------
+ * Install the PostgresqlSchedule.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlSchedule :: install(void) throw (std::exception)
+{
+ Ptr::Ref conn;
+ try {
+ conn = cm->getConnection();
+ Ptr::Ref stmt(conn->createStatement());
+ stmt->execute(createStmt);
+ cm->returnConnection(conn);
+ } catch (std::exception &e) {
+ if (conn) {
+ cm->returnConnection(conn);
+ }
+ throw;
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Uninstall the PostgresqlSchedule.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlSchedule :: uninstall(void) throw (std::exception)
+{
+ Ptr::Ref conn;
+ try {
+ conn = cm->getConnection();
+ Ptr::Ref stmt(conn->createStatement());
+ stmt->execute(dropStmt);
+ cm->returnConnection(conn);
+ } catch (std::exception &e) {
+ if (conn) {
+ cm->returnConnection(conn);
+ }
+ throw;
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Check if a timeframe is available.
+ *----------------------------------------------------------------------------*/
+bool
+PostgresqlSchedule :: isTimeframeAvailable(
+ Ptr::Ref from,
+ Ptr::Ref to) throw ()
+{
+ Ptr::Ref conn;
+ bool result = false;
+
+ try {
+ conn = cm->getConnection();
+ Ptr::Ref timestamp;
+ Ptr::Ref pstmt(conn->prepareStatement(
+ isTimeframaAvailableStmt));
+ timestamp = Conversion::ptimeToTimestamp(from);
+ pstmt->setTimestamp(1, *timestamp);
+ pstmt->setTimestamp(2, *timestamp);
+ pstmt->setTimestamp(5, *timestamp);
+
+ timestamp = Conversion::ptimeToTimestamp(to);
+ pstmt->setTimestamp(3, *timestamp);
+ pstmt->setTimestamp(4, *timestamp);
+ pstmt->setTimestamp(6, *timestamp);
+
+ Ptr::Ref rs(pstmt->executeQuery());
+ result = (rs->next()) ? (rs->getInt(1) == 0) : false;
+
+ cm->returnConnection(conn);
+ } catch (std::exception &e) {
+ if (conn) {
+ cm->returnConnection(conn);
+ }
+ return false;
+ }
+
+ return result;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Schedule a playlist
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlSchedule :: schedulePlaylist(
+ Ptr::Ref playlist,
+ Ptr::Ref playtime)
+ throw (std::invalid_argument)
+{
+ Ptr::Ref conn;
+ bool result = false;
+
+ try {
+ conn = cm->getConnection();
+ Ptr::Ref timestamp;
+ Ptr::Ref id;
+ Ptr::Ref ends;
+ Ptr::Ref pstmt(conn->prepareStatement(
+ schedulePlaylistStmt));
+ id = UniqueId::generateId();
+ pstmt->setInt(1, id->getId());
+
+ pstmt->setInt(2, playlist->getId()->getId());
+
+ timestamp = Conversion::ptimeToTimestamp(playtime);
+ pstmt->setTimestamp(3, *timestamp);
+
+ ends.reset(new ptime((*playtime) + *(playlist->getPlaylength())));
+ timestamp = Conversion::ptimeToTimestamp(ends);
+ pstmt->setTimestamp(4, *timestamp);
+
+ result = pstmt->executeUpdate() == 1;
+
+ cm->returnConnection(conn);
+ } catch (std::exception &e) {
+ if (conn) {
+ cm->returnConnection(conn);
+ }
+ throw std::invalid_argument(e.what());
+ }
+
+ if (!result) {
+ throw std::invalid_argument("couldn't insert into database");
+ }
+}
+
diff --git a/livesupport/products/scheduler/src/PostgresqlSchedule.h b/livesupport/products/scheduler/src/PostgresqlSchedule.h
new file mode 100644
index 000000000..3a11260f3
--- /dev/null
+++ b/livesupport/products/scheduler/src/PostgresqlSchedule.h
@@ -0,0 +1,221 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlSchedule.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef PostresqlSchedule_h
+#define PostresqlSchedule_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+#include
+
+#include "LiveSupport/Core/Ptr.h"
+#include "LiveSupport/Core/Configurable.h"
+#include "LiveSupport/Db/ConnectionManagerInterface.h"
+#include "ScheduleInterface.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * An object containing the schedule of events in a PostreSQL database.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class PostgresqlSchedule : public Configurable,
+ public ScheduleInterface
+{
+ private:
+ /**
+ * The name of the configuration XML elmenent used by this object.
+ */
+ static const std::string configElementNameStr;
+
+ /**
+ * The SQL create statement used in the installation step.
+ */
+ static const std::string createStmt;
+
+ /**
+ * The SQL drop statement used in the uninstallation step.
+ */
+ static const std::string dropStmt;
+
+ /**
+ * The SQL statement for querying if a time frame is available.
+ */
+ static const std::string isTimeframaAvailableStmt;
+
+ /**
+ * The SQL statement for scheduling a playlist.
+ */
+ static const std::string schedulePlaylistStmt;
+
+ /**
+ * The database connection manager to use for connecting the
+ * database.
+ */
+ Ptr::Ref cm;
+
+ /**
+ * The default constructor.
+ */
+ PostgresqlSchedule(void) throw()
+ {
+ }
+
+
+ public:
+ /**
+ * Construct a PostgresqlSchedule.
+ *
+ * @param cm the connection manager the PostgresqlSchedule will use to
+ * connect to the database.
+ */
+ PostgresqlSchedule(Ptr::Ref cm)
+ throw ()
+ {
+ this->cm = cm;
+ }
+
+ /**
+ * A virtual destructor, as this class has virtual functions.
+ */
+ virtual
+ ~PostgresqlSchedule(void) throw ()
+ {
+ }
+
+ /**
+ * Return the name of the XML element this object expects
+ * to be sent to a call to configure().
+ *
+ * @return the name of the expected XML configuration element.
+ */
+ static const std::string
+ getConfigElementName(void) throw ()
+ {
+ return configElementNameStr;
+ }
+
+ /**
+ * Configure the object based on the XML element supplied.
+ * The supplied element is expected to be of the name
+ * returned by configElementName().
+ *
+ * @param element the XML element to configure the object from.
+ * @exception std::invalid_argument if the supplied XML element
+ * contains bad configuraiton information
+ * @exception std::logic_error if the object has already
+ * been configured, and can not be reconfigured.
+ */
+ virtual void
+ configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error);
+
+ /**
+ * Install the component.
+ * This step involves creating the environment in which the component
+ * will run. This may be creation of coniguration files,
+ * database tables, etc.
+ *
+ * @exception std::exception on installation problems.
+ */
+ virtual void
+ install(void) throw (std::exception);
+
+ /**
+ * Uninstall the component.
+ * Removes all the resources created in the install step.
+ *
+ * @exception std::exception on unistallation problems.
+ */
+ virtual void
+ uninstall(void) throw (std::exception);
+
+ /**
+ * Check if a timeframe is available for scheduling.
+ *
+ * @param from the start time of the timeframe.
+ * @param to the end time of the timeframe.
+ * @return true if the timeframe is available, false otherwise.
+ */
+ virtual bool
+ isTimeframeAvailable(Ptr::Ref from,
+ Ptr::Ref to) throw ();
+
+ /**
+ * Schedule a playlist.
+ *
+ * @param playlist the playlist to schedule.
+ * @param playtime the time to schedule the playlist for.
+ * @exception std::invalid_argument if the there is something
+ * already scheduled for the duration of the playlist.
+ */
+ virtual void
+ schedulePlaylist(Ptr::Ref playlist,
+ Ptr::Ref playtime)
+ throw (std::invalid_argument);
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // PostresqlSchedule_h
+
diff --git a/livesupport/products/scheduler/src/PostgresqlScheduleTest.cxx b/livesupport/products/scheduler/src/PostgresqlScheduleTest.cxx
new file mode 100644
index 000000000..6b0baafaa
--- /dev/null
+++ b/livesupport/products/scheduler/src/PostgresqlScheduleTest.cxx
@@ -0,0 +1,228 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlScheduleTest.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+
+#include
+#include
+
+#include "LiveSupport/Db/ConnectionManagerFactory.h"
+#include "PostgresqlSchedule.h"
+#include "PostgresqlScheduleTest.h"
+
+
+using namespace boost::posix_time;
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+CPPUNIT_TEST_SUITE_REGISTRATION(PostgresqlScheduleTest);
+
+/**
+ * The name of the configuration file for the connection manager factory.
+ */
+static const std::string configFileName = "etc/connectionManagerFactory.xml";
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Set up the test environment
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlScheduleTest :: setUp(void) throw ()
+{
+ try {
+ Ptr::Ref parser(
+ new xmlpp::DomParser(configFileName, true));
+ const xmlpp::Document * document = parser->get_document();
+ const xmlpp::Element * root = document->get_root_node();
+
+ Ptr::Ref cmf =
+ ConnectionManagerFactory::getInstance();
+ cmf->configure(*root);
+ cm = cmf->getConnectionManager();
+
+ schedule.reset(new PostgresqlSchedule(cm));
+ schedule->install();
+
+ } catch (std::invalid_argument &e) {
+ CPPUNIT_FAIL("semantic error in configuration file");
+ } catch (xmlpp::exception &e) {
+ CPPUNIT_FAIL("error parsing configuration file");
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Clean up the test environment
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlScheduleTest :: tearDown(void) throw ()
+{
+ schedule->uninstall();
+ schedule.reset();
+ cm.reset();
+}
+
+
+/*------------------------------------------------------------------------------
+ * Test for an available timeframe in an empty schedule database.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlScheduleTest :: firstTest(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ // check with any two arbitary dates, the timeframe should be available
+ Ptr::Ref from(new ptime(time_from_string("2004-07-23 10:00:00")));
+ Ptr::Ref to(new ptime(time_from_string("2004-07-23 11:00:00")));
+
+ CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
+}
+
+
+/*------------------------------------------------------------------------------
+ * Schedule a single playlist.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlScheduleTest :: simpleScheduleTest(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ // create a 1 hour long playlist, from 10 o'clock 2004-07-23
+ Ptr::Ref id = UniqueId::generateId();
+ Ptr::Ref playlength(new time_duration(1, 0, 0));
+ Ptr::Ref playlist(new Playlist(id, playlength));
+ Ptr::Ref from(new ptime(time_from_string(
+ "2004-07-23 10:00:00")));
+
+ try {
+ schedule->schedulePlaylist(playlist, from);
+ } catch (std::invalid_argument &e) {
+ CPPUNIT_ASSERT(e.what());
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Schedule a single playlist, and then query for available timeframes
+ * around it.
+ *----------------------------------------------------------------------------*/
+void
+PostgresqlScheduleTest :: scheduleAndQueryTest(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ // create a 1 hour long playlist, from 10 o'clock 2004-07-23
+ Ptr::Ref id = UniqueId::generateId();
+ Ptr::Ref playlength(new time_duration(1, 0, 0));
+ Ptr::Ref playlist(new Playlist(id, playlength));
+ Ptr::Ref from(new ptime(time_from_string(
+ "2004-07-23 10:00:00")));
+
+ try {
+ schedule->schedulePlaylist(playlist, from);
+ } catch (std::invalid_argument &e) {
+ CPPUNIT_ASSERT(e.what());
+ }
+
+ // check for available timeframes around the inserted one
+ Ptr::Ref to;
+
+ // this is the exact same timeframe as the scheduled playlist
+ from.reset(new ptime(time_from_string("2004-07-23 10:00:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 11:00:00")));
+
+ CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe before our playlist
+ from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 09:50:00")));
+
+ CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe after our playlist
+ from.reset(new ptime(time_from_string("2004-07-23 11:10:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 12:00:00")));
+
+ CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe inside ours
+ from.reset(new ptime(time_from_string("2004-07-23 10:10:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 10:50:00")));
+
+ CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe encapsulating ours
+ from.reset(new ptime(time_from_string("2004-07-23 09:50:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 11:10:00")));
+
+ CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe starting earlier, but flowing into ours
+ from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 10:10:00")));
+
+ CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe starting inside ours, and continuing afterwards
+ from.reset(new ptime(time_from_string("2004-07-23 10:50:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 11:50:00")));
+
+ CPPUNIT_ASSERT(!schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe ending exaclty when ours starts, which is OK
+ from.reset(new ptime(time_from_string("2004-07-23 09:00:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 10:00:00")));
+
+ CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
+
+ // a timeframe starting exactly when ours ends, which is OK
+ from.reset(new ptime(time_from_string("2004-07-23 11:00:00")));
+ to.reset(new ptime(time_from_string("2004-07-23 12:00:00")));
+
+ CPPUNIT_ASSERT(schedule->isTimeframeAvailable(from, to));
+}
+
diff --git a/livesupport/products/scheduler/src/PostgresqlScheduleTest.h b/livesupport/products/scheduler/src/PostgresqlScheduleTest.h
new file mode 100644
index 000000000..fddef5bce
--- /dev/null
+++ b/livesupport/products/scheduler/src/PostgresqlScheduleTest.h
@@ -0,0 +1,142 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/PostgresqlScheduleTest.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef PostgresqlScheduleTest_h
+#define PostgresqlScheduleTest_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+
+#include "LiveSupport/Db/ConnectionManagerInterface.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+using namespace LiveSupport::Db;
+using namespace LiveSupport::Core;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * Unit test for the PostgresqlSchedule class.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ * @see PostgresqlSchedule
+ */
+class PostgresqlScheduleTest : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE(PostgresqlScheduleTest);
+ CPPUNIT_TEST(firstTest);
+ CPPUNIT_TEST(simpleScheduleTest);
+ CPPUNIT_TEST(scheduleAndQueryTest);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ /**
+ * The connection manager used for testing.
+ */
+ Ptr::Ref cm;
+
+ /**
+ * The schedule used for testing.
+ */
+ Ptr::Ref schedule;
+
+ protected:
+
+ /**
+ * Test for an available timeframe in an empty schedule database.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ firstTest(void) throw (CPPUNIT_NS::Exception);
+
+ /**
+ * Schedule a single playlist.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ simpleScheduleTest(void) throw (CPPUNIT_NS::Exception);
+
+ /**
+ * Schedule a single playlist, and then query for available timeframes
+ * around it.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ scheduleAndQueryTest(void) throw (CPPUNIT_NS::Exception);
+
+ public:
+
+ /**
+ * Set up the environment for the test case.
+ */
+ void
+ setUp(void) throw ();
+
+ /**
+ * Clean up the environment after the test case.
+ */
+ void
+ tearDown(void) throw ();
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // PostgresqlScheduleTest_h
+
diff --git a/livesupport/products/scheduler/src/ScheduleFactory.cxx b/livesupport/products/scheduler/src/ScheduleFactory.cxx
new file mode 100644
index 000000000..d84f7826a
--- /dev/null
+++ b/livesupport/products/scheduler/src/ScheduleFactory.cxx
@@ -0,0 +1,117 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ScheduleFactory.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include "LiveSupport/Db/ConnectionManagerFactory.h"
+#include "PostgresqlSchedule.h"
+#include "ScheduleFactory.h"
+
+
+using namespace LiveSupport::Core;
+using namespace LiveSupport::Db;
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/*------------------------------------------------------------------------------
+ * The name of the config element for this class
+ *----------------------------------------------------------------------------*/
+const std::string ScheduleFactory::configElementNameStr =
+ "scheduleFactory";
+
+/*------------------------------------------------------------------------------
+ * The singleton instance of Scheduleactory
+ *----------------------------------------------------------------------------*/
+Ptr::Ref ScheduleFactory::singleton;
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Return the singleton instance to ScheduleFactory
+ *----------------------------------------------------------------------------*/
+Ptr::Ref
+ScheduleFactory :: getInstance(void) throw ()
+{
+ if (!singleton.get()) {
+ singleton.reset(new ScheduleFactory());
+ }
+
+ return singleton;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Configure the schedule factory.
+ *----------------------------------------------------------------------------*/
+void
+ScheduleFactory :: configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error)
+{
+ if (element.get_name() != configElementNameStr) {
+ std::string eMsg = "Bad configuration element ";
+ eMsg += element.get_name();
+ throw std::invalid_argument(eMsg);
+ }
+
+ schedule.reset();
+
+ Ptr::Ref cmf =
+ ConnectionManagerFactory::getInstance();
+ Ptr::Ref cm = cmf->getConnectionManager();
+
+ // try to look for a PostgresqlSchedule configuration element
+ xmlpp::Node::NodeList nodes =
+ element.get_children(PostgresqlSchedule::getConfigElementName());
+ if (nodes.size() >= 1) {
+ const xmlpp::Element * configElement =
+ dynamic_cast (*(nodes.begin()));
+ Ptr::Ref dbs(new PostgresqlSchedule(cm));
+ dbs->configure(*configElement);
+ schedule = dbs;
+ }
+
+ if (!schedule) {
+ throw std::invalid_argument("no storage client factories to configure");
+ }
+}
+
+
diff --git a/livesupport/products/scheduler/src/ScheduleFactory.h b/livesupport/products/scheduler/src/ScheduleFactory.h
new file mode 100644
index 000000000..e25be6baa
--- /dev/null
+++ b/livesupport/products/scheduler/src/ScheduleFactory.h
@@ -0,0 +1,163 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ScheduleFactory.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef ScheduleFactory_h
+#define ScheduleFactory_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+
+#include "LiveSupport/Core/Configurable.h"
+#include "ScheduleInterface.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * The factory to create appropriate Schedule objects.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class ScheduleFactory :
+ virtual public Configurable
+{
+ private:
+ /**
+ * The name of the configuration XML elmenent used by this object.
+ */
+ static const std::string configElementNameStr;
+
+ /**
+ * The singleton instance of this object.
+ */
+ static Ptr::Ref singleton;
+
+ /**
+ * The schedule created by this factory.
+ */
+ Ptr::Ref schedule;
+
+ /**
+ * The default constructor.
+ */
+ ScheduleFactory(void) throw()
+ {
+ }
+
+
+ public:
+ /**
+ * A virtual destructor, as this class has virtual functions.
+ */
+ virtual
+ ~ScheduleFactory(void) throw ()
+ {
+ }
+
+ /**
+ * Return the name of the XML element this object expects
+ * to be sent to a call to configure().
+ *
+ * @return the name of the expected XML configuration element.
+ */
+ static const std::string
+ configElementName(void) throw ()
+ {
+ return configElementNameStr;
+ }
+
+ /**
+ * Returns the singleton instance of this object.
+ *
+ * @return the singleton instance of this object.
+ */
+ static Ptr::Ref
+ getInstance() throw ();
+
+ /**
+ * Configure the object based on the XML element supplied.
+ *
+ * @param element the XML element to configure the object from.
+ * @exception std::invalid_argument if the supplied XML element
+ * contains bad configuraiton information
+ * @exception std::logic_error if the object has already
+ * been configured, and can not be reconfigured.
+ */
+ virtual void
+ configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error);
+
+ /**
+ * Return a schedule.
+ *
+ * @return the appropriate schedule, according to the
+ * configuration of this factory.
+ */
+ Ptr::Ref
+ getSchedule(void) throw ()
+ {
+ return schedule;
+ }
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Storage
+} // namespace LiveSupport
+
+#endif // ScheduleFactory_h
+
diff --git a/livesupport/products/scheduler/src/ScheduleInterface.h b/livesupport/products/scheduler/src/ScheduleInterface.h
new file mode 100644
index 000000000..426b06344
--- /dev/null
+++ b/livesupport/products/scheduler/src/ScheduleInterface.h
@@ -0,0 +1,115 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ScheduleInterface.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef ScheduleInterface_h
+#define ScheduleInterface_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+#include
+
+#include "LiveSupport/Core/Ptr.h"
+#include "LiveSupport/Core/Installable.h"
+#include "LiveSupport/Core/Playlist.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace boost::posix_time;
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * The generic interface for the component scheduling events.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class ScheduleInterface : virtual public Installable
+{
+ public:
+ /**
+ * Check if a timeframe is available for scheduling.
+ *
+ * @param from the start time of the timeframe.
+ * @param to the end time of the timeframe.
+ * @return true if the timeframe is available, false otherwise.
+ */
+ virtual bool
+ isTimeframeAvailable(Ptr::Ref from,
+ Ptr::Ref to) throw ()
+ = 0;
+
+ /**
+ * Schedule a playlist.
+ *
+ * @param playlist the playlist to schedule.
+ * @param playtime the time to schedule the playlist for.
+ * @exception std::invalid_argument if the there is something
+ * already scheduled for the duration of the playlist.
+ */
+ virtual void
+ schedulePlaylist(Ptr::Ref playlist,
+ Ptr::Ref playtime)
+ throw (std::invalid_argument)
+ = 0;
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // ScheduleInterface_h
+
diff --git a/livesupport/products/scheduler/src/SchedulerDaemon.cxx b/livesupport/products/scheduler/src/SchedulerDaemon.cxx
new file mode 100644
index 000000000..cfcb49246
--- /dev/null
+++ b/livesupport/products/scheduler/src/SchedulerDaemon.cxx
@@ -0,0 +1,119 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemon.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SIGNAL_H
+#include
+#else
+#error "Need signal.h"
+#endif
+
+#if HAVE_SYS_STAT_H
+#include
+#else
+#error "Need sys/stat.h"
+#endif
+
+
+#include
+#include
+#include
+#include
+
+#include "SchedulerDaemon.h"
+
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/**
+ * The singleton instance of the Scheduler daemon object.
+ */
+SchedulerDaemon * SchedulerDaemon::schedulerDaemon = 0;
+
+/**
+ * The name of the XML configuration element for the Scheduler daemon.
+ */
+static const std::string confElement = "scheduler";
+
+/**
+ * The name of the XML configuration element for the XmlRpcDaemon inside.
+ */
+static const std::string xmlRpcDaemonConfElement = "xmlRpcDaemon";
+
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Return the singleton instnace.
+ *----------------------------------------------------------------------------*/
+class SchedulerDaemon *
+SchedulerDaemon :: getInstance (void) throw ()
+{
+ if (!schedulerDaemon) {
+ schedulerDaemon = new SchedulerDaemon();
+ }
+
+ return schedulerDaemon;
+}
+
+/*------------------------------------------------------------------------------
+ * Configure the scheduler daemon
+ *----------------------------------------------------------------------------*/
+void
+SchedulerDaemon :: configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error)
+{
+ if (element.get_name() != confElement) {
+ std::string eMsg = "Bad configuration element ";
+ eMsg += element.get_name();
+ throw std::invalid_argument(eMsg);
+ }
+
+ xmlpp::Node::NodeList nodes =
+ element.get_children(xmlRpcDaemonConfElement);
+ if (nodes.size() < 1) {
+ throw std::invalid_argument("no xmlRpcDaemon element");
+ }
+ configureXmlRpcDaemon( *((const xmlpp::Element*) *(nodes.begin())) );
+}
diff --git a/livesupport/products/scheduler/src/SchedulerDaemon.h b/livesupport/products/scheduler/src/SchedulerDaemon.h
new file mode 100644
index 000000000..72e0ab17c
--- /dev/null
+++ b/livesupport/products/scheduler/src/SchedulerDaemon.h
@@ -0,0 +1,149 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemon.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef SchedulerDaemon_h
+#define SchedulerDaemon_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include
+#else
+#error "Need sys/types.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+#include
+#include
+#include
+#include
+
+#include "XmlRpcDaemon.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * Scheduler daemon main class.
+ * This class is responsible for starting, running and stopping the
+ * Scheduler daemon.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class SchedulerDaemon : public XmlRpcDaemon
+{
+ private:
+
+ /**
+ * The singleton instance of the scheduler daemon.
+ */
+ static SchedulerDaemon * schedulerDaemon;
+
+ /**
+ * Default constructor.
+ */
+ SchedulerDaemon (void) throw ()
+ : XmlRpcDaemon()
+ {
+ }
+
+ protected:
+
+ /**
+ * Register your XML-RPC functions by implementing this function.
+ */
+ virtual void
+ registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer)
+ throw (std::logic_error)
+ {
+ }
+
+ public:
+
+ /**
+ * Return a pointer to the singleton instance of SchedulerDaemon.
+ *
+ * @return a pointer to the singleton instance of SchedulerDaemon
+ */
+ static SchedulerDaemon *
+ getInstance (void) throw ();
+
+ /**
+ * Configure the scheduler daemon based on the XML element
+ * supplied.
+ *
+ * @param element the XML element to configure the scheduler
+ * daemon from.
+ * @exception std::invalid_argument if the supplied XML element
+ * contains bad configuraiton information
+ * @exception std::logic_error if the scheduler daemon has already
+ * been configured.
+ */
+ void
+ configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error);
+
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // SchedulerDaemon_h
+
diff --git a/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx b/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx
new file mode 100644
index 000000000..f528835a7
--- /dev/null
+++ b/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx
@@ -0,0 +1,129 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemonTest.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+
+#include
+
+#include "SchedulerDaemon.h"
+#include "SchedulerDaemonTest.h"
+
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+//CPPUNIT_TEST_SUITE_REGISTRATION(SchedulerDaemonTest);
+
+/**
+ * The name of the configuration file for the scheduler daemon.
+ */
+static const std::string configFileName = "etc/scheduler.xml";
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Set up the test environment
+ *----------------------------------------------------------------------------*/
+void
+SchedulerDaemonTest :: setUp(void) throw ()
+{
+ SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
+
+ if (!daemon->isConfigured()) {
+ try {
+ std::auto_ptr
+ parser(new xmlpp::DomParser(configFileName, true));
+ const xmlpp::Document * document = parser->get_document();
+ daemon->configure(*(document->get_root_node()));
+ } catch (std::invalid_argument &e) {
+ CPPUNIT_FAIL("semantic error in configuration file");
+ } catch (xmlpp::exception &e) {
+ CPPUNIT_FAIL("error parsing configuration file");
+ }
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Clean up the test environment
+ *----------------------------------------------------------------------------*/
+void
+SchedulerDaemonTest :: tearDown(void) throw ()
+{
+}
+
+
+/*------------------------------------------------------------------------------
+ * Test to see if the singleton Hello object is accessible
+ *----------------------------------------------------------------------------*/
+void
+SchedulerDaemonTest :: getSingleton(void) throw (CPPUNIT_NS::Exception)
+{
+ CPPUNIT_ASSERT( SchedulerDaemon::getInstance() );
+}
+
+
+/*------------------------------------------------------------------------------
+ * Test to see if the scheduler starts and stops OK
+ *----------------------------------------------------------------------------*/
+void
+SchedulerDaemonTest :: testStartStop(void) throw (CPPUNIT_NS::Exception)
+{
+ SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
+
+ CPPUNIT_ASSERT( daemon );
+ CPPUNIT_ASSERT( !(daemon->isRunning()) );
+ daemon->start();
+ sleep(3);
+ CPPUNIT_ASSERT( daemon->isRunning() );
+ daemon->stop();
+ sleep(3);
+ CPPUNIT_ASSERT( !(daemon->isRunning()) );
+}
+
+
diff --git a/livesupport/products/scheduler/src/SchedulerDaemonTest.h b/livesupport/products/scheduler/src/SchedulerDaemonTest.h
new file mode 100644
index 000000000..216c22a9c
--- /dev/null
+++ b/livesupport/products/scheduler/src/SchedulerDaemonTest.h
@@ -0,0 +1,117 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SchedulerDaemonTest.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef SchedulerDaemonTest_h
+#define SchedulerDaemonTest_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * Unit test for the SchedulerDaemon class.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ * @see SchedulerDaemon
+ */
+class SchedulerDaemonTest : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE(SchedulerDaemonTest);
+ CPPUNIT_TEST(getSingleton);
+ CPPUNIT_TEST(testStartStop);
+ CPPUNIT_TEST_SUITE_END();
+
+ protected:
+
+ /**
+ * A simple test to see if the singleton Hello object is accessible.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ getSingleton(void) throw (CPPUNIT_NS::Exception);
+
+ /**
+ * Test to see if the daemon starts an stops OK.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ testStartStop(void) throw (CPPUNIT_NS::Exception);
+
+ public:
+
+ /**
+ * Set up the environment for the test case.
+ */
+ void
+ setUp(void) throw ();
+
+ /**
+ * Clean up the environment after the test case.
+ */
+ void
+ tearDown(void) throw ();
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // SchedulerDaemonTest_h
+
diff --git a/livesupport/products/scheduler/src/SignalDispatcher.cxx b/livesupport/products/scheduler/src/SignalDispatcher.cxx
new file mode 100644
index 000000000..976b8fa1a
--- /dev/null
+++ b/livesupport/products/scheduler/src/SignalDispatcher.cxx
@@ -0,0 +1,142 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SignalDispatcher.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SIGNAL_H
+#include
+#else
+#error "Need signal.h"
+#endif
+
+#if HAVE_SYS_STAT_H
+#include
+#else
+#error "Need sys/stat.h"
+#endif
+
+
+#include
+#include
+#include
+#include
+
+#include "SignalDispatcher.h"
+
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/*------------------------------------------------------------------------------
+ * The singleton isntnace of SignalDispatcher.
+ *----------------------------------------------------------------------------*/
+SignalDispatcher * SignalDispatcher::instance = 0;
+
+/*------------------------------------------------------------------------------
+ * The signal handlers.
+ *----------------------------------------------------------------------------*/
+SignalHandler * SignalDispatcher::handlers[NSIG];
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Return the singleton instnace.
+ *----------------------------------------------------------------------------*/
+class SignalDispatcher *
+SignalDispatcher :: getInstance (void) throw ()
+{
+ if (!instance) {
+ instance = new SignalDispatcher();
+ }
+
+ return instance;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Register a signal handler
+ *----------------------------------------------------------------------------*/
+void
+SignalDispatcher :: registerHandler(
+ int signal,
+ SignalHandler * signalHandler)
+ throw (std::invalid_argument)
+{
+ if (signal < 0 || signal >= NSIG) {
+ throw std::invalid_argument("invalid signal value");
+ }
+ if (!signalHandler) {
+ throw std::invalid_argument("signalHandler is 0");
+ }
+
+ handlers[signal] = signalHandler;
+
+ // register our dispatcher for this signal
+ ::signal(signal, dispatcher);
+}
+
+
+/*------------------------------------------------------------------------------
+ * Remove a signal handler
+ *----------------------------------------------------------------------------*/
+void
+SignalDispatcher :: removeHandler(
+ int signal)
+ throw (std::invalid_argument)
+{
+ if (signal < 0 || signal >= NSIG) {
+ throw std::invalid_argument("invalid signal value");
+ }
+
+ handlers[signal] = 0;
+
+ ::signal(signal, SIG_DFL);
+}
+
+/*------------------------------------------------------------------------------
+ * Our signal dispatcher
+ *----------------------------------------------------------------------------*/
+void
+SignalDispatcher :: dispatcher(int signal) throw ()
+{
+ handlers[signal]->handleSignal(signal);
+}
+
diff --git a/livesupport/products/scheduler/src/SignalDispatcher.h b/livesupport/products/scheduler/src/SignalDispatcher.h
new file mode 100644
index 000000000..bc363f110
--- /dev/null
+++ b/livesupport/products/scheduler/src/SignalDispatcher.h
@@ -0,0 +1,148 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SignalDispatcher.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef SignalDispatcher_h
+#define SignalDispatcher_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SIGNAL_H
+#include
+#else
+#error "Need signal.h"
+#endif
+
+#include
+#include
+
+#include "SignalHandler.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * A class to dispatch signals.
+ * See http://www.cs.wustl.edu/~schmidt/signal-patterns.html for details.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class SignalDispatcher
+{
+ private:
+
+ /**
+ * The singleton instance of this class.
+ */
+ static SignalDispatcher * instance;
+
+ /**
+ * An array of registered signal handlers,
+ * of size NSIG defined in signal.h
+ */
+ static SignalHandler * handlers[NSIG];
+
+ /**
+ * Default constructor.
+ */
+ SignalDispatcher(void) throw ()
+ {
+ }
+
+ /**
+ * The function registered to handle signals.
+ *
+ * @param signal the signal being handled.
+ */
+ static void
+ dispatcher(int signal) throw ();
+
+ public:
+
+ /**
+ * Return the singleton instance of SignalDispatcher.
+ *
+ * @return the singleton instance of SignalDispatcher.
+ */
+ static SignalDispatcher *
+ getInstance(void) throw ();
+
+ /**
+ * Register a signal handler for a specific signal.
+ *
+ * @param signal the signal to register for.
+ * @param signalHandler the signal handler to register.
+ * @exception std::invalid_argument if signal is out of range,
+ * or if signalHandler is 0.
+ */
+ void
+ registerHandler(int signal,
+ SignalHandler * signalHandler)
+ throw (std::invalid_argument);
+
+ /**
+ * Remove a signal handler for a specific signal.
+ * Restores the original system signal handling.
+ *
+ * @param signal the signal to remove the handler for.
+ * @exception std::invalid_argument if signal is out of range.
+ */
+ void
+ removeHandler(int signal) throw (std::invalid_argument);
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // SignalDispatcher_h
+
diff --git a/livesupport/products/scheduler/src/SignalHandler.h b/livesupport/products/scheduler/src/SignalHandler.h
new file mode 100644
index 000000000..86c05c644
--- /dev/null
+++ b/livesupport/products/scheduler/src/SignalHandler.h
@@ -0,0 +1,87 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/SignalHandler.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef SignalHandler_h
+#define SignalHandler_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * A class to handle a signal.
+ * Register subclasses of this class at SignalDispatcher.
+ * See http://www.cs.wustl.edu/~schmidt/signal-patterns.html for details.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ * @see SignalDispatcher
+ */
+class SignalHandler
+{
+ public:
+ /**
+ * Handle the signal.
+ *
+ * @param signal the actual signal received.
+ */
+ virtual void
+ handleSignal(int signal) throw () = 0;
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // SignalHandler_h
+
diff --git a/livesupport/products/scheduler/src/TestRunner.cxx b/livesupport/products/scheduler/src/TestRunner.cxx
new file mode 100644
index 000000000..0cf694cae
--- /dev/null
+++ b/livesupport/products/scheduler/src/TestRunner.cxx
@@ -0,0 +1,85 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/TestRunner.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Run all tests
+ *----------------------------------------------------------------------------*/
+int
+main( int argc,
+ char * argv[] ) throw ()
+{
+ // Create the event manager and test controller
+ CPPUNIT_NS::TestResult controller;
+
+ // Add a listener that colllects test result
+ CPPUNIT_NS::TestResultCollector result;
+ controller.addListener( &result );
+
+ // Add a listener that print dots as test run.
+ CPPUNIT_NS::BriefTestProgressListener progress;
+ controller.addListener( &progress );
+
+ // Add the top suite to the test runner
+ CPPUNIT_NS::TestRunner runner;
+ runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
+ runner.run( controller );
+
+ // Print test in a compiler compatible format.
+ CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
+ outputter.setLocationFormat("%p:%l:");
+ outputter.write();
+
+ return result.wasSuccessful() ? 0 : 1;
+}
+
diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx b/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx
new file mode 100644
index 000000000..ec52510b3
--- /dev/null
+++ b/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx
@@ -0,0 +1,183 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethod.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#ifdef HAVE_TIME_H
+#include
+#else
+#error need time.h
+#endif
+
+
+#include
+
+#include "LiveSupport/Core/StorageClientInterface.h"
+#include "LiveSupport/Storage/StorageClientFactory.h"
+#include "ScheduleInterface.h"
+#include "ScheduleFactory.h"
+#include "UploadPlaylistMethod.h"
+
+
+using namespace boost::posix_time;
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+using namespace LiveSupport::Storage;
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/*------------------------------------------------------------------------------
+ * The name of this XML-RPC method.
+ *----------------------------------------------------------------------------*/
+const std::string UploadPlaylistMethod::methodName = "stop";
+
+/*------------------------------------------------------------------------------
+ * The name of the playlist id member in the XML-RPC parameter
+ * structure.
+ *----------------------------------------------------------------------------*/
+const std::string UploadPlaylistMethod::playlistIdName = "playlistId";
+
+/*------------------------------------------------------------------------------
+ * The name of the playlength member in the XML-RPC parameter
+ * structure.
+ *----------------------------------------------------------------------------*/
+const std::string UploadPlaylistMethod::playlengthName = "playlength";
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Construct the StopXmlRpcMethod and register it right away.
+ *----------------------------------------------------------------------------*/
+UploadPlaylistMethod :: UploadPlaylistMethod (
+ Ptr::Ref xmlRpcServer) throw()
+ : XmlRpc::XmlRpcServerMethod(methodName, xmlRpcServer.get())
+{
+}
+
+
+/*------------------------------------------------------------------------------
+ * Extract the UniqueId from an XML-RPC function call parameter
+ *----------------------------------------------------------------------------*/
+Ptr::Ref
+UploadPlaylistMethod :: extractPlaylistId(
+ XmlRpc::XmlRpcValue & xmlRpcValue)
+ throw (std::invalid_argument)
+{
+ if (!xmlRpcValue.hasMember(playlistIdName)) {
+ throw std::invalid_argument("no playlist id in parameter structure");
+ }
+
+ Ptr::Ref id(new UniqueId((int) xmlRpcValue[playlistIdName]));
+ return id;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Extract the playtime from an XML-RPC function call parameter
+ *----------------------------------------------------------------------------*/
+Ptr::Ref
+UploadPlaylistMethod :: extractPlayschedule(
+ XmlRpc::XmlRpcValue & xmlRpcValue)
+ throw (std::invalid_argument)
+{
+ if (!xmlRpcValue.hasMember(playlengthName)) {
+ throw std::invalid_argument("no playlength in parameter structure");
+ }
+
+ struct tm & tm = (struct tm &) xmlRpcValue[playlengthName];
+ time_t time = mktime(&tm);
+ Ptr::Ref ptime(new ptime(from_time_t(time)));
+
+ return ptime;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Execute the stop XML-RPC function call.
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethod :: execute( XmlRpc::XmlRpcValue & parameters,
+ XmlRpc::XmlRpcValue & returnValue)
+ throw ()
+{
+ try {
+ Ptr::Ref id = extractPlaylistId(parameters);
+ Ptr::Ref playschedule = extractPlayschedule(parameters);
+
+ Ptr::Ref scf;
+ Ptr::Ref storage;
+
+ scf = StorageClientFactory::getInstance();
+ storage = scf->getStorageClient();
+
+ if (!storage->existsPlaylist(id)) {
+ // TODO: mark error
+ returnValue = XmlRpc::XmlRpcValue(false);
+ return;
+ }
+
+ Ptr::Ref playlist = storage->getPlaylist(id);
+ Ptr::Ref until(new ptime(*playschedule
+ + *(playlist->getPlaylength())));
+
+ Ptr::Ref sf = ScheduleFactory::getInstance();
+ Ptr::Ref schedule = sf->getSchedule();
+
+ if (!schedule->isTimeframeAvailable(playschedule, until)) {
+ // TODO: mark error;
+ returnValue = XmlRpc::XmlRpcValue(false);
+ return;
+ }
+
+ schedule->schedulePlaylist(playlist, playschedule);
+
+ } catch (std::invalid_argument &e) {
+ // TODO: mark error
+ returnValue = XmlRpc::XmlRpcValue(false);
+ return;
+ }
+
+ // TODO
+ returnValue = XmlRpc::XmlRpcValue(true);
+}
+
diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethod.h b/livesupport/products/scheduler/src/UploadPlaylistMethod.h
new file mode 100644
index 000000000..3ad7a66e1
--- /dev/null
+++ b/livesupport/products/scheduler/src/UploadPlaylistMethod.h
@@ -0,0 +1,160 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethod.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef UploadPlaylistMetohd_h
+#define UploadPlaylistMethod_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "LiveSupport/Core/Ptr.h"
+#include "LiveSupport/Core/UniqueId.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * An XML-RPC method object to accept a playlist for upload,
+ * and schedule it in the scheduler.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class UploadPlaylistMethod : public XmlRpc::XmlRpcServerMethod
+{
+ private:
+ /**
+ * The name of this method, as it will be registered into the
+ * XML-RPC server.
+ */
+ static const std::string methodName;
+
+ /**
+ * The name of the playlist id member in the XML-RPC parameter
+ * structure.
+ */
+ static const std::string playlistIdName;
+
+ /**
+ * The name of the playlength member in the XML-RPC parameter
+ * structure.
+ */
+ static const std::string playlengthName;
+
+ /**
+ * Extract the playlist id from the XML-RPC parameters.
+ *
+ * @param xmlRpcValue the XML-RPC parameter to extract from.
+ * @return a UniqueId that was found in the XML-RPC parameter.
+ * @exception std::invalid_argument if there was no UniqueId
+ * in xmlRpcValue
+ */
+ Ptr::Ref
+ extractPlaylistId(XmlRpc::XmlRpcValue & xmlRpcValue)
+ throw (std::invalid_argument);
+
+ /**
+ * Extract the playtime from the XML-RPC parameters.
+ *
+ * @param xmlRpcValue the XML-RPC parameter to extract from.
+ * @return the playing time, as stored in the XML-RPC parameter
+ * @exception std::invalid_argument if there was no playtime
+ * in xmlRpcValue
+ */
+ Ptr::Ref
+ extractPlayschedule(XmlRpc::XmlRpcValue & xmlRpcValue)
+ throw (std::invalid_argument);
+
+
+ public:
+ /**
+ * A default constructor, for testing purposes.
+ */
+ UploadPlaylistMethod(void) throw ()
+ : XmlRpc::XmlRpcServerMethod(methodName)
+ {
+ }
+
+ /**
+ * Constuctor that registers the method with the server right away.
+ *
+ * @param xmlRpcServer the XML-RPC server to register with.
+ */
+ UploadPlaylistMethod(
+ Ptr::Ref xmlRpcServer)
+ throw ();
+
+ /**
+ * Execute the upload playlist command on the Scheduler daemon.
+ *
+ * @param parameters XML-RPC function call parameters
+ * @param returnValue the return value of the call (out parameter)
+ */
+ void
+ execute( XmlRpc::XmlRpcValue & parameters,
+ XmlRpc::XmlRpcValue & returnValue) throw ();
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // UploadPlaylistMetohd_h
+
diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx
new file mode 100644
index 000000000..3d98a2f2f
--- /dev/null
+++ b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx
@@ -0,0 +1,214 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethodTest.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+
+#include
+#include
+#include
+
+#include "LiveSupport/Db/ConnectionManagerFactory.h"
+#include "LiveSupport/Storage/StorageClientFactory.h"
+#include "ScheduleFactory.h"
+#include "UploadPlaylistMethod.h"
+#include "UploadPlaylistMethodTest.h"
+
+
+using namespace LiveSupport::Db;
+using namespace LiveSupport::Storage;
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+CPPUNIT_TEST_SUITE_REGISTRATION(UploadPlaylistMethodTest);
+
+/**
+ * The name of the configuration file for the storage client factory.
+ */
+const std::string UploadPlaylistMethodTest::storageClientConfig =
+ "etc/storageClient.xml";
+
+/**
+ * The name of the configuration file for the connection manager factory.
+ */
+const std::string UploadPlaylistMethodTest::connectionManagerConfig =
+ "etc/connectionManagerFactory.xml";
+
+/**
+ * The name of the configuration file for the schedule factory.
+ */
+const std::string UploadPlaylistMethodTest::scheduleConfig =
+ "etc/scheduleFactory.xml";
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Configure a Configurable with an XML file.
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethodTest :: configure(
+ Ptr::Ref configurable,
+ const std::string fileName)
+ throw (std::invalid_argument,
+ xmlpp::exception)
+{
+ Ptr::Ref parser(new xmlpp::DomParser(fileName, true));
+ const xmlpp::Document * document = parser->get_document();
+ const xmlpp::Element * root = document->get_root_node();
+
+ configurable->configure(*root);
+}
+
+
+/*------------------------------------------------------------------------------
+ * Set up the test environment
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethodTest :: setUp(void) throw ()
+{
+ try {
+ Ptr::Ref scf
+ = StorageClientFactory::getInstance();
+ configure(scf, storageClientConfig);
+
+ Ptr::Ref cmf
+ = ConnectionManagerFactory::getInstance();
+ configure(cmf, connectionManagerConfig);
+
+ Ptr::Ref sf = ScheduleFactory::getInstance();
+ configure(sf, scheduleConfig);
+
+ schedule = sf->getSchedule();
+ schedule->install();
+ } catch (std::invalid_argument &e) {
+ CPPUNIT_FAIL("semantic error in configuration file");
+ } catch (xmlpp::exception &e) {
+ CPPUNIT_FAIL("error parsing configuration file");
+ } catch (std::exception &e) {
+ CPPUNIT_FAIL(e.what());
+ }
+}
+
+
+/*------------------------------------------------------------------------------
+ * Clean up the test environment
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethodTest :: tearDown(void) throw ()
+{
+ schedule->uninstall();
+}
+
+
+/*------------------------------------------------------------------------------
+ * Test to see if the singleton Hello object is accessible
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethodTest :: firstTest(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ Ptr::Ref method(new UploadPlaylistMethod());
+ XmlRpc::XmlRpcValue parameters;
+ XmlRpc::XmlRpcValue result;
+ struct tm time;
+
+ // set up a structure for the parameters
+ parameters["playlistId"] = 1;
+ strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &time);
+ parameters["playlength"] = &time;
+
+ method->execute(parameters, result);
+ CPPUNIT_ASSERT(result);
+}
+
+
+/*------------------------------------------------------------------------------
+ * Try to upload overlapping playlists, and see them fail.
+ *----------------------------------------------------------------------------*/
+void
+UploadPlaylistMethodTest :: overlappingPlaylists(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ Ptr::Ref method(new UploadPlaylistMethod());
+ XmlRpc::XmlRpcValue parameters;
+ XmlRpc::XmlRpcValue result;
+ struct tm time;
+
+ // load the first playlist, this will succeed
+ parameters["playlistId"] = 1;
+ strptime("2001-11-12 10:00:00", "%Y-%m-%d %H:%M:%S", &time);
+ parameters["playlength"] = &time;
+
+ method->execute(parameters, result);
+ CPPUNIT_ASSERT(result);
+
+ // try to load the same one, but in an overlapping time region
+ // (we know that playlist with id 1 in 1 hour long)
+ parameters["playlistId"] = 1;
+ strptime("2001-11-12 10:30:00", "%Y-%m-%d %H:%M:%S", &time);
+ parameters["playlength"] = &time;
+
+ method->execute(parameters, result);
+ CPPUNIT_ASSERT(!result);
+
+ // try to load the same one, but now in good timing
+ parameters["playlistId"] = 1;
+ strptime("2001-11-12 11:30:00", "%Y-%m-%d %H:%M:%S", &time);
+ parameters["playlength"] = &time;
+
+ method->execute(parameters, result);
+ CPPUNIT_ASSERT(result);
+
+ // try to load the same one, this time overlapping both previos instnaces
+ parameters["playlistId"] = 1;
+ strptime("2001-11-12 10:45:00", "%Y-%m-%d %H:%M:%S", &time);
+ parameters["playlength"] = &time;
+
+ method->execute(parameters, result);
+ CPPUNIT_ASSERT(!result);
+}
+
diff --git a/livesupport/products/scheduler/src/UploadPlaylistMethodTest.h b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.h
new file mode 100644
index 000000000..299344d11
--- /dev/null
+++ b/livesupport/products/scheduler/src/UploadPlaylistMethodTest.h
@@ -0,0 +1,154 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/UploadPlaylistMethodTest.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef UploadPlaylistMethodTest_h
+#define UploadPlaylistMethodTest_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+using namespace LiveSupport;
+using namespace LiveSupport::Core;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * Unit test for the UploadPlaylistMetohd class.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ * @see UploadPlaylistMethod
+ */
+class UploadPlaylistMethodTest : public CPPUNIT_NS::TestFixture
+{
+ CPPUNIT_TEST_SUITE(UploadPlaylistMethodTest);
+ CPPUNIT_TEST(firstTest);
+ CPPUNIT_TEST(overlappingPlaylists);
+ CPPUNIT_TEST_SUITE_END();
+
+ /**
+ * The name of the configuration file for the storage client factory.
+ */
+ static const std::string storageClientConfig;
+
+ /**
+ * The name of the configuration file for the connection manager
+ * factory.
+ */
+ static const std::string connectionManagerConfig;
+
+ /**
+ * The name of the configuration file for the schedule factory.
+ */
+ static const std::string scheduleConfig;
+
+ /**
+ * The schedule used during the test.
+ */
+ Ptr::Ref schedule;
+
+ /**
+ * Configure a configurable with an XML file.
+ *
+ * @param configurable configure this
+ * @param fileName the name of the XML file to configure with.
+ * @exception std::invalid_argument on configuration errors.
+ * @exception xmlpp::exception on XML parsing errors.
+ */
+ void
+ configure(Ptr::Ref configurable,
+ std::string fileName)
+ throw (std::invalid_argument,
+ xmlpp::exception);
+
+
+ protected:
+
+ /**
+ * A simple test.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ firstTest(void) throw (CPPUNIT_NS::Exception);
+
+ /**
+ * Try to upload overlapping playlists, and see them fail.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ overlappingPlaylists(void) throw (CPPUNIT_NS::Exception);
+
+ public:
+
+ /**
+ * Set up the environment for the test case.
+ */
+ void
+ setUp(void) throw ();
+
+ /**
+ * Clean up the environment after the test case.
+ */
+ void
+ tearDown(void) throw ();
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // UploadPlaylistMethodTest_h
+
diff --git a/livesupport/products/scheduler/src/XmlRpcDaemon.cxx b/livesupport/products/scheduler/src/XmlRpcDaemon.cxx
new file mode 100644
index 000000000..eade4c891
--- /dev/null
+++ b/livesupport/products/scheduler/src/XmlRpcDaemon.cxx
@@ -0,0 +1,298 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/XmlRpcDaemon.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SIGNAL_H
+#include
+#else
+#error "Need signal.h"
+#endif
+
+#if HAVE_SYS_STAT_H
+#include
+#else
+#error "Need sys/stat.h"
+#endif
+
+
+#include
+#include
+#include
+#include
+
+#include "SignalDispatcher.h"
+#include "XmlRpcDaemonShutdownSignalHandler.h"
+#include "XmlRpcDaemon.h"
+
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/**
+ * The name of the XML configuration element for the Scheduler daemon.
+ */
+static const std::string confElement = "xmlRpcDaemon";
+
+/**
+ * The name of the XML configuration attribute for the XML-RPC host name.
+ */
+static const std::string confXmlRpcHostAttr = "xmlRpcHost";
+
+/**
+ * The name of the XML configuration attribute for the XML-RPC port.
+ */
+static const std::string confXmlRpcPortAttr = "xmlRpcPort";
+
+/**
+ * The name of the XML configuration attribute for the process id file.
+ */
+static const std::string confPidFileNameAttr = "pidFileName";
+
+/**
+ * The umask used by the daemon for file creations
+ */
+static const mode_t uMask = 027;
+
+
+/* =============================================== local function prototypes */
+
+
+/* ============================================================= module code */
+
+/*------------------------------------------------------------------------------
+ * Configure the Scheder daemon according to an XML element
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: configureXmlRpcDaemon(
+ const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error)
+{
+ if (configured) {
+ throw std::logic_error("already configured");
+ }
+
+ const xmlpp::Attribute * attribute;
+ std::stringstream strStr;
+
+ if (element.get_name() != confElement) {
+ std::string eMsg = "Bad configuration element ";
+ eMsg += element.get_name();
+ throw std::invalid_argument(eMsg);
+ }
+
+ if (!(attribute = element.get_attribute(confXmlRpcHostAttr))) {
+ std::string eMsg = "Missing attribute ";
+ eMsg += confXmlRpcHostAttr;
+ throw std::invalid_argument(eMsg);
+ }
+ xmlRpcHost = attribute->get_value();
+
+ if (!(attribute = element.get_attribute(confXmlRpcPortAttr))) {
+ std::string eMsg = "Missing attribute ";
+ eMsg += confXmlRpcPortAttr;
+ throw std::invalid_argument(eMsg);
+ }
+ strStr.str(attribute->get_value());
+ strStr >> xmlRpcPort;
+
+ if (!(attribute = element.get_attribute(confPidFileNameAttr))) {
+ std::string eMsg = "Missing attribute ";
+ eMsg += confPidFileNameAttr;
+ throw std::invalid_argument(eMsg);
+ }
+ pidFileName = attribute->get_value();
+
+ configured = true;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Do all the necessary work of becoming a daemon.
+ * See http://www.enderunix.org/docs/eng/daemon.php and
+ * http://www.linuxprofilm.com/articles/linux-daemon-howto.html
+ * for hints.
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: daemonize(void) throw (std::runtime_error)
+{
+ int i;
+
+ if (getppid() == 1) {
+ // we're already a daemon
+ return;
+ }
+
+ i = fork();
+ if (i < 0) {
+ throw std::runtime_error("fork error");
+ } else if (i > 0) {
+ // this is the parent, simply return
+ return;
+ }
+
+ // now we're in the child process
+
+ // obtain a new process group
+ setsid();
+
+ // change the umask
+ umask(uMask);
+
+ // close standard file descriptors
+ /* TODO: don't close these until we don't have logging
+ std::cin.close();
+ std::cout.close();
+ std::cerr.close();
+ */
+
+ // save the process id
+ savePid();
+
+ // ignore some signals
+ /* TODO
+ signal(SIGCHLD,SIG_IGN);
+ signal(SIGTSTP,SIG_IGN);
+ signal(SIGTTOU,SIG_IGN);
+ signal(SIGTTIN,SIG_IGN);
+ */
+
+ // register our signal hanlder
+ SignalDispatcher * signalDispatcher = SignalDispatcher::getInstance();
+ XmlRpcDaemonShutdownSignalHandler * handler =
+ new XmlRpcDaemonShutdownSignalHandler(this);
+ signalDispatcher->registerHandler(SIGHUP, handler);
+ signalDispatcher->registerHandler(SIGTERM, handler);
+ // FIXME: this signal handler will not be deleted by anyone,
+ // poddible memory leak
+}
+
+
+/*------------------------------------------------------------------------------
+ * Save the current process id.
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: savePid(void) throw ()
+{
+ std::ofstream pidFile(pidFileName.c_str());
+ pidFile << getpid();
+ pidFile.flush();
+ pidFile.close();
+}
+
+
+/*------------------------------------------------------------------------------
+ * Return the saved process id.
+ *----------------------------------------------------------------------------*/
+pid_t
+XmlRpcDaemon :: loadPid(void) throw ()
+{
+ pid_t pid;
+
+ std::ifstream pidFile(pidFileName.c_str());
+ if (pidFile.fail()) {
+ return 0;
+ }
+
+ pidFile >> pid;
+ pidFile.close();
+
+ return pid;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Start the daemon.
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: start (void) throw (std::logic_error)
+{
+ checkForConfiguration();
+
+ if (background) {
+ daemonize();
+ }
+
+ // and now our own XML-RPC methods
+ registerXmlRpcFunctions(xmlRpcServer);
+
+ // bind & run
+ XmlRpc::setVerbosity(5);
+ xmlRpcServer.bindAndListen(xmlRpcPort);
+ xmlRpcServer.work(-1.0);
+}
+
+
+/*------------------------------------------------------------------------------
+ * Tell if the daemon is running.
+ *----------------------------------------------------------------------------*/
+bool
+XmlRpcDaemon :: isRunning (void) throw (std::logic_error)
+{
+ checkForConfiguration();
+
+ return loadPid();
+}
+
+
+/*------------------------------------------------------------------------------
+ * Stop the daemon.
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: stop (void) throw (std::logic_error)
+{
+ checkForConfiguration();
+
+ pid_t pid = loadPid();
+ kill(pid, SIGTERM);
+}
+
+
+/*------------------------------------------------------------------------------
+ * Shut down the daemon.
+ *----------------------------------------------------------------------------*/
+void
+XmlRpcDaemon :: shutdown (void) throw (std::logic_error)
+{
+ checkForConfiguration();
+
+ xmlRpcServer.shutdown();
+ remove(pidFileName.c_str());
+}
+
+
diff --git a/livesupport/products/scheduler/src/XmlRpcDaemon.h b/livesupport/products/scheduler/src/XmlRpcDaemon.h
new file mode 100644
index 000000000..84dc62777
--- /dev/null
+++ b/livesupport/products/scheduler/src/XmlRpcDaemon.h
@@ -0,0 +1,397 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/XmlRpcDaemon.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef XmlRpcDaemon_h
+#define XmlRpcDaemon_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_SYS_TYPES_H
+#include
+#else
+#error "Need sys/types.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+#include
+#include
+#include
+#include
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * A generic XML-RPC daemon, that has to be sublclassed to provide
+ * real functionality.
+ *
+ * To use this class, subclass it, and override the configure() and
+ * registerXmlRpcFunctions() functions.
+ *
+ * The typical usage of the XmlRpcDaemon is as follows. To start the
+ * daemon:
+ *
+ * - create an instance of a subclass of XmlRpcDaemon
+ * - call the configure() method with a proper XML element
+ * - optionally call setBackground()
+ * - call start() to start the daemon
+ *
+ * Stopping the daemon is similar:
+ *
+ * - create an instance of a subclass of XmlRpcDaemon
+ * - call the configure() method with a proper XML element
+ * if it has not yet been configured
+ * - call stop() to stop the daemon
+ *
+ *
+ * The structure of the XML configuration element used to configure the
+ * XML-RPC daemon is as follows:
+ *
+ *
+ *
+ *
+ *
+ * The DTD for the above is:
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ */
+class XmlRpcDaemon
+{
+ private:
+
+ /**
+ * The host the XML-RPC server the daemon is
+ * listening on.
+ */
+ std::string xmlRpcHost;
+
+ /**
+ * The port the XML-RPC server the daemon is
+ * listening on.
+ */
+ unsigned int xmlRpcPort;
+
+ /**
+ * The name of the file where the daemon saves it's process id when
+ * running.
+ */
+ std::string pidFileName;
+
+ /**
+ * Flag indicating if the singleton instnace has been
+ * configured already.
+ */
+ bool configured;
+
+ /**
+ * Flag indicating wether to fork into background as a daemon
+ * or don't (good for debugging, for example).
+ * Defaults to true.
+ */
+ bool background;
+
+ /**
+ * The XML-RPC server running within the Scheduler Daemon.
+ */
+ XmlRpc::XmlRpcServer xmlRpcServer;
+
+ /**
+ * Do all the necessary tasks of becoming a daemon.
+ *
+ * @exception std::runtime_error on forking errors
+ */
+ void
+ daemonize(void) throw (std::runtime_error);
+
+ /**
+ * Save the current process id to the process id file
+ */
+ void
+ savePid(void) throw();
+
+ /**
+ * Return the saved process id.
+ *
+ * @return the saved process id of the daemon, or 0 if none saved.
+ */
+ pid_t
+ loadPid(void) throw();
+
+ protected:
+
+ /**
+ * Default constructor.
+ */
+ XmlRpcDaemon (void) throw ()
+ {
+ background = true;
+ configured = false;
+ }
+
+ /**
+ * Virtual destructor.
+ */
+ virtual
+ ~XmlRpcDaemon(void) throw ()
+ {
+ }
+
+ /**
+ * Check if the daemon has already been configured,
+ * and raise an exception if not so.
+ *
+ * @exception std::logic_error if the daemon has not yet been
+ * configured.
+ */
+ void
+ checkForConfiguration(void) const throw (std::logic_error)
+ {
+ if (!configured) {
+ throw std::logic_error("not yet configured");
+ }
+ }
+
+ /**
+ * Configure the XML-RPC daemon itself. Pass an <xmlRpcDaemon>
+ * element to this function.
+ *
+ * @param element the XML element to configure the XML-RPC
+ * daemon from.
+ * @exception std::invalid_argument if the supplied XML element
+ * contains bad configuraiton information
+ * @exception std::logic_error if the daemon has already
+ * been configured.
+ */
+ void
+ configureXmlRpcDaemon(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error);
+
+
+ /**
+ * Register your XML-RPC functions by implementing this function.
+ */
+ virtual void
+ registerXmlRpcFunctions(XmlRpc::XmlRpcServer & xmlRpcServer)
+ throw (std::logic_error)
+ = 0;
+
+ public:
+
+ /**
+ * Tell if the daemon has already been configured.
+ * If so, an attempt to configure it again will result in an
+ * exception.
+ *
+ * @return true if the daemon has already been
+ * configured, false otherwise.
+ */
+ const bool
+ isConfigured(void) const throw ()
+ {
+ return configured;
+ }
+
+ /**
+ * Set if the XML-RPC server should fork into background.
+ *
+ * @param background if true, the XML-RPC server will fork into
+ * background, otherwise not (good for debugging).
+ */
+ void
+ setBackground(const bool background) throw ()
+ {
+ this->background = background;
+ }
+
+ /**
+ * Tell if the XML-RPC server will fork into background.
+ *
+ * @return if true, the XML-RPC server will fork into
+ * background, otherwise not (good for debugging).
+ */
+ const bool
+ getBackground(void) const throw ()
+ {
+ return background;
+ }
+
+ /**
+ * Configure the daemon based on the XML element
+ * supplied.
+ * Implemtors should call the funtion configureXmlRpcDaemon
+ * from here with a proper <xmlRpcDaemon> element.
+ *
+ * @param element the XML element to configure the
+ * daemon from.
+ * @exception std::invalid_argument if the supplied XML element
+ * contains bad configuraiton information
+ * @exception std::logic_error if the daemon has already
+ * been configured.
+ * @see #configureXmlRpcDaemon
+ */
+ virtual void
+ configure(const xmlpp::Element & element)
+ throw (std::invalid_argument,
+ std::logic_error)
+ = 0;
+
+ /**
+ * Tell the host name of the XML-RPC server the
+ * daemon is listening on.
+ *
+ * @return the host name of the XML-RPC server the
+ * daemon is listening on.
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ const std::string
+ getXmlRpcHost(void) const throw (std::logic_error)
+ {
+ checkForConfiguration();
+ return xmlRpcHost;
+ }
+
+ /**
+ * Tell the port of the XML-RPC server the
+ * daemon is listening on.
+ *
+ * @return the port of the XML-RPC server the
+ * daemon is listening on.
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ const unsigned int
+ getXmlRpcPort(void) const throw (std::logic_error)
+ {
+ checkForConfiguration();
+ return xmlRpcPort;
+ }
+
+ /**
+ * Tell the file name where the daemon stores its process id.
+ *
+ * @return the name of the file where the process id is stored.
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ const std::string
+ getPidFileName(void) const throw (std::logic_error)
+ {
+ checkForConfiguration();
+ return pidFileName;
+ }
+
+ /**
+ * Start the daemon.
+ *
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ void
+ start (void) throw (std::logic_error);
+
+ /**
+ * Tell if the deamon is running.
+ *
+ * @return true of the deamon is running, false otherwise.
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ bool
+ isRunning (void) throw (std::logic_error);
+
+ /**
+ * Stop the daemon.
+ *
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ void
+ stop (void) throw (std::logic_error);
+
+ /**
+ * Shut down the daemon.
+ * This function is public only because the signal handler
+ * needs visibility to this function, which will call it.
+ *
+ * @exception std::logic_error if the daemon has not
+ * yet been configured.
+ */
+ void
+ shutdown (void) throw (std::logic_error);
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // XmlRpcDaemon_h
+
diff --git a/livesupport/products/scheduler/src/XmlRpcDaemonShutdownSignalHandler.h b/livesupport/products/scheduler/src/XmlRpcDaemonShutdownSignalHandler.h
new file mode 100644
index 000000000..845bafcb4
--- /dev/null
+++ b/livesupport/products/scheduler/src/XmlRpcDaemonShutdownSignalHandler.h
@@ -0,0 +1,111 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/XmlRpcDaemonShutdownSignalHandler.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef XmlRpcDaemonShutdownSignalHandler_h
+#define XmlRpcDaemonShutdownSignalHandler_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include "SignalHandler.h"
+#include "XmlRpcDaemon.h"
+
+
+namespace LiveSupport {
+namespace Scheduler {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ * Signal handler to shut down an XmlRpcDaemon.
+ *
+ * @author $Author: maroy $
+ * @version $Revision: 1.1 $
+ * @see XmlRpcDaemon
+ */
+class XmlRpcDaemonShutdownSignalHandler : public SignalHandler
+{
+ private:
+ /**
+ * The XmlRpcDaemon to shut down.
+ */
+ XmlRpcDaemon * xmlRpcDaemon;
+
+ public:
+ /**
+ * Constructor.
+ *
+ * @param xmlRpcDaemon the XmlRpcDaemon to shut down when the
+ * handler is invoked.
+ */
+ XmlRpcDaemonShutdownSignalHandler(
+ XmlRpcDaemon * xmlRpcDaemon)
+ throw ()
+ {
+ this->xmlRpcDaemon = xmlRpcDaemon;
+ }
+
+ /**
+ * Handle the signal. Shuts down the XmlRpcDaemon used to
+ * construct this handler.
+ *
+ * @param signal the actual signal received.
+ */
+ virtual void
+ handleSignal(int signal) throw ()
+ {
+ xmlRpcDaemon->shutdown();
+ }
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Scheduler
+} // namespace LiveSupport
+
+#endif // XmlRpcDaemonShutdownSignalHandler_h
+
diff --git a/livesupport/products/scheduler/src/main.cxx b/livesupport/products/scheduler/src/main.cxx
new file mode 100644
index 000000000..256afc579
--- /dev/null
+++ b/livesupport/products/scheduler/src/main.cxx
@@ -0,0 +1,243 @@
+/*------------------------------------------------------------------------------
+
+ Copyright (c) 2004 Media Development Loan Fund
+
+ This file is part of the LiveSupport project.
+ http://livesupport.campware.org/
+ To report bugs, send an e-mail to bugs@campware.org
+
+ LiveSupport is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ LiveSupport is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LiveSupport; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+ Author : $Author: maroy $
+ Version : $Revision: 1.1 $
+ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/main.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/** @file
+ * This file contains the main entry point to the Scheduler daemon.
+ */
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#if HAVE_UNISTD_H
+#include
+#else
+#error "Need unistd.h"
+#endif
+
+#if HAVE_GETOPT_H
+#include
+#else
+#error "Need getopt.h"
+#endif
+
+#include
+#include
+#include
+#include
+
+#include "SchedulerDaemon.h"
+
+
+using namespace LiveSupport::Scheduler;
+
+/* =================================================== local data structures */
+
+
+/* ================================================ local constants & macros */
+
+/**
+ * Our copyright notice, should be at most 80 columns
+ */
+static const char copyrightNotice[] =
+ "Copyright (c) 2004 Media Development Loan Fund under the GNU GPL";
+
+/**
+ * String describing the short options.
+ */
+static const char options[] = "c:dhv";
+
+/**
+ * Structure describing the long options
+ */
+static const struct option longOptions[] = {
+ { "config", required_argument, 0, 'c' },
+ { "debug", no_argument, 0, 'd' },
+ { "help", no_argument, 0, 'h' },
+ { "version", no_argument, 0, 'v' },
+ { 0, 0, 0, 0 }
+};
+
+/**
+ * The start command: "start"
+ */
+static const std::string startCommand = "start";
+
+/**
+ * The status command: "status"
+ */
+static const std::string statusCommand = "status";
+
+/**
+ * The stop command: "stop"
+ */
+static const std::string stopCommand = "stop";
+
+
+/* =============================================== local function prototypes */
+
+/**
+ * Print program version.
+ *
+ * @param os the std::ostream to print to.
+ */
+static void
+printVersion ( std::ostream & os );
+
+/**
+ * Print program usage information.
+ *
+ * @param invocation the command line command used to invoke this program.
+ * @param os the std::ostream to print to.
+ */
+static void
+printUsage ( const char invocation[],
+ std::ostream & os );
+
+
+/* ============================================================= module code */
+
+/**
+ * Program entry point.
+ *
+ * @param argc the number of command line arguments passed by the user.
+ * @param argv the command line arguments passed by the user.
+ * @return 0 on success, non-0 on failure.
+ */
+int main ( int argc,
+ char * argv[] )
+{
+ int i;
+ std::string configFileName;
+ bool debugMode = false;
+
+ while ((i = getopt_long(argc, argv, options, longOptions, 0)) != -1) {
+ switch (i) {
+ case 'c':
+ configFileName = optarg;
+ break;
+
+ case 'd':
+ debugMode = true;
+ break;
+
+ case 'h':
+ printUsage(argv[0], std::cout);
+ return 0;
+
+ case 'v':
+ printVersion(std::cout);
+ return 0;
+
+ default:
+ printUsage(argv[0], std::cout);
+ return 1;
+ }
+ }
+
+ if (optind != argc - 1) {
+ printUsage(argv[0], std::cout);
+ return 1;
+ }
+
+ std::cerr << "using config file '" << configFileName << '\'' << std::endl;
+
+ SchedulerDaemon * daemon = SchedulerDaemon::getInstance();
+
+ try {
+ std::auto_ptr
+ parser(new xmlpp::DomParser(configFileName, true));
+ const xmlpp::Document * document = parser->get_document();
+ daemon->configure(*(document->get_root_node()));
+ } catch (std::invalid_argument &e) {
+ std::cerr << "semantic error in configuration file" << std::endl
+ << e.what() << std::endl;
+ return 1;
+ } catch (xmlpp::exception &e) {
+ std::cerr << "error parsing configuration file" << std::endl
+ << e.what() << std::endl;
+ return 1;
+ }
+
+ daemon->setBackground(!debugMode);
+
+ if (startCommand == argv[optind]) {
+ daemon->start();
+ } else if (statusCommand == argv[optind]) {
+ std::cout << "The Scheduler Daemon is "
+ << (daemon->isRunning() ? "" : "not ")
+ << "running" << std::endl;
+ } else if (stopCommand == argv[optind]) {
+ daemon->stop();
+ } else {
+ printUsage(argv[0], std::cout);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Print program version.
+ *----------------------------------------------------------------------------*/
+static void
+printVersion ( std::ostream & os )
+{
+ os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
+ << copyrightNotice << std::endl;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Print program usage.
+ *----------------------------------------------------------------------------*/
+static void
+printUsage ( const char invocation[],
+ std::ostream & os )
+{
+ os << PACKAGE_NAME << ' ' << PACKAGE_VERSION << std::endl
+ << std::endl
+ << "Usage: " << invocation << " [OPTION] COMMAND"
+ << std::endl
+ << " COMMAND is one of: start, stop or status" << std::endl
+ << std::endl
+ << " mandatory options:" << std::endl
+ << " -c, --config=file.name scheduler configuration file" << std::endl
+ << " optional options:" << std::endl
+ << " -d, --debug don't fork into background" << std::endl
+ << " -h, --help display this help and exit" << std::endl
+ << " -v, --version display version information and exit"
+ << std::endl
+ << std::endl
+ << "Report bugs to " << PACKAGE_BUGREPORT << std::endl;
+}
+
diff --git a/livesupport/products/scheduler/tmp/.keepme b/livesupport/products/scheduler/tmp/.keepme
new file mode 100644
index 000000000..e0808fa16
--- /dev/null
+++ b/livesupport/products/scheduler/tmp/.keepme
@@ -0,0 +1 @@
+keep me