From a5b4dd625ed4afcc64ce5045434a3752e52612c4 Mon Sep 17 00:00:00 2001 From: fgerlits Date: Fri, 15 Oct 2004 16:48:44 +0000 Subject: [PATCH] added new removeAudioClipFromPlaylist and validatePlaylist modified the contract for removeAudioClipFromPlaylist to take a relative offset as argument instead of an audio clip id (makes more sense this way, also implements more neatly :-) --- livesupport/doc/model/Scheduler/index.html | 9996 ++++++++++------- .../core/include/LiveSupport/Core/Playlist.h | 49 +- livesupport/modules/core/src/Playlist.cxx | 47 +- livesupport/modules/core/src/PlaylistTest.cxx | 38 +- livesupport/modules/core/src/PlaylistTest.h | 8 +- .../scheduler/doc/model/SchedulerModel.zuml | Bin 102546 -> 116449 bytes .../products/scheduler/etc/Makefile.in | 8 +- .../src/AddAudioClipToPlaylistMethod.cxx | 32 +- .../src/AddAudioClipToPlaylistMethod.h | 16 +- .../src/AddAudioClipToPlaylistMethodTest.cxx | 4 +- .../src/RemoveAudioClipFromPlaylistMethod.cxx | 163 + .../src/RemoveAudioClipFromPlaylistMethod.h | 154 + .../RemoveAudioClipFromPlaylistMethodTest.cxx | 175 + .../RemoveAudioClipFromPlaylistMethodTest.h | 135 + .../scheduler/src/ValidatePlaylistMethod.cxx | 146 + .../scheduler/src/ValidatePlaylistMethod.h | 154 + .../src/ValidatePlaylistMethodTest.cxx | 180 + .../src/ValidatePlaylistMethodTest.h | 135 + .../products/scheduler/src/XmlRpcTools.cxx | 22 +- .../products/scheduler/src/XmlRpcTools.h | 19 +- 20 files changed, 7217 insertions(+), 4264 deletions(-) create mode 100644 livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.cxx create mode 100644 livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.h create mode 100644 livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.cxx create mode 100644 livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.h create mode 100644 livesupport/products/scheduler/src/ValidatePlaylistMethod.cxx create mode 100644 livesupport/products/scheduler/src/ValidatePlaylistMethod.h create mode 100644 livesupport/products/scheduler/src/ValidatePlaylistMethodTest.cxx create mode 100644 livesupport/products/scheduler/src/ValidatePlaylistMethodTest.h diff --git a/livesupport/doc/model/Scheduler/index.html b/livesupport/doc/model/Scheduler/index.html index f8ea22bfd..b19fa7456 100644 --- a/livesupport/doc/model/Scheduler/index.html +++ b/livesupport/doc/model/Scheduler/index.html @@ -1,4211 +1,5785 @@ - - - - - LiveSupport Scheduler specifications - - - -

Preface

-This document is part of the LiveSupport -project, Copyright © 2004 Media -Development Loan Fund, under the GNU GPL.
- -

Scope

-This document contains the specification of the LiveSupport Scheduler -daemon.
-
-This document contains embedded SVG figures, thus an SVG -capable browser is needed to view it, or an SVG plugin like Adobe's SVG Viewer.
-

Requirements

-

Overview
-

-The purpose of the LiveSupport Scheduler daemon is to execute -playlists.
-

Goals
-

-The scheduler daemon is a remotely accessible service accepting -playlists on a local audio interface. Specific goals include:
- -

System functions

-The main system functions are described below. There are three -categories for these functions:
- - - - - - - - - - - - - - - - - - - -
function category
-
meaning
-
evident
-
Should perform, and the user should be cognizant -that it is performed
-
hidden
-
Should perform, but not visible to the users.
-
frill
-
Optional
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref#
-
function
-
category
-
F1.1
-
Accept uploaded playlists
-
evident
-
F1.2
-
Retrieve remote files referenced by playlists
-
hidden
-
F1.3
-
Access local files
-
hidden
-
F1.4
-
Provide status information
-
evident
-
F1.5
-
Log playlist execution for proof of broadcast -reasons
-
evident
-
F1.6
-
Purge local file storage of unused audio clips
-
hidden
-
F1.7
-
Execute playlists
-
evident
-
F1.8
-
Play live streams as part of the playlist
-
hidden
-
F1.9
-
Remove playists from the schedule
-
evident
-
F1.10
-
Re-schedule playlsits
-
evident
-
F1.11
-
Delete playlists
-
evident
-
F1.12
-
Create playlists
-
evident
-
F1.13
-
Edit playlists
-
evident
-
F1.14
-
Start the scheduler daemon
-
evident
-
F1.15
-
Stop the scheduler daemon
-
evident
-

-

-

-
-
-

System attributes

-Generic attributes
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref#
-
attribute
-
details and constraints
-
category
-
A1.1
-
operating system platform
-
Linux
-
must
-
A1.2
-
supported audio interfaces
-
ALSA (maybe also OSS?)
-
must
-
A1.3
-
supported playlist format
-
SMIL 2.0. only partial support is required, -which focuses only on audio aspects of SMIL.
-
must
-
A1.4
-
supported audio clip formats
-
Ogg Vorbis, mp3, wav
-
must
-

-

-

-

-
-
-Attributes related to system functions
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref#
-
function
-
ref#
-
attribute
-
details and constraints
-
category
-
F1.7
-
Execute playlists
-
A1.5
-
low latency
-
when executing playlists, very low latency -should be achieved
-
must
-

-

-
A1.6
-
handle time skew
-
the -daemon has to take into account that the system's clock is not -accurate. the clock is synchronized to an external regularly, but the -resulting time-jump must be handled.
-
must
-
F1.8
-
Play live streams as part of the playlist A1.7
-
supported audio stream formats
-
Ogg Vorbis via HTTP, mp3 via HTTP
-
must
-
F1.14
-F1.15
-
Start / stop the scheduler daemon
-
A1.8
-
provide System V init style services
-
Provide a System V init interface to starting -and stopping the scheduler daemon
-
must
-

-

-

-

-

-

-
-
-

Essential use cases

-This section lists generic (essential) uses cases, that do not contain -architecture-specific considerations.
-
- -

UC-1 Upload playlist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-1
use case Upload playlist
type primary, essential
actors Playlist editor
purpose Upload a playlist
overview The Playlist editor uploads a new playlist.
references F1.1
-

Typical course of events

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Playlist editor connects to the scheduler daemon -with the intent of uploading a new playlist.
-

-

-
2. The Playlist editor provides authentication -information 3. The system authenticates the Playlist editor and -grants access.
4. The Playlist editor presents the new playlist -and the intended schedule for the playlist.
-
5. The system validates the new playlist, and sees -that it does not conflict with existing schedule.

-

-
6. The system stores the new playlist, adds it to -the schedule, and sends confirmation to the Playlist editor.
7. The Playlist editor receives confirmation and -disconnects.
-

-

-

-

-

-
-
-

Alternate courses

- -

UC-2 Manage schedule
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref#
-
UC-2
use case Manage schedule
type
-
primary, essential
actors
-
Playlist editor
purpose
-
View the schedule and remove or re-schedule -playlists
-
overview
-
The Playlist editor reviews the schedule. If he -decides to, he might remove or re-schedule some of these playlists.
references
-
F1.4, F1.9, F1.10
-
-
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Playlist editor connects to the scheduler daemon -with the intent of viewing and editing the schedule.
-

-

-
2. The Playlist editor provides authentication -information 3. The system authenticates the Playlist editor and -grants access.

-

-
4.
-
The system shows the Schedule to the Playlist -editor
-
5.
-
The Playlist editor browses the Schedule, -selects a playlist for detailed viewing.
-
6.
-
The system shows the details of the selected -Playlist.
-
7.
-
The playlist editor removes a playlist from the -schedule.
-
8.
-
The system removes the playlist from the -schedule, than re-displays the updated schedle.
-
9.
-
The Playlist editor re-schedules a playlist
-
10.
-
The system removes the selected playlist from -the schedule, and re-enters it at a new timepoint
-
11.
-
The Playlist editor browses the Schedule
-
12.
-
The system shows the Schedule to the playlist -editor
-
13.
-
The Playlist editor disconnects.
-

-

-
-
-

Alternate courses

- -

UC-3 Manage playlists
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref#
-
UC-3
use case Manage playlists
type
-
primary, essential
actors
-
Playlist editor
purpose
-
View and delete playlists
overview
-
The Playlist editor reviews the uploaded -playlists. If he decides so, he might delete some of these playlists.
references
-
F1.4, F1.11
-
-
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Playlist editor connects to the scheduler daemon -with the intent of viewing and deleting playlists.
-

-

-
2. The Playlist editor provides authentication -information 3. The system authenticates the Playlist editor and -grants access.

-

-
4.
-
The system lists the available Playlists
-
5.
-
The Playlist editor browses the playlists, and -selects one for detailed viewing.
-
6.
-
The system shows the details of the selected -Playlist.
-
7.
-
The playlist editor deletes a playlist.
-
8.
-
The system deletes the playlist, than -re-displays the list of available Playlists.
-
9.
-
The Playlist editor disconnects.
-

-

-
-
-

Alternate courses

- -

UC-4 Retrieve remote files
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-4
use case Retrieve remote files
type
-
primary, essential
actors
-
(internal actor, initiator), Media archive, -Local storage
-
purpose
-
Retrieve remote files referenced by active -playlists and store them in the local storage
-
overview
-
The -daemon contacts the remote media archive and retrieves audio clips -referenced by active playlists. The clips are stored locally for -playing.
references
-
F1.2
-
-Note that this use case is somewhat reversed, as it is initiated by the -system (not an actor), and the main tasks are done by an external actor -(the Media archive).
-

Typical course of events

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. An Internal actor triggers the retrieval of some -remote files.
-
2. The system looks up the URN of the remote file, -and determines the Media archive to contact regarding the file.

-

-
3.
-
The system contacts the Local storage and sends -authorization information
-
4.
-
Local storage authenticates the system and -grants access
-
5.
-
The system iniquires the local storage about the -availability of the file to download in the Local storage by presenting -its unique ID
-
6.
-
Local storage tells if the required file is -already stored or not.
-
7.
-
If the file is available in the local storage, -the use case ends. Otherwise, it continues.
-

-

-
8.
-
The system contacts the Media archive and sends -authorization information
9. Media archive authenticates the system and -grants access 10. The system requests an audio clip by presenting -its unique ID
11. Media archive looks up the file, and presents it -to the system 12. The system retrieves the file and closes the -connection to the Media archive
-

-

-
13.
-
The system presents the file to Local storage
-
14.
-
Local storage stores the file under the -specified unique ID
-
15.
-
The system closes the connection to Local -storage.
-

-

-

-

-
-
-

Alternate courses

- -

UC-5 Review play log
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-5
use case Review play log
type secondary, essential
actors Broadcast auditor
purpose Review what has been played
overview The -Broadcast auditor reviews the audio clips that have been played in a -selected time interval. He may generate reports for proof of broadcast -reasons.
references F1.4
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Broadcast auditor connects to the scheduler -daemon with the intent of reviewing what has been played.
-

-

-
2. The Broadcast auditor provides authentication -information 3. The system authenticates the Broadcast auditor -and grants access.
3.
-
The Broadcast auditor browses through the play -log in a time-ordered manner.
-
4.
-
The system displays the play log entries.
-
5.
-
The Broadcast auditor requests a play report for -a given time period.
-
6.
-
The system displays the requested report.
-
7.
-
The Broadcast auditor disconnects.
-

-

-

-

-

-

-
-
-

Alternate courses

- -
-

UC-6 Create playlist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-6
use case Create playlist
-
type secondary, essential
actors Playlist editor
-
purpose Create a new playlist, and then edit it.
-
overview The Playlist editor connects to the Scheduler -with the aim of creating a new playlist. A basic user interface is -provided, which allows professionals to create and edit the playlsits -on the system.
-
references F1.12, F1.13
-
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Playlist editor connects to the scheduler with -the intent of creating a new playlist.
-

-

-
2. The Playlist editor provides authentication -information 3. The system authenticates the Playlist editor and -grants access.
4.
-
The Playlist editor signals that he whishes for -a new playlist
-
5.
-
The system creates a new, empty playlist, and -opens it for editing.
-
6.
-
The Playlist editor edits the new playlist. See -UC-7 actions 7-15 for details.
-

-

-
7.
-
The Playlist editor disconnects.
-

-

-

-

-

-

-
-
-

Alternate courses

- -
-

UC-7 Edit playlist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-7
use case Edit playlist
-
type secondary, essential
actors Playlist editor
-
purpose Edit a previoulsy uploaded playlist
-
overview The Playlist editor connects to the -Scheduler with the aim of either editing an existing playlist. A basic -user interface is provided, which allows -professionals to edit the playlsits on the system.
-
references F1.12
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. Playlist editor connects to the scheduler with -the intent of editing a playlist.
-

-

-
2. The Playlist editor provides authentication -information 3. The system authenticates the Playlist editor and -grants access.

-

-
4.
-
The system lists the available playlists.
-
5.
-
The Playlist editor selects a playlist for -editing.
-
6.
-
The system opens the playlist in editing mode.
-
7.
-
The Playlist editor browses the available Audio -clips
-
8.
-
The system shows the list of available audio -clips
-
9.
-
The Playlist editor selects an Audio clip
-
10.
-
The system displays details on the audio clip.
-
11.
-
The Playlist editor ads a new audio clip to the -playlist, at a certain timepoint in the playlist.
-
12.
-
The new audio clip is added to the playlist.
-
13.
-
The Playlist editor removes an audio clip from -the playlist.
-
14.
-
The audio clip is removed from the playlist.
-
15.
-
The Playlist editor edits the fade-in or -fade-out of a clip in the playlist.
-
16.
-
The fade-in or fade-out is edited.
-
17.
-
The Playlist editor saves the playlist.
-
18.
-
The playlist is validated.
-

-

-
19.
-
The playlist is saved.
-
20.
-
The Playlist editor disconnects.
-

-

-
-
-

Alternate courses

- -
-

UC-8 Start/stop scheduler
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ref# UC-8
use case Start/stop scheduler
-
type primary, essential
actors Administrator
-
purpose Start and stop the scheduler daemon
-
overview The adminisitrator starts the scheduler deamon -by invoking a System V init-style startup script. He may also stop the -deamon with the same script.
-
references F1.14, F1.15, A1.8
-
-

Typical course of events
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
actor action
-
system response
-
1. The Administrator invokes the scheduler's System -V init script with the start parameter
-

-

-

-

-
2. The scheduler daemon starts up.
-
3.
-
The Administrator checks to see if the scheduler -daemon is running
-
4.
-
The scheduler daemon reports that it is running.
-
5.
-
The Administrator stops the scheduler deamon.
-
6.
-
The scheduler daemon stops.
-
-
-

Alternate courses

- -

Conceptual model

-The following figure displays the semantic concepts identified for the -Scheduler daemon, and the main associations between the concepts.
-
- -
-

Concepts

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
concept
-
description
-
Media archive
-
An archive external to the system, which holds -Audio clips. The archive offers its clips for download by requesting -clips based on their unique ids.
-
Clip retriever
-
Retrieves Audio clips from the Media archive and -stores them in local storage.
-
Local storage
-
A local store of Audio clips. Provides access to -each clip based on the clips' unique id. Allows random access to the -clip files.
-
Audio clip
-
A uniquely identified audio file.
-
Playlist
-
A metafile, containing references to Audio -clips, and information on how the clips should be played.
-
PlaylistElement
-
An association class describing the specifics of -an instance of an Audio clip in a playlist.
-
FadeInfo
-
A class describing fade in or fade out -characteristics for an Audio clip in a Playlist
-
Playlist store
-
A container holding a range of playlists.
-
Schedule
-
Contains Schedule entries
-
Schedule entry
-
Contains the time and details of when a playlist -should be played.
-
Scheduler daemon
-
Executes playlists at timepoints specified by -the schedule.
-
Play log
-
A logging facility, holding Play log entries.
-
Play log entry
-
A record of when an Audio clip was played.
-
Play report
-
An audit report of what Audio clips have been -played in a certain time period
-
Authentication
-
Provides authentication services
-
Playlist editor
-
An external editor, managing playlists.
-
Broadcast auditor
-
An external auditor, browsing the Play log.
-
Administrator
-
The administrator responsible for starting and -stopping the scheduler daemon.
-

-

-
-
-

Associations

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
source
-
association
-
target
-
description
-
Clip retriever
-
Retrieves clips from
-
Media archive
-

-
Media archive
-
Contains
-
Audio clip
-

-
Clip retriever
-
Stores clips in
-
Local storage
-

-
Local storage
-
Contains
-
Audio clip
-

-
Playlist
-
References by PlaylistElement
-
Audio clip
-

-
PlaylistElement
-
Fades in with
-
FadeInfo
-

-
PlaylistElement
-
Fades out with
-
FadeInfo
-

-
Playlist store
-
Contains
-
Play list
-

-
Playlist editor
-
Uploads playlist to
-
Playlist store
-

-
Playlist editor
-
Manages schedule in
-
Schedule
-
The Playlist editor schedules playlists.
-
Schedule
-
Contains
-
Schedule entry
-

-
Schedule entry
-
References
-
Playlist
-

-
Scheduler daemon
-
Executes
-
Schedule
-
The Scheduler daemon plays the scheduled -playlists.
-
Scheduler daemon
-
Logs into
-
Play log
-
The Scheduler daemon logs all the played audio -clips into the Play log for proof of broadcast purposes.
-
Play log
-
Contains
-
Play log entry
-

-
Play log
-
Generated
-
Play report
-
The play log generates reports based on Play log -entries.
-
Play log entry
-
References
-
Audio clip
-

-
Broadcast auditor
-
Browses entries from
-
Play log
-

-
Broadcast auditor
-
Requests
-
Play report
-

-
Playlist editor
-
Is authenticated by
-
Authentication
-

-
Broadcast auditor
-
Is authenticated by
-
Authentication
-

-
Administrator
-
Manages
-
Scheduler daemon
-

-

-

-

-

-
-
-

System behavior

-The behavior of the system as a whole as experienced from the outside -is discussed in this section.
-

System sequence diagrams

-System diagrams are presented for each use case below.
-

UC-1 Upload playlists

- -
-

UC-2 Manage schedule

- -
-

UC-3 Manage playlists

- -
-

UC-4 Retrieve remote files
-

- -
-

UC-5 Review play log

- -

UC-6 Create playlist

- -

UC-7 Edit playlist
- -

-

UC-8 Start/stop scheduler

- -
-
-

System objects

-The following figures shows the system objects and their functions, as -derived from the system sequence diagrams.
- -

Contracts

-For all operations exposed in the system sequence diagrams, the -following contracts are defined.
-

Contract for Scheduler : authenticate

-See Authentication : authenticate
-
-

Contract for Scheduler : uploadPlaylist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
uploadPlaylist
-(playlist : Playlist,
-playtime: Schedule)
-: UniqueId
-
Responsibilities
-
Upload a playlist and -put it into the schedule.
-
Type
-
system
-
Cross-reference
-
F1.1, UC-1
-
Notes
-

-
Exceptions
-
If the uploaded playlist -is not valid, indicate as an error
-If the proposed schedule conflicts with existing schedules, indicate as -an error
-
Output
-
the unique id of the -ScheduleEntry created with this upload
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
A new Playlist is created, storing the uploaded -playlist
-
instance creation

-
Playlist is entered into the Playlist store
-
association formed
-

-
A new Schedule is created, according to the -supplied schedule
-
instance creation
-

-
Schedule is associated with the Playlist
-
association formed
-

-

-

-
-
-

Contract for Scheduler : displaySchedule

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displaySchedule
-(from : TimeStamp,
-to : TimeStamp)
-: Schedule
-
Responsibilities
-
Display Schedule entries -for a time period.
-
Type
-
system
-
Cross-reference
-
F1.4, UC-2
-
Notes
-

-
Exceptions
-
none
-
Output
-
The Schedule entries for -the specified time period.
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : displayPlaylist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displayPlaylist
-(playlistId : UniqueId)
-: Playlist
-
Responsibilities
-
Display a specific -playlist
-
Type
-
system
-
Cross-reference
-
F1.4, UC-3
-
Notes
-

-
Exceptions
-
If no playlist exists -for the specified playlistId, indicate as an error.
-
Output
-
The requested playlist.
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : deletePlaylist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
deletePlaylist
-(playlist : Playlist)
-: void
-
Responsibilities
-
Delete a specific -playlist
-
Type
-
system
-
Cross-reference
-
F1.11, UC-3
-
Notes
-

-
Exceptions
-
If no playlist exists -for the specified playlistId, indicate as an error.
-If the playlist is referenced by any Schedule entry, indicate as an -error.
-
Output
-
none
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
The playlist is removed from the Playlist store.
-
association broken
-

-
References by the playlist to Audio clips removed
-
association broken
-

-
The playlist is deleted
-
instance deletion
-

-

-

-
-
-

Contract for Scheduler : removeFromSchedule
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
removeFromSchedule
-(scheduleEntryId : UniqueId)
-: bool
-
Responsibilities
-
Remove a specific -playlist from a schedule entry
-
Type
-
system
-
Cross-reference
-
F1.9, UC-2
-
Notes
-

-
Exceptions
-
If no ScheduleEntry by -the specified -scheduleEntryId exist, indicate as an error.
-
Output
-
true if the specified -entry was removed, false if it did not exist.
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
Reference to the playlist by the scheduleEntry -is removed.
-
association broken
-

-
The ScheduleEntry specified by the -scheduleEntryId is deleted
-
instance deletion
-

-

-

-
-
-

Contract for Scheduler : reschedule
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
reschedule
-(scheduleEntryId : UniqueId,
-playtime : TimeStamp)
-: bool
-
Responsibilities
-
Change when a certain -playlist is scheduled to play.
-
Type
-
system
-
Cross-reference
-
F1.10, UC-2
-
Notes
-

-
Exceptions
-
If no ScheduleEntry by -the specified -scheduleEntryId exist, indicate as an error.
-If the new playtime conflicts with other schedule entries, indicate as -an error.
-
Output
-
false on errors
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
The time attribute of scheduleEntry is updated -to the supplied playtime.
-
attribute modification
-

-

-

-
-
-

Contract for Scheduler : displayPlaylists

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displayPlaylists
-()
-: Playlist
-
Responsibilities
-
Display Playlists -contained in the Playlist store
-
Type
-
system
-
Cross-reference
-
F1.4, UC-3
-
Notes
-

-
Exceptions
-
none
-
Output
-
The playlists contained -in the Playlist store.
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : displayPlayLog

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displayPlayLog
-()
-: Play log
-
Responsibilities
-
Display Play log entries -contained in the Play log
-
Type
-
system
-
Cross-reference
-
F1.4, UC-5
-
Notes
-

-
Exceptions
-
none
-
Output
-
The play log entries -contained in the Play log.
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : generatePlayReport
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
generatePlayReport
-(from : TimeStamp,
-to : TimeStamp)
-: Play report
-
Responsibilities
-
Present a report on what -Audio clips have been played to the Broadcast auditor.
-
Type
-
system
-
Cross-reference
-
F1.4, UC-5
-
Notes
-

-
Exceptions
-
none
-
Output
-
A report on the played -Audio clips played in the specified time period.
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : createPlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
createPlaylist
-()
-: Playlist
-
Responsibilities
-
Create a new playlist
-
Type
-
system
-
Cross-reference
-
F1.12, UC-6
-
Notes
-
A new playlist is -created, and is immediately locked for editing.
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
A new Playlist is created
-
instance creation
-

-
The lockedForEditing attribute is set to true -for the playlist
-
attribute modification
-

-
The playlist is added to the Playlist store
-
association formed
-

-

-

-
-
-

Contract for Scheduler : openPlaylistForEditing
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
openPlaylistForEditing
-(playlist : Playlist)
-: void
-
Responsibilities
-
Open a playlist for -editing
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
A playlist is opened for -editing. The playlist may not be played when being edited. Also, active -(currently executing) playlists may not be opened for editing. This is -in effect a lock, which is released by saving the playlist.
-
Exceptions
-
if the playlist is -currently being executed, indicate as an error.
-
Output
-
none
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
The current version of the playlist is stored, -in case the user wants to revert to the last saved version (see -revertEditedPlaylist)
-
instance creation
-

-
The lockedForEditing attribute is set to true -for the playlist
-
attribute modification
-

-

-

-
-
-

Contract for Scheduler : addAudioClipToPlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
addAutioClipToPlaylist
-(playlist : Playlist,
-audioClip : AudioClip,
-relativeOffset : Time)
-: void
-
Responsibilities
-
Add an Audio clip to a -Playlist
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
The Audio clip is added -to the playlist with the specified relativeOffset from the beginning of -the Playlist.
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
the Playlist is -currently opened for editing
-
Post-conditions
-
condition
-
type
-

-
The new PlaylistElement is created associating -the playlist with the audio clip, with the specified relativeOffset
-
association formed, instnace creation
-

-

-

-
-
-

Contract for Scheduler : displayAudioClips
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displayAudioClips
-()
-: AudioClip
-
Responsibilities
-
Display the audio clips -known to the Scheduler
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
none
-
Exceptions
-
none
-
Output
-
The Audio clips kown to -the Scheduler
-
Pre-conditions
-
none
-
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : displayAudioClip
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
displayAudioClip
-(audioClipId : UniqueId)
-: AudioClip
-
Responsibilities
-
Display the audio clip -specified by the audioClipId
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
none
-
Exceptions
-
if no audio clip by the -specified id exists, indicate as an error
-
Output
-
The Audio clip specified -by the audioClipId
-
Pre-conditions
-
none
-
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : removeAudioClipFromPlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
removeAutioClipFromPlaylist
-(playlist : Playlist,
-audioClip : AudioClip)
-: void
-
Responsibilities
-
Remove an Audio clip -from a Playlist
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
The Audio clip is -removed from the Playlist.
-
Exceptions
-
If the Audio clip is not -in the playlist, indicate as an error.
-
Output
-
none
-
Pre-conditions
-
the Playlist is -currently opened for editing
-
Post-conditions
-
condition
-
type
-

-
The PlaylistElement associating the AudioClip -with the Playlist is removed, with the related FadeInfo instances
-
instance deletion, association broken
-

-

-

-
-
-

Contract for Scheduler : updateFadeInFadeOut
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
updateFadeInFadeOut
-(audioClip : AudioClip,
-playlist : Playlist)
-: void
-
Responsibilities
-
Update the fade-in and -fade-out parameters for an audio clip playing in a playlist.
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
none
-
Exceptions
-
If the Audio clip is not -in the playlist, indicate as an error.
-
Output
-
none
-
Pre-conditions
-
the Playlist is -currently opened for editing
-
Post-conditions
-
condition
-
type
-

-
The fade-in and fade-out parameters for the -audio clip in the playlist are updated
-
attribute modification
-

-

-

-
-
-

Contract for Scheduler : validatePlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
validatePlaylist
-(playlist : Playlist)
-: boolean
-
Responsibilities
-
Validate a playlist for -being complete.
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
The playlist is checked -for being complete (not containing silence) and other sanity criteria.
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
none
-
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : savePlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
savePlaylist
-(playlist : Playlist)
-: void
-
Responsibilities
-
The playlist is saved.
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
none
-
Exceptions
-
If the playlist is not -valid, indicate as an error.
-
Output
-
none
-
Pre-conditions
-
the Playlist is -currently opened for editing
-
Post-conditions
-
condition
-
type
-

-
The lockedForEditing attriubute is set to false -for the playlist
-
attribute modification
-

-
The old version of the Playlist that could have -been used for reverting is deleted (see revertEditedPlaylist)
-
instance deletion
-

-

-

-
-
-

Contract for Scheduler : revertEditedPlaylist
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
revertEditedPlaylist
-(playlist : Playlist)
-: void
-
Responsibilities
-
Changes are discarded -for a Playlist that is being edited.
-
Type
-
system
-
Cross-reference
-
F1.13, UC-7
-
Notes
-
The contents of the -playlist are reverted to the state prior to when editing began on it.
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
the Playlist is -currently opened for editing
-
Post-conditions
-
condition
-
type
-

-
The contents of the Playlist are reverted to the -last saved version. This includes deleting all created PlaylistElement -and FadeInfo instances.
-
attribute modification, instance deletion
-

-
The lockedForEditing attriubute is set to false -for the playlist
-
attribute modification
-

-

-

-
-
-

Contract for Scheduler : start
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
start
-()
-: void
-
Responsibilities
-
Starts the scheduler -daemon
-
Type
-
system
-
Cross-reference
-
F1.14, UC-8
-
Notes
-
A System V init-style -daemon starting entry point
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
The scheduler daemon is -currently not running
-
Post-conditions
-
condition
-
type
-

-
The scheduler daemon object is created
-
instance creation
-

-
All the necessary structures are created for the -deamon to run
-
instance creation
-

-

-

-
-
-

Contract for Scheduler : isRunning
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
isRunning
-()
-: boolean
-
Responsibilities
-
Tells if the scheduler -daemon is running
-
Type
-
system
-
Cross-reference
-
UC-8
-
Notes
-
A System V init-style -daemon status entry point
-
Exceptions
-
none
-
Output
-
true of the daemon is -running, false otherwise
-
Pre-conditions
-
none
-
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Scheduler : stop
-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
stop
-()
-: void
-
Responsibilities
-
Stops the scheduler -daemon
-
Type
-
system
-
Cross-reference
-
F1.15, UC-8
-
Notes
-
A System V init-style -daemon stopping entry point
-
Exceptions
-
none
-
Output
-
none
-
Pre-conditions
-
The scheduler daemon is -currently running
-
Post-conditions
-
condition
-
type
-

-
The scheduler daemon object is deleted
-
instance deletion
-

-

-

-
-
-

Contract for Media archive : authenticate

-TODO: move to Media archive spec
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
authenticate
-(authenticationInfo : AuthenticationInfo)
-: boolean
-
Responsibilities
-
Check if the provided -authentication info is recognized.
-
Type
-
interface
-
Cross-reference
-
UC-4
-
Notes
-

-
Exceptions
-
none
Output
-
true if the provided -authentication is recognized, false otherwise
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Media archive : retrieveAudioClip

-TODO: move to Media archive spec
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
retrieveAudioClip
-(clipId : UniqueId)
-: AudioClip
-
Responsibilities
-
Retrieve an AudioClip -specified by the supplied audio clip id.
-
Type
-
interface
-
Cross-reference
-
F1.2, UC-4
-
Notes
-

-
Exceptions
-
if no audio clip exists -with the supplied id, indicate as an error
-
Output
-
the requested audio clip
-
Pre-conditions
-
none
Post-conditions
-
condition
-
type
-

-
A new Audio clip is created and filled with the -contents of the retrieved audio clip
-
instance creation

-
Audio clip is entered into Local storage
-
association formed
-

-

-

-
-
-

Contract for Local storage : authenticate

-TODO: move to Local storage spec
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
authenticate
-(authenticationInfo : AuthenticationInfo)
-: boolean
-
Responsibilities
-
Check if the provided -authentication info is recognized.
-
Type
-
interface
-
Cross-reference
-
UC-4
-
Notes
-

-
Exceptions
-
none
Output
-
true if the provided -authentication is recognized, false otherwise
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Local storage : existsAudioClip

-TODO: move to Local storage spec
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
existsAudioClip
-(audioClipId : UniqueId)
-: boolean
-
Responsibilities
-
Tell if an audio clip by -the provided unique id is stored in the Local storage
-
Type
-
interface
-
Cross-reference
-
UC-4
-
Notes
-

-
Exceptions
-
none
Output
-
true if an audio clip -with the provided id exists, false otherwise
-
Pre-conditions
-
none
Post-conditions
-
none
-

-

-

-

-
-
-

Contract for Local storage : storeAudioClip

-TODO: move to Local storage spec
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
-
storeAudioClip
-(audioClip : AudioClip)
-: void
-
Responsibilities
-
Store an audio clip.
-
Type
-
interface
-
Cross-reference
-
UC-4
-
Notes
-

-
Exceptions
-
none
Output
-
none
-
Pre-conditions
-
none
Post-conditions
-
The supplied audio clip is stored in the storage.
-

-

-

-

-
-
-

Glossary

-playlist
-The playlist is a metafile, containing references to audio clips that -should be played, and details on how they should be played.
-
- - + + + + + LiveSupport Scheduler specifications + + + + + + +

Preface

+

This document is part of the LiveSupport +project, Copyright Š 2004 Media +Development Loan Fund, under the GNU GPL.

+ +

Scope

+

This document contains the specification of the LiveSupport +Scheduler daemon.

This document contains embedded SVG +figures, thus an SVG capable browser is needed to view it, or an SVG +plugin like Adobe's SVG Viewer.

+

Requirements

+

Overview

+

The purpose of the LiveSupport Scheduler daemon is to execute +playlists.

+

Goals

+

The scheduler daemon is a remotely accessible service accepting +playlists on a local audio interface. Specific goals include:

+ +

System functions

+

The main system functions are described +below. There are three categories for these functions:

+ + + + + + + + + + + + + + + + + +
+

function category

+
+

meaning

+
+

evident

+
+

Should perform, and the user should be cognizant that it is + performed

+
+

hidden

+
+

Should perform, but not visible to the users.

+
+

frill

+
+

Optional

+
+



+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref#

+
+

function

+
+

category

+
+

F1.1

+
+

Accept uploaded playlists

+
+

evident

+
+

F1.2

+
+

Retrieve remote files referenced by playlists

+
+

hidden

+
+

F1.3

+
+

Access local files

+
+

hidden

+
+

F1.4

+
+

Provide status information

+
+

evident

+
+

F1.5

+
+

Log playlist execution for proof of broadcast reasons

+
+

evident

+
+

F1.6

+
+

Purge local file storage of unused audio clips

+
+

hidden

+
+

F1.7

+
+

Execute playlists

+
+

evident

+
+

F1.8

+
+

Play live streams as part of the playlist

+
+

hidden

+
+

F1.9

+
+

Remove playists from the schedule

+
+

evident

+
+

F1.10

+
+

Re-schedule playlsits

+
+

evident

+
+

F1.11

+
+

Delete playlists

+
+

evident

+
+

F1.12

+
+

Create playlists

+
+

evident

+
+

F1.13

+
+

Edit playlists

+
+

evident

+
+

F1.14

+
+

Start the scheduler daemon

+
+

evident

+
+

F1.15

+
+

Stop the scheduler daemon

+
+

evident

+
+


+

+
+


+

+
+


+

+
+



+

+

System attributes

+

Generic attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref#

+
+

attribute

+
+

details and constraints

+
+

category

+
+

A1.1

+
+

operating system platform

+
+

Linux

+
+

must

+
+

A1.2

+
+

supported audio interfaces

+
+

ALSA (maybe also OSS?)

+
+

must

+
+

A1.3

+
+

supported playlist format

+
+

SMIL 2.0. only partial support is required, which focuses only + on audio aspects of SMIL.

+
+

must

+
+

A1.4

+
+

supported audio clip formats

+
+

Ogg Vorbis, mp3, wav

+
+

must

+
+


+

+
+


+

+
+


+

+
+


+

+
+


Attributes related to system functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref#

+
+

function

+
+

ref#

+
+

attribute

+
+

details and constraints

+
+

category

+
+

F1.7

+
+

Execute playlists

+
+

A1.5

+
+

low latency

+
+

when executing playlists, very low latency should be achieved

+
+

must

+
+


+

+
+


+

+
+

A1.6

+
+

handle time skew

+
+

the daemon has to take into account that the system's clock is + not accurate. the clock is synchronized to an external regularly, + but the resulting time-jump must be handled.

+
+

must

+
+

F1.8

+
+

Play live streams as part of the playlist +

+
+

A1.7

+
+

supported audio stream formats

+
+

Ogg Vorbis via HTTP, mp3 via HTTP

+
+

must

+
+

F1.14
F1.15

+
+

Start / stop the scheduler daemon

+
+

A1.8

+
+

provide System V init style services

+
+

Provide a System V init interface to starting and stopping the + scheduler daemon

+
+

must

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Essential use cases

+

This section lists generic (essential) uses cases, that do not +contain architecture-specific considerations.

+

UC-1 Upload playlist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-1 +

+
+

use case +

+
+

Upload playlist +

+
+

type +

+
+

primary, essential +

+
+

actors +

+
+

Playlist editor +

+
+

purpose +

+
+

Upload a playlist +

+
+

overview +

+
+

The Playlist editor uploads a new playlist. +

+
+

references +

+
+

F1.1 +

+
+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Playlist editor connects to the scheduler daemon with the + intent of uploading a new playlist. +

+
+


+

+
+


+

+
+

2. +

+
+

The Playlist editor provides authentication information +

+
+

3. +

+
+

The system authenticates the Playlist editor and grants access. +

+
+

4. +

+
+

The Playlist editor presents the new playlist and the intended + schedule for the playlist.

+
+

5. +

+
+

The system validates the new playlist, and sees that it does + not conflict with existing schedule. +

+
+


+

+
+


+

+
+

6. +

+
+

The system stores the new playlist, adds it to the schedule, + and sends confirmation to the Playlist editor. +

+
+

7. +

+
+

The Playlist editor receives confirmation and disconnects. +

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +

UC-2 Manage schedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref#

+
+

UC-2 +

+
+

use case +

+
+

Manage schedule +

+
+

type

+
+

primary, essential +

+
+

actors

+
+

Playlist editor +

+
+

purpose

+
+

View the schedule and remove or re-schedule playlists

+
+

overview

+
+

The Playlist editor reviews the schedule. If he decides to, he + might remove or re-schedule some of these playlists. +

+
+

references

+
+

F1.4, F1.9, F1.10

+
+



+

+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Playlist editor connects to the scheduler daemon with the + intent of viewing and editing the schedule.

+
+


+

+
+


+

+
+

2. +

+
+

The Playlist editor provides authentication information +

+
+

3. +

+
+

The system authenticates the Playlist editor and grants access. +

+
+


+

+
+


+

+
+

4.

+
+

The system shows the Schedule to the Playlist editor

+
+

5.

+
+

The Playlist editor browses the Schedule, selects a playlist + for detailed viewing.

+
+

6.

+
+

The system shows the details of the selected Playlist.

+
+

7.

+
+

The playlist editor removes a playlist from the schedule.

+
+

8.

+
+

The system removes the playlist from the schedule, than + re-displays the updated schedle.

+
+

9.

+
+

The Playlist editor re-schedules a playlist

+
+

10.

+
+

The system removes the selected playlist from the schedule, and + re-enters it at a new timepoint

+
+

11.

+
+

The Playlist editor browses the Schedule

+
+

12.

+
+

The system shows the Schedule to the playlist editor

+
+

13.

+
+

The Playlist editor disconnects.

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +

UC-3 Manage playlists

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref#

+
+

UC-3 +

+
+

use case +

+
+

Manage playlists +

+
+

type

+
+

primary, essential +

+
+

actors

+
+

Playlist editor +

+
+

purpose

+
+

View and delete playlists +

+
+

overview

+
+

The Playlist editor reviews the uploaded playlists. If he + decides so, he might delete some of these playlists. +

+
+

references

+
+

F1.4, F1.11

+
+



+

+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Playlist editor connects to the scheduler daemon with the + intent of viewing and deleting playlists.

+
+


+

+
+


+

+
+

2. +

+
+

The Playlist editor provides authentication information +

+
+

3. +

+
+

The system authenticates the Playlist editor and grants access. +

+
+


+

+
+


+

+
+

4.

+
+

The system lists the available Playlists

+
+

5.

+
+

The Playlist editor browses the playlists, and selects one for + detailed viewing.

+
+

6.

+
+

The system shows the details of the selected Playlist.

+
+

7.

+
+

The playlist editor deletes a playlist.

+
+

8.

+
+

The system deletes the playlist, than re-displays the list of + available Playlists.

+
+

9.

+
+

The Playlist editor disconnects.

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +

UC-4 Retrieve remote files

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-4 +

+
+

use case +

+
+

Retrieve remote files +

+
+

type

+
+

primary, essential +

+
+

actors

+
+

(internal actor, initiator), Media archive, Local storage

+
+

purpose

+
+

Retrieve remote files referenced by active playlists and store + them in the local storage

+
+

overview

+
+

The daemon contacts the remote media archive and retrieves + audio clips referenced by active playlists. The clips are stored + locally for playing. +

+
+

references

+
+

F1.2 +

+
+


Note that this use case is somewhat reversed, as it is +initiated by the system (not an actor), and the main tasks are done +by an external actor (the Media archive).

+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

An Internal actor triggers the retrieval of some remote files. +

+
+

2. +

+
+

The system looks up the URN of the remote file, and determines + the Media archive to contact regarding the file. +

+
+


+

+
+


+

+
+

3.

+
+

The system contacts the Local storage and sends authorization + information

+
+

4.

+
+

Local storage authenticates the system and grants access

+
+

5.

+
+

The system iniquires the local storage about the availability + of the file to download in the Local storage by presenting its + unique ID

+
+

6.

+
+

Local storage tells if the required file is already stored or + not.

+
+

7.

+
+

If the file is available in the local storage, the use case + ends. Otherwise, it continues.

+
+


+

+
+


+

+
+

8.

+
+

The system contacts the Media archive and sends authorization + information +

+
+

9. +

+
+

Media archive authenticates the system and grants access +

+
+

10. +

+
+

The system requests an audio clip by presenting its unique ID +

+
+

11. +

+
+

Media archive looks up the file, and presents it to the system +

+
+

12. +

+
+

The system retrieves the file and closes the connection to the + Media archive

+
+


+

+
+


+

+
+

13.

+
+

The system presents the file to Local storage

+
+

14.

+
+

Local storage stores the file under the specified unique ID

+
+

15.

+
+

The system closes the connection to Local storage.

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +

UC-5 Review play log

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-5 +

+
+

use case +

+
+

Review play log +

+
+

type +

+
+

secondary, essential +

+
+

actors +

+
+

Broadcast auditor +

+
+

purpose +

+
+

Review what has been played +

+
+

overview +

+
+

The Broadcast auditor reviews the audio clips that have been + played in a selected time interval. He may generate reports for + proof of broadcast reasons. +

+
+

references +

+
+

F1.4 +

+
+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Broadcast auditor connects to the scheduler daemon with the + intent of reviewing what has been played.

+
+


+

+
+


+

+
+

2. +

+
+

The Broadcast auditor provides authentication information +

+
+

3. +

+
+

The system authenticates the Broadcast auditor and grants + access. +

+
+

3.

+
+

The Broadcast auditor browses through the play log in a + time-ordered manner.

+
+

4.

+
+

The system displays the play log entries.

+
+

5.

+
+

The Broadcast auditor requests a play report for a given time + period.

+
+

6.

+
+

The system displays the requested report.

+
+

7.

+
+

The Broadcast auditor disconnects.

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +



+

+

UC-6 Create playlist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-6 +

+
+

use case +

+
+

Create playlist

+
+

type +

+
+

secondary, essential +

+
+

actors +

+
+

Playlist editor

+
+

purpose +

+
+

Create a new playlist, and then edit it.

+
+

overview +

+
+

The Playlist editor connects to the Scheduler with the aim of + creating a new playlist. A basic user interface is provided, which + allows professionals to create and edit the playlsits on the + system.

+
+

references +

+
+

F1.12, F1.13

+
+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Playlist editor connects to the scheduler with the intent of + creating a new playlist.

+
+


+

+
+


+

+
+

2. +

+
+

The Playlist editor provides authentication information +

+
+

3. +

+
+

The system authenticates the Playlist editor and grants access. +

+
+

4.

+
+

The Playlist editor signals that he whishes for a new playlist

+
+

5.

+
+

The system creates a new, empty playlist, and opens it for + editing.

+
+

6.

+
+

The Playlist editor edits the new playlist. See UC-7 actions + 7-15 for details.

+
+


+

+
+


+

+
+

7.

+
+

The Playlist editor disconnects.

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +



+

+

UC-7 Edit playlist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-7 +

+
+

use case +

+
+

Edit playlist

+
+

type +

+
+

secondary, essential +

+
+

actors +

+
+

Playlist editor

+
+

purpose +

+
+

Edit a previoulsy uploaded playlist

+
+

overview +

+
+

The Playlist editor connects to the Scheduler with the aim of + either editing an existing playlist. A basic user interface is + provided, which allows professionals to edit the playlsits on the + system.

+
+

references +

+
+

F1.12 +

+
+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

Playlist editor connects to the scheduler with the intent of + editing a playlist.

+
+


+

+
+


+

+
+

2. +

+
+

The Playlist editor provides authentication information +

+
+

3. +

+
+

The system authenticates the Playlist editor and grants access. +

+
+


+

+
+


+

+
+

4.

+
+

The system lists the available playlists.

+
+

5.

+
+

The Playlist editor selects a playlist for editing.

+
+

6.

+
+

The system opens the playlist in editing mode.

+
+

7.

+
+

The Playlist editor browses the available Audio clips

+
+

8.

+
+

The system shows the list of available audio clips

+
+

9.

+
+

The Playlist editor selects an Audio clip

+
+

10.

+
+

The system displays details on the audio clip.

+
+

11.

+
+

The Playlist editor ads a new audio clip to the playlist, at a + certain timepoint in the playlist.

+
+

12.

+
+

The new audio clip is added to the playlist.

+
+

13.

+
+

The Playlist editor removes an audio clip from the playlist.

+
+

14.

+
+

The audio clip is removed from the playlist.

+
+

15.

+
+

The Playlist editor edits the fade-in or fade-out of a clip in + the playlist.

+
+

16.

+
+

The fade-in or fade-out is edited.

+
+

17.

+
+

The Playlist editor saves the playlist.

+
+

18.

+
+

The playlist is validated.

+
+


+

+
+


+

+
+

19.

+
+

The playlist is saved.

+
+

20.

+
+

The Playlist editor disconnects.

+
+


+

+
+


+

+
+



+

+

Alternate courses

+ +



+

+

UC-8 Start/stop scheduler

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

ref# +

+
+

UC-8 +

+
+

use case +

+
+

Start/stop scheduler

+
+

type +

+
+

primary, essential +

+
+

actors +

+
+

Administrator

+
+

purpose +

+
+

Start and stop the scheduler daemon

+
+

overview +

+
+

The adminisitrator starts the scheduler deamon by invoking a + System V init-style startup script. He may also stop the deamon + with the same script.

+
+

references +

+
+

F1.14, F1.15, A1.8

+
+

Typical course of events

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

actor action +

+
+

system response +

+
+

1. +

+
+

The Administrator invokes the scheduler's System V init script + with the start parameter

+
+


+

+
+


+

+
+


+

+
+


+

+
+

2. +

+
+

The scheduler daemon starts up.

+
+

3.

+
+

The Administrator checks to see if the scheduler daemon is + running

+
+

4.

+
+

The scheduler daemon reports that it is running.

+
+

5.

+
+

The Administrator stops the scheduler deamon.

+
+

6.

+
+

The scheduler daemon stops.

+
+



+

+

Alternate courses

+ +

Conceptual model

+

The following figure displays the semantic concepts identified for +the Scheduler daemon, and the main associations between the +concepts.


+

+

Concepts

+


+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

concept

+
+

description

+
+

Media archive

+
+

An archive external to the system, which holds Audio clips. The + archive offers its clips for download by requesting clips based on + their unique ids.

+
+

Clip retriever

+
+

Retrieves Audio clips from the Media archive and stores them in + local storage.

+
+

Local storage

+
+

A local store of Audio clips. Provides access to each clip + based on the clips' unique id. Allows random access to the clip + files.

+
+

Audio clip

+
+

A uniquely identified audio file.

+
+

Playlist

+
+

A metafile, containing references to Audio clips, and + information on how the clips should be played.

+
+

PlaylistElement

+
+

An association class describing the specifics of an instance of + an Audio clip in a playlist.

+
+

FadeInfo

+
+

A class describing fade in or fade out characteristics for an + Audio clip in a Playlist

+
+

Playlist store

+
+

A container holding a range of playlists.

+
+

Schedule

+
+

Contains Schedule entries

+
+

Schedule entry

+
+

Contains the time and details of when a playlist should be + played.

+
+

Scheduler daemon

+
+

Executes playlists at timepoints specified by the schedule.

+
+

Play log

+
+

A logging facility, holding Play log entries.

+
+

Play log entry

+
+

A record of when an Audio clip was played.

+
+

Play report

+
+

An audit report of what Audio clips have been played in a + certain time period

+
+

Authentication

+
+

Provides authentication services

+
+

Playlist editor

+
+

An external editor, managing playlists.

+
+

Broadcast auditor

+
+

An external auditor, browsing the Play log.

+
+

Administrator

+
+

The administrator responsible for starting and stopping the + scheduler daemon.

+
+


+

+
+


+

+
+



+

+

Associations

+


+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

source

+
+

association

+
+

target

+
+

description

+
+

Clip retriever

+
+

Retrieves clips from

+
+

Media archive

+
+


+

+
+

Media archive

+
+

Contains

+
+

Audio clip

+
+


+

+
+

Clip retriever

+
+

Stores clips in

+
+

Local storage

+
+


+

+
+

Local storage

+
+

Contains

+
+

Audio clip

+
+


+

+
+

Playlist

+
+

References by PlaylistElement

+
+

Audio clip

+
+


+

+
+

PlaylistElement

+
+

Fades in with

+
+

FadeInfo

+
+


+

+
+

PlaylistElement

+
+

Fades out with

+
+

FadeInfo

+
+


+

+
+

Playlist store

+
+

Contains

+
+

Play list

+
+


+

+
+

Playlist editor

+
+

Uploads playlist to

+
+

Playlist store

+
+


+

+
+

Playlist editor

+
+

Manages schedule in

+
+

Schedule

+
+

The Playlist editor schedules playlists.

+
+

Schedule

+
+

Contains

+
+

Schedule entry

+
+


+

+
+

Schedule entry

+
+

References

+
+

Playlist

+
+


+

+
+

Scheduler daemon

+
+

Executes

+
+

Schedule

+
+

The Scheduler daemon plays the scheduled playlists.

+
+

Scheduler daemon

+
+

Logs into

+
+

Play log

+
+

The Scheduler daemon logs all the played audio clips into the + Play log for proof of broadcast purposes.

+
+

Play log

+
+

Contains

+
+

Play log entry

+
+


+

+
+

Play log

+
+

Generated

+
+

Play report

+
+

The play log generates reports based on Play log entries.

+
+

Play log entry

+
+

References

+
+

Audio clip

+
+


+

+
+

Broadcast auditor

+
+

Browses entries from

+
+

Play log

+
+


+

+
+

Broadcast auditor

+
+

Requests

+
+

Play report

+
+


+

+
+

Playlist editor

+
+

Is authenticated by

+
+

Authentication

+
+


+

+
+

Broadcast auditor

+
+

Is authenticated by

+
+

Authentication

+
+


+

+
+

Administrator

+
+

Manages

+
+

Scheduler daemon

+
+


+

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

System behavior

+

The behavior of the system as a whole as experienced from the +outside is discussed in this section.

+

System sequence diagrams

+

System diagrams are presented for each use case below.

+

UC-1 Upload playlists

+



+

+

UC-2 Manage schedule

+



+

+

UC-3 Manage playlists

+



+

+

UC-4 Retrieve remote files

+



+

+

UC-5 Review play log

+

UC-6 Create playlist

+

UC-7 Edit playlist

+

UC-8 Start/stop scheduler

+



+

+

System objects

+

The following figures shows the system objects and their +functions, as derived from the system sequence diagrams.

+

Contracts

+

For all operations exposed in the system sequence diagrams, the +following contracts are defined.

+

Contract for Scheduler : authenticate

+

See Authentication : authenticate

+

Contract for Scheduler : uploadPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

uploadPlaylist
(playlist : Playlist,
playtime: + Schedule)
: UniqueId

+
+

Responsibilities

+
+

Upload a playlist and put it into the schedule.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.1, UC-1

+
+

Notes

+
+


+

+
+

Exceptions

+
+

If the uploaded playlist is not valid, indicate as an error
If + the proposed schedule conflicts with existing schedules, indicate + as an error

+
+

Output

+
+

the unique id of the ScheduleEntry created with this upload

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

A new Playlist is created, storing the uploaded playlist

+
+

instance creation +

+
+


+

+
+

Playlist is entered into the Playlist store

+
+

association formed

+
+


+

+
+

A new Schedule is created, according to the supplied schedule

+
+

instance creation

+
+


+

+
+

Schedule is associated with the Playlist

+
+

association formed

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displaySchedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displaySchedule
(from : TimeStamp,
to : TimeStamp)
: + Schedule

+
+

Responsibilities

+
+

Display Schedule entries for a time period.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.4, UC-2

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

The Schedule entries for the specified time period.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displayPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displayPlaylist
(playlistId : UniqueId)
: Playlist

+
+

Responsibilities

+
+

Display a specific playlist

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.4, UC-3

+
+

Notes

+
+


+

+
+

Exceptions

+
+

If no playlist exists for the specified playlistId, indicate as + an error.

+
+

Output

+
+

The requested playlist.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : deletePlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

deletePlaylist
(playlist : Playlist)
: void

+
+

Responsibilities

+
+

Delete a specific playlist

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.11, UC-3

+
+

Notes

+
+


+

+
+

Exceptions

+
+

If no playlist exists for the specified playlistId, indicate as + an error.
If the playlist is referenced by any Schedule entry, + indicate as an error.

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The playlist is removed from the Playlist store.

+
+

association broken

+
+


+

+
+

References by the playlist to Audio clips removed

+
+

association broken

+
+


+

+
+

The playlist is deleted

+
+

instance deletion

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : removeFromSchedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

removeFromSchedule
(scheduleEntryId : UniqueId)
: bool

+
+

Responsibilities

+
+

Remove a specific playlist from a schedule entry

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.9, UC-2

+
+

Notes

+
+


+

+
+

Exceptions

+
+

If no ScheduleEntry by the specified scheduleEntryId exist, + indicate as an error.

+
+

Output

+
+

true if the specified entry was removed, false if it did not + exist.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

Reference to the playlist by the scheduleEntry is removed.

+
+

association broken

+
+


+

+
+

The ScheduleEntry specified by the scheduleEntryId is deleted

+
+

instance deletion

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : reschedule

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

reschedule
(scheduleEntryId : UniqueId,
playtime : + TimeStamp)
: bool

+
+

Responsibilities

+
+

Change when a certain playlist is scheduled to play.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.10, UC-2

+
+

Notes

+
+


+

+
+

Exceptions

+
+

If no ScheduleEntry by the specified scheduleEntryId exist, + indicate as an error.
If the new playtime conflicts with other + schedule entries, indicate as an error.

+
+

Output

+
+

false on errors

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The time attribute of scheduleEntry is updated to the supplied + playtime.

+
+

attribute modification

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displayPlaylists

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displayPlaylists
()
: Playlist

+
+

Responsibilities

+
+

Display Playlists contained in the Playlist store

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.4, UC-3

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

The playlists contained in the Playlist store.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displayPlayLog

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displayPlayLog
()
: Play log

+
+

Responsibilities

+
+

Display Play log entries contained in the Play log

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.4, UC-5

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

The play log entries contained in the Play log.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : generatePlayReport

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

generatePlayReport
(from : TimeStamp,
to : TimeStamp)
: + Play report

+
+

Responsibilities

+
+

Present a report on what Audio clips have been played to the + Broadcast auditor.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.4, UC-5

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

A report on the played Audio clips played in the specified time + period.

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : createPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

createPlaylist
()
: Playlist

+
+

Responsibilities

+
+

Create a new playlist

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.12, UC-6

+
+

Notes

+
+

A new playlist is created, and is immediately locked for + editing.

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

A new Playlist is created

+
+

instance creation

+
+


+

+
+

The lockedForEditing attribute is set to true for the playlist

+
+

attribute modification

+
+


+

+
+

The playlist is added to the Playlist store

+
+

association formed

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : openPlaylistForEditing

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

openPlaylistForEditing
(playlist : Playlist)
: void

+
+

Responsibilities

+
+

Open a playlist for editing

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

A playlist is opened for editing. The playlist may not be + played when being edited. Also, active (currently executing) + playlists may not be opened for editing. This is in effect a lock, + which is released by saving the playlist.

+
+

Exceptions

+
+

if the playlist is currently being executed, indicate as an + error.

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The current version of the playlist is stored, in case the user + wants to revert to the last saved version (see + revertEditedPlaylist)

+
+

instance creation

+
+


+

+
+

The lockedForEditing attribute is set to true for the playlist

+
+

attribute modification

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : addAudioClipToPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

addAutioClipToPlaylist
(playlist : Playlist,
audioClip : + AudioClip,
relativeOffset : Time)
: void

+
+

Responsibilities

+
+

Add an Audio clip to a Playlist

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

The Audio clip is added to the playlist with the specified + relativeOffset from the beginning of the Playlist.

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

the Playlist is currently opened for editing

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The new PlaylistElement is created associating the playlist + with the audio clip, with the specified relativeOffset

+
+

association formed, instnace creation

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displayAudioClips

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displayAudioClips
()
: AudioClip

+
+

Responsibilities

+
+

Display the audio clips known to the Scheduler

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

none

+
+

Exceptions

+
+

none

+
+

Output

+
+

The Audio clips kown to the Scheduler

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : displayAudioClip

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

displayAudioClip
(audioClipId : UniqueId)
: AudioClip

+
+

Responsibilities

+
+

Display the audio clip specified by the audioClipId

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

none

+
+

Exceptions

+
+

if no audio clip by the specified id exists, indicate as an + error

+
+

Output

+
+

The Audio clip specified by the audioClipId

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : removeAudioClipFromPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

removeAutioClipFromPlaylist
(playlist : + Playlist,
relativeOffset: Time)
: void

+
+

Responsibilities

+
+

Remove an Audio clip at the given relative offset from a + Playlist

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

The Audio clip is removed from the Playlist.

+
+

Exceptions

+
+

If there is no Audio clip at the specified relative offset in + the playlist, indicate as an error.

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

the Playlist is currently opened for editing

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The PlaylistElement associating the AudioClip with the Playlist + is removed, with the related FadeInfo instances

+
+

instance deletion, association broken

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : updateFadeInFadeOut

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

updateFadeInFadeOut
(audioClip : AudioClip,
playlist : + Playlist)
: void

+
+

Responsibilities

+
+

Update the fade-in and fade-out parameters for an audio clip + playing in a playlist.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

none

+
+

Exceptions

+
+

If the Audio clip is not in the playlist, indicate as an error.

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

the Playlist is currently opened for editing

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The fade-in and fade-out parameters for the audio clip in the + playlist are updated

+
+

attribute modification

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : validatePlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

validatePlaylist
(playlist : Playlist)
: boolean

+
+

Responsibilities

+
+

Validate a playlist for being complete.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

The playlist is checked for being complete (not containing + silence) and other sanity criteria.

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : savePlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

savePlaylist
(playlist : Playlist)
: void

+
+

Responsibilities

+
+

The playlist is saved.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

none

+
+

Exceptions

+
+

If the playlist is not valid, indicate as an error.

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

the Playlist is currently opened for editing

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The lockedForEditing attriubute is set to false for the + playlist

+
+

attribute modification

+
+


+

+
+

The old version of the Playlist that could have been used for + reverting is deleted (see revertEditedPlaylist)

+
+

instance deletion

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : revertEditedPlaylist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

revertEditedPlaylist
(playlist : Playlist)
: void

+
+

Responsibilities

+
+

Changes are discarded for a Playlist that is being edited.

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.13, UC-7

+
+

Notes

+
+

The contents of the playlist are reverted to the state prior to + when editing began on it.

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

the Playlist is currently opened for editing

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The contents of the Playlist are reverted to the last saved + version. This includes deleting all created PlaylistElement and + FadeInfo instances.

+
+

attribute modification, instance deletion

+
+


+

+
+

The lockedForEditing attriubute is set to false for the + playlist

+
+

attribute modification

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : start

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

start
()
: void

+
+

Responsibilities

+
+

Starts the scheduler daemon

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.14, UC-8

+
+

Notes

+
+

A System V init-style daemon starting entry point

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

The scheduler daemon is currently not running

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The scheduler daemon object is created

+
+

instance creation

+
+


+

+
+

All the necessary structures are created for the deamon to run

+
+

instance creation

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : isRunning

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

isRunning
()
: boolean

+
+

Responsibilities

+
+

Tells if the scheduler daemon is running

+
+

Type

+
+

system

+
+

Cross-reference

+
+

UC-8

+
+

Notes

+
+

A System V init-style daemon status entry point

+
+

Exceptions

+
+

none

+
+

Output

+
+

true of the daemon is running, false otherwise

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Scheduler : stop

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

stop
()
: void

+
+

Responsibilities

+
+

Stops the scheduler daemon

+
+

Type

+
+

system

+
+

Cross-reference

+
+

F1.15, UC-8

+
+

Notes

+
+

A System V init-style daemon stopping entry point

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

The scheduler daemon is currently running

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

The scheduler daemon object is deleted

+
+

instance deletion

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Media archive : authenticate

+

TODO: move to Media archive spec

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

authenticate
(authenticationInfo : AuthenticationInfo)
: + boolean

+
+

Responsibilities

+
+

Check if the provided authentication info is recognized.

+
+

Type

+
+

interface

+
+

Cross-reference

+
+

UC-4

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

true if the provided authentication is recognized, false + otherwise

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Media archive : retrieveAudioClip

+

TODO: move to Media archive spec

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

retrieveAudioClip
(clipId : UniqueId)
: AudioClip

+
+

Responsibilities

+
+

Retrieve an AudioClip specified by the supplied audio clip id.

+
+

Type

+
+

interface

+
+

Cross-reference

+
+

F1.2, UC-4

+
+

Notes

+
+


+

+
+

Exceptions

+
+

if no audio clip exists with the supplied id, indicate as an + error

+
+

Output

+
+

the requested audio clip

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

condition

+
+

type

+
+


+

+
+

A new Audio clip is created and filled with the contents of the + retrieved audio clip

+
+

instance creation +

+
+


+

+
+

Audio clip is entered into Local storage

+
+

association formed

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Local storage : authenticate

+

TODO: move to Local storage spec

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

authenticate
(authenticationInfo : AuthenticationInfo)
: + boolean

+
+

Responsibilities

+
+

Check if the provided authentication info is recognized.

+
+

Type

+
+

interface

+
+

Cross-reference

+
+

UC-4

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

true if the provided authentication is recognized, false + otherwise

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Local storage : existsAudioClip

+

TODO: move to Local storage spec

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

existsAudioClip
(audioClipId : UniqueId)
: boolean

+
+

Responsibilities

+
+

Tell if an audio clip by the provided unique id is stored in + the Local storage

+
+

Type

+
+

interface

+
+

Cross-reference

+
+

UC-4

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

true if an audio clip with the provided id exists, false + otherwise

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

none

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Contract for Local storage : storeAudioClip

+

TODO: move to Local storage spec

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Name

+
+

storeAudioClip
(audioClip : AudioClip)
: void

+
+

Responsibilities

+
+

Store an audio clip.

+
+

Type

+
+

interface

+
+

Cross-reference

+
+

UC-4

+
+

Notes

+
+


+

+
+

Exceptions

+
+

none

+
+

Output

+
+

none

+
+

Pre-conditions

+
+

none

+
+

Post-conditions

+
+

The supplied audio clip is stored in the storage.

+
+


+

+
+


+

+
+


+

+
+


+

+
+



+

+

Glossary

+

playlist
The playlist is a metafile, containing +references to audio clips that should be played, and details on how +they should be played.

+ + \ No newline at end of file diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h index 4359fb7b1..99544b3e6 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h +++ b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $ ------------------------------------------------------------------------------*/ @@ -71,7 +71,7 @@ using namespace boost::posix_time; * the playlist. * * @author $Author: fgerlits $ - * @version $Revision: 1.5 $ + * @version $Revision: 1.6 $ */ class Playlist : public Configurable { @@ -166,7 +166,7 @@ class Playlist : public Configurable * @return the name of the expected XML configuration element. */ static const std::string - getConfigElementName(void) throw () + getConfigElementName(void) throw () { return configElementNameStr; } @@ -182,7 +182,7 @@ class Playlist : public Configurable */ virtual void configure(const xmlpp::Element & element) - throw (std::invalid_argument); + throw (std::invalid_argument); /** * Return the id of the playlist. @@ -190,7 +190,7 @@ class Playlist : public Configurable * @return the unique id of the playlist. */ Ptr::Ref - getId(void) const throw () + getId(void) const throw () { return id; } @@ -201,7 +201,7 @@ class Playlist : public Configurable * @return the playling length of this playlist, in milliseconds. */ Ptr::Ref - getPlaylength(void) const throw () + getPlaylength(void) const throw () { return playlength; } @@ -209,12 +209,14 @@ class Playlist : public Configurable /** * Test whether the playlist is locked for editing. * - * @return true if playlist is locked, false if not + * @return true if playlist is currently being edited; + * false if not, or if the editing has been suspended + * because the playlist is being played */ bool - getIsLockedForEditing() throw () + getIsLockedForEditing() const throw () { - return isLockedForEditing; + return isLockedForEditing && !isLockedForPlaying; } /** @@ -223,7 +225,7 @@ class Playlist : public Configurable * @return true if playlist is locked, false if not */ bool - getIsLockedForPlaying() throw () + getIsLockedForPlaying() const throw () { return isLockedForPlaying; } @@ -235,7 +237,7 @@ class Playlist : public Configurable * false otherwise. */ bool - setLockedForEditing(bool lockStatus) + setLockedForEditing(const bool lockStatus) throw (); /** @@ -245,7 +247,7 @@ class Playlist : public Configurable * false otherwise. */ bool - setLockedForPlaying(bool lockStatus) + setLockedForPlaying(const bool lockStatus) throw (); /** @@ -256,7 +258,6 @@ class Playlist : public Configurable /** * Get an iterator pointing to the first playlist element. - * */ const_iterator begin() const throw () @@ -266,7 +267,6 @@ class Playlist : public Configurable /** * Get an iterator pointing to one after the last playlist element. - * */ const_iterator end() const throw () @@ -287,6 +287,27 @@ class Playlist : public Configurable addAudioClip(Ptr::Ref audioClip, Ptr::Ref relativeOffset) throw (std::invalid_argument); + + /** + * Remove an audio clip from the playlist. + * + * @param relativeOffset the start of the audio clip, relative + * to the start of the playlist + * @exception std::invalid_argument if the playlist does not contain + * an audio clip with the specified relative offset + */ + void + removeAudioClip(Ptr::Ref relativeOffset) + throw (std::invalid_argument); + + /** + * Validate the playlist: check that there are no overlaps or gaps. + * If the playlength is the only thing amiss, playlist is considered + * valid, and the playlength is fixed. (Hence no 'const'.) + */ + bool + valid(void) throw (); + }; diff --git a/livesupport/modules/core/src/Playlist.cxx b/livesupport/modules/core/src/Playlist.cxx index 9371ac4d2..96d3935f9 100644 --- a/livesupport/modules/core/src/Playlist.cxx +++ b/livesupport/modules/core/src/Playlist.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $ ------------------------------------------------------------------------------*/ @@ -153,7 +153,7 @@ Playlist::addAudioClip(Ptr::Ref audioClip, throw (std::invalid_argument) { if (elementList->find(*relativeOffset) != elementList->end()) { - std::string eMsg = "two playlist elements at the same relative offset"; + std::string eMsg = "two audio clips at the same relative offset"; throw std::invalid_argument(eMsg); } @@ -164,11 +164,26 @@ Playlist::addAudioClip(Ptr::Ref audioClip, } +/*------------------------------------------------------------------------------ + * Remove an audio clip from the playlist. + *----------------------------------------------------------------------------*/ +void +Playlist::removeAudioClip(Ptr::Ref relativeOffset) + throw (std::invalid_argument) +{ + // this returns the number of elements found and erased + if (!elementList->erase(*relativeOffset)) { + std::string eMsg = "no audio clip at the specified relative offset"; + throw std::invalid_argument(eMsg); + } +} + + /*------------------------------------------------------------------------------ * Lock or unlock the playlist for editing. *----------------------------------------------------------------------------*/ bool -Playlist::setLockedForEditing(bool lockStatus) +Playlist::setLockedForEditing(const bool lockStatus) throw () { if (lockStatus == true) { @@ -196,7 +211,7 @@ Playlist::setLockedForEditing(bool lockStatus) * Lock or unlock the playlist for playing. *----------------------------------------------------------------------------*/ bool -Playlist::setLockedForPlaying(bool lockStatus) +Playlist::setLockedForPlaying(const bool lockStatus) throw () { if (lockStatus == true) { @@ -214,3 +229,27 @@ Playlist::setLockedForPlaying(bool lockStatus) } // was already unlocked! } + +/*------------------------------------------------------------------------------ + * Validate the playlist. + *----------------------------------------------------------------------------*/ +bool +Playlist::valid(void) throw () +{ + Ptr::Ref runningTime(new time_duration(0,0,0,0)); + Ptr::Ref playlistElement; + Ptr::Ref audioClip; + + PlaylistElementListType::const_iterator it = elementList->begin(); + while (it != elementList->end()) { + playlistElement = it->second; + if (*runningTime != *(playlistElement->getRelativeOffset())) { + return false; + } + audioClip = playlistElement->getAudioClip(); + *runningTime += *(audioClip->getPlaylength()); + ++it; + } + playlength = runningTime; // fix playlength, if everything else is OK + return true; +} diff --git a/livesupport/modules/core/src/PlaylistTest.cxx b/livesupport/modules/core/src/PlaylistTest.cxx index ef62115f8..0a5bd70db 100644 --- a/livesupport/modules/core/src/PlaylistTest.cxx +++ b/livesupport/modules/core/src/PlaylistTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.5 $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -90,6 +90,9 @@ PlaylistTest :: setUp(void) throw () CPPUNIT_ASSERT(duration->hours() == 1); CPPUNIT_ASSERT(duration->minutes() == 30); CPPUNIT_ASSERT(duration->seconds() == 0); + + CPPUNIT_ASSERT(playlist->valid()); + } catch (std::invalid_argument &e) { CPPUNIT_FAIL("semantic error in configuration file"); } catch (xmlpp::exception &e) { @@ -162,10 +165,10 @@ PlaylistTest :: lockTest(void) /*------------------------------------------------------------------------------ - * Test to see if we can add a new audio clip + * Test to see if we can add or remove an audio clip *----------------------------------------------------------------------------*/ void -PlaylistTest :: addAudioClipTest(void) +PlaylistTest :: audioClipTest(void) throw (CPPUNIT_NS::Exception) { Ptr::Ref clipId(new UniqueId(20001)); @@ -183,6 +186,8 @@ PlaylistTest :: addAudioClipTest(void) CPPUNIT_FAIL(eMsg); } + CPPUNIT_ASSERT(!playlist->valid()); // overlapping audio clips + Playlist::const_iterator it = playlist->begin(); CPPUNIT_ASSERT(it != playlist->end()); @@ -200,4 +205,31 @@ PlaylistTest :: addAudioClipTest(void) ++it; CPPUNIT_ASSERT(it == playlist->end()); + + try { + playlist->removeAudioClip(relativeOffset); + } + catch (std::invalid_argument &e) { + string eMsg = "removeAudioClip returned with error: "; + eMsg += e.what(); + CPPUNIT_FAIL(eMsg); + } + + it = playlist->begin(); + CPPUNIT_ASSERT(it != playlist->end()); + ++it; + CPPUNIT_ASSERT(it != playlist->end()); + ++it; + CPPUNIT_ASSERT(it == playlist->end()); + + Ptr::Ref phonyRelativeOffset( + new time_duration(0,0,1,0)); + try { + playlist->removeAudioClip(phonyRelativeOffset); + } + catch (std::invalid_argument &e) { + return; + } + CPPUNIT_FAIL("removeAudioClip allowed to remove " + "non-existent audio clip"); } diff --git a/livesupport/modules/core/src/PlaylistTest.h b/livesupport/modules/core/src/PlaylistTest.h index 84d591ee1..e3c09d4aa 100644 --- a/livesupport/modules/core/src/PlaylistTest.h +++ b/livesupport/modules/core/src/PlaylistTest.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.3 $ + Version : $Revision: 1.4 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistTest.h,v $ ------------------------------------------------------------------------------*/ @@ -58,7 +58,7 @@ namespace Core { * Unit test for the UploadPlaylistMetohd class. * * @author $Author: fgerlits $ - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ * @see Playlist */ class PlaylistTest : public CPPUNIT_NS::TestFixture @@ -66,7 +66,7 @@ class PlaylistTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST_SUITE(PlaylistTest); CPPUNIT_TEST(firstTest); CPPUNIT_TEST(lockTest); - CPPUNIT_TEST(addAudioClipTest); + CPPUNIT_TEST(audioClipTest); CPPUNIT_TEST_SUITE_END(); private: @@ -100,7 +100,7 @@ class PlaylistTest : public CPPUNIT_NS::TestFixture * @exception CPPUNIT_NS::Exception on test failures. */ void - addAudioClipTest(void) throw (CPPUNIT_NS::Exception); + audioClipTest(void) throw (CPPUNIT_NS::Exception); public: diff --git a/livesupport/products/scheduler/doc/model/SchedulerModel.zuml b/livesupport/products/scheduler/doc/model/SchedulerModel.zuml index ab5f958122ef312f6bcf71ce82defe126a5e78af..a14396569f24b84273b7482e3f8082885f5d6bd5 100644 GIT binary patch literal 116449 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

`Y^sP@7Z`g}iH?92>PyhqQtUq?r8{!Uyf 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 literal 102546 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 diff --git a/livesupport/products/scheduler/etc/Makefile.in b/livesupport/products/scheduler/etc/Makefile.in index 4f706e9f8..549730c6c 100644 --- a/livesupport/products/scheduler/etc/Makefile.in +++ b/livesupport/products/scheduler/etc/Makefile.in @@ -21,7 +21,7 @@ # # # Author : $Author: fgerlits $ -# Version : $Revision: 1.13 $ +# Version : $Revision: 1.14 $ # Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/etc/Makefile.in,v $ # # @configure_input@ @@ -123,7 +123,9 @@ SCHEDULER_OBJS = ${TMP_DIR}/SignalDispatcher.o \ ${TMP_DIR}/DisplayPlaylistsMethod.o \ ${TMP_DIR}/OpenPlaylistForEditingMethod.o \ ${TMP_DIR}/CreatePlaylistMethod.o \ - ${TMP_DIR}/AddAudioClipToPlaylistMethod.o + ${TMP_DIR}/AddAudioClipToPlaylistMethod.o \ + ${TMP_DIR}/RemoveAudioClipFromPlaylistMethod.o \ + ${TMP_DIR}/ValidatePlaylistMethod.o SCHEDULER_EXE_OBJS = ${SCHEDULER_OBJS} \ ${TMP_DIR}/main.o @@ -150,6 +152,8 @@ TEST_RUNNER_OBJS = ${SCHEDULER_OBJS} \ ${TMP_DIR}/OpenPlaylistForEditingMethodTest.o \ ${TMP_DIR}/CreatePlaylistMethodTest.o \ ${TMP_DIR}/AddAudioClipToPlaylistMethodTest.o \ + ${TMP_DIR}/RemoveAudioClipFromPlaylistMethodTest.o \ + ${TMP_DIR}/ValidatePlaylistMethodTest.o \ ${TMP_DIR}/TestRunner.o TEST_RUNNER_LIBS = ${SCHEDULER_EXE_LIBS} -lcppunit -ldl diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx index b7e4f50f4..183a485a5 100644 --- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx +++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.cxx,v $ ------------------------------------------------------------------------------*/ @@ -107,18 +107,32 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, } Ptr::Ref playlistId; - Ptr::Ref audioClipId; - Ptr::Ref relativeOffset; try{ playlistId = XmlRpcTools::extractPlaylistId(parameters); - audioClipId = XmlRpcTools::extractAudioClipId(parameters); - relativeOffset = XmlRpcTools::extractRelativeOffset(parameters); } catch (std::invalid_argument &e) { XmlRpcTools::markError(errorId+2, e.what(), returnValue); return; } + Ptr::Ref audioClipId; + try{ + audioClipId = XmlRpcTools::extractAudioClipId(parameters); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+3, e.what(), returnValue); + return; + } + + Ptr::Ref relativeOffset; + try{ + relativeOffset = XmlRpcTools::extractRelativeOffset(parameters); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+4, e.what(), returnValue); + return; + } + Ptr::Ref scf; Ptr::Ref storage; scf = StorageClientFactory::getInstance(); @@ -129,13 +143,13 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, playlist = storage->getPlaylist(playlistId); } catch (std::invalid_argument &e) { - XmlRpcTools::markError(errorId+3, "playlist does not exist", + XmlRpcTools::markError(errorId+5, "playlist does not exist", returnValue); return; } if (!playlist->getIsLockedForEditing()) { - XmlRpcTools::markError(errorId+4, + XmlRpcTools::markError(errorId+6, "playlist has not been opened for editing", returnValue); return; @@ -146,7 +160,7 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, audioClip = storage->getAudioClip(audioClipId); } catch (std::invalid_argument &e) { - XmlRpcTools::markError(errorId+5, "audio clip does not exist", + XmlRpcTools::markError(errorId+7, "audio clip does not exist", returnValue); return; } @@ -155,7 +169,7 @@ AddAudioClipToPlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, playlist->addAudioClip(audioClip, relativeOffset); } catch(std::invalid_argument &e) { - XmlRpcTools::markError(errorId+6, + XmlRpcTools::markError(errorId+8, "two audio clips at the same relative offset", returnValue); return; diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h index 88b14ca10..d2680d48f 100644 --- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h +++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethod.h,v $ ------------------------------------------------------------------------------*/ @@ -88,14 +88,16 @@ using namespace LiveSupport::Core; * The possible error codes are: *

    *
  • 301 - invalid argument format
  • - *
  • 302 - missing ... argument
  • - *
  • 303 - playlist does not exist
  • - *
  • 304 - playlist has not been opened for editing
  • - *
  • 305 - audio clip does not exist
  • - *
  • 306 - two audio clips at the same relative offset
  • + *
  • 302 - missing playlist ID argument
  • + *
  • 303 - missing audio clip ID argument
  • + *
  • 304 - missing relative offset argument
  • + *
  • 305 - playlist does not exist
  • + *
  • 306 - playlist has not been opened for editing
  • + *
  • 307 - audio clip does not exist
  • + *
  • 308 - two audio clips at the same relative offset
  • *
* @author $Author: fgerlits $ - * @version $Revision: 1.2 $ + * @version $Revision: 1.3 $ */ class AddAudioClipToPlaylistMethod : public XmlRpc::XmlRpcServerMethod { diff --git a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx index 75d81fd29..3302963b2 100644 --- a/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx +++ b/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/AddAudioClipToPlaylistMethodTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -157,7 +157,7 @@ AddAudioClipToPlaylistMethodTest :: firstTest(void) openPlaylistMethod->execute(parameter, result); addAudioClipMethod->execute(parameter, result); CPPUNIT_ASSERT(result.hasMember("errorCode")); - CPPUNIT_ASSERT((int)(result["errorCode"]) == 306); + CPPUNIT_ASSERT((int)(result["errorCode"]) == 308); parameter.clear(); result.clear(); diff --git a/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.cxx b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.cxx new file mode 100644 index 000000000..cd487cf0e --- /dev/null +++ b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.cxx @@ -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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.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 "XmlRpcTools.h" + +#include "RemoveAudioClipFromPlaylistMethod.h" + + +using namespace boost; +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 RemoveAudioClipFromPlaylistMethod::methodName + = "removeAudioClipFromPlaylist"; + +/*------------------------------------------------------------------------------ + * The ID of this method for error reporting purposes. + *----------------------------------------------------------------------------*/ +const int RemoveAudioClipFromPlaylistMethod::errorId = 400; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Construct the method and register it right away. + *----------------------------------------------------------------------------*/ +RemoveAudioClipFromPlaylistMethod :: RemoveAudioClipFromPlaylistMethod ( + Ptr::Ref xmlRpcServer) throw() + : XmlRpc::XmlRpcServerMethod(methodName, xmlRpcServer.get()) +{ +} + + +/*------------------------------------------------------------------------------ + * Execute the stop XML-RPC function call. + *----------------------------------------------------------------------------*/ +void +RemoveAudioClipFromPlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, + XmlRpc::XmlRpcValue & returnValue) + throw () +{ + if (!parameters.valid()) { + XmlRpcTools::markError(errorId+1, "invalid argument format", + returnValue); + return; + } + + Ptr::Ref playlistId; + try{ + playlistId = XmlRpcTools::extractPlaylistId(parameters); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+2, + "missing playlist ID argument", + returnValue); + return; + } + + Ptr::Ref relativeOffset; + try{ + relativeOffset = XmlRpcTools::extractRelativeOffset(parameters); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+3, + "missing relative offset argument", + returnValue); + return; + } + + Ptr::Ref scf; + Ptr::Ref storage; + scf = StorageClientFactory::getInstance(); + storage = scf->getStorageClient(); + + Ptr::Ref playlist; + try { + playlist = storage->getPlaylist(playlistId); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+4, "playlist does not exist", + returnValue); + return; + } + + if (!playlist->getIsLockedForEditing()) { + XmlRpcTools::markError(errorId+5, + "playlist has not been opened for editing", + returnValue); + return; + } + + try { // and finally, the beef + playlist->removeAudioClip(relativeOffset); + } + catch(std::invalid_argument &e) { + XmlRpcTools::markError(errorId+6, + "no audio clip at the specified " + "relative offset", + returnValue); + return; + } +} diff --git a/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.h b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.h new file mode 100644 index 000000000..a1654aaab --- /dev/null +++ b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethod.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef RemoveAudioClipFromPlaylistMethod_h +#define RemoveAudioClipFromPlaylistMethod_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 "LiveSupport/Core/Ptr.h" +#include "LiveSupport/Core/Playlist.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An XML-RPC method object to remove an audio clip (specified by its relative + * offset) from a playlist (specified by its ID). + * + * The name of the method when called through XML-RPC is + * "removeAudioClipFromPlaylist". + * The expected parameter is an XML-RPC structure, with the following + * members: + *
    + *
  • playlistId - int - the unique id of the playlist.
  • + *
  • relativeOffset - int - the number of seconds between the + * start of the playlist and the start of the audio clip + * to be removed.
  • + *
+ * + * In case of an error, an XML-RPC structure is returned, with the following + * fields: + *
    + *
  • errorCode - int - the id of the error condition
  • + *
  • errorMessage - string - a description of the error
  • + *
+ * The possible error codes are: + *
    + *
  • 401 - invalid argument format
  • + *
  • 402 - missing playlist ID argument
  • + *
  • 403 - missing relative offset argument
  • + *
  • 404 - playlist does not exist
  • + *
  • 405 - playlist has not been opened for editing
  • + *
  • 406 - no audio clip at the specified relative offset
  • + *
+ * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + */ +class RemoveAudioClipFromPlaylistMethod : 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 ID of this method for error reporting purposes. + */ + static const int errorId; + + + public: + /** + * A default constructor, for testing purposes. + */ + RemoveAudioClipFromPlaylistMethod(void) throw () + : XmlRpc::XmlRpcServerMethod(methodName) + { + } + + /** + * Constuctor that registers the method with the server right away. + * + * @param xmlRpcServer the XML-RPC server to register with. + */ + RemoveAudioClipFromPlaylistMethod( + Ptr::Ref xmlRpcServer) + throw (); + + /** + * Execute the display schedule 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 // RemoveAudioClipFromPlaylistMethod_h + diff --git a/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.cxx b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.cxx new file mode 100644 index 000000000..ca96cf39f --- /dev/null +++ b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.cxx @@ -0,0 +1,175 @@ +/*------------------------------------------------------------------------------ + + 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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.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 "XmlRpcTools.h" + +#include "OpenPlaylistForEditingMethod.h" +#include "AddAudioClipToPlaylistMethod.h" +#include "RemoveAudioClipFromPlaylistMethod.h" + +#include "RemoveAudioClipFromPlaylistMethodTest.h" + + +using namespace std; +using namespace LiveSupport::Db; +using namespace LiveSupport::Storage; +using namespace LiveSupport::Scheduler; + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +CPPUNIT_TEST_SUITE_REGISTRATION(RemoveAudioClipFromPlaylistMethodTest); + +/** + * The name of the configuration file for the storage client factory. + */ +const std::string RemoveAudioClipFromPlaylistMethodTest::storageClientConfig = + "etc/storageClient.xml"; + +/** + * The name of the configuration file for the connection manager factory. + */ +const std::string RemoveAudioClipFromPlaylistMethodTest::connectionManagerConfig = + "etc/connectionManagerFactory.xml"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Configure a Configurable with an XML file. + *----------------------------------------------------------------------------*/ +void +RemoveAudioClipFromPlaylistMethodTest :: 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 +RemoveAudioClipFromPlaylistMethodTest :: setUp(void) throw () +{ + try { + Ptr::Ref scf + = StorageClientFactory::getInstance(); + configure(scf, storageClientConfig); + + Ptr::Ref cmf + = ConnectionManagerFactory::getInstance(); + configure(cmf, connectionManagerConfig); + + } 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 +RemoveAudioClipFromPlaylistMethodTest :: tearDown(void) throw () +{ +} + + +/*------------------------------------------------------------------------------ + * Just a very simple smoke test + *----------------------------------------------------------------------------*/ +void +RemoveAudioClipFromPlaylistMethodTest :: firstTest(void) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref + openPlaylistMethod(new OpenPlaylistForEditingMethod()); + Ptr::Ref + addAudioClipMethod(new AddAudioClipToPlaylistMethod()); + Ptr::Ref + removeAudioClipMethod(new RemoveAudioClipFromPlaylistMethod()); + XmlRpc::XmlRpcValue parameter; + XmlRpc::XmlRpcValue result; + + parameter["playlistId"] = 1; + parameter["audioClipId"] = 20002; + parameter["relativeOffset"] = 90*60; + + removeAudioClipMethod->execute(parameter, result); + CPPUNIT_ASSERT(result.hasMember("errorCode")); + CPPUNIT_ASSERT((int)(result["errorCode"]) == 405); // not open for editing + + result.clear(); + openPlaylistMethod->execute(parameter, result); + removeAudioClipMethod->execute(parameter, result); + CPPUNIT_ASSERT(result.hasMember("errorCode")); + CPPUNIT_ASSERT((int)(result["errorCode"]) == 406); // no such audio clip + + result.clear(); + addAudioClipMethod->execute(parameter, result); + removeAudioClipMethod->execute(parameter, result); + CPPUNIT_ASSERT(!result.hasMember("errorCode")); +} diff --git a/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.h b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.h new file mode 100644 index 000000000..d73c6d49b --- /dev/null +++ b/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.h @@ -0,0 +1,135 @@ +/*------------------------------------------------------------------------------ + + 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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/RemoveAudioClipFromPlaylistMethodTest.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef RemoveAudioClipFromPlaylistMethodTest_h +#define RemoveAudioClipFromPlaylistMethodTest_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 RemoveAudioClipFromPlaylistMethod class. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + * @see RemoveAudioClipFromPlaylistMethod + */ +class RemoveAudioClipFromPlaylistMethodTest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(RemoveAudioClipFromPlaylistMethodTest); + CPPUNIT_TEST(firstTest); + 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; + + /** + * 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); + + + 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 // RemoveAudioClipFromPlaylistMethodTest_h + diff --git a/livesupport/products/scheduler/src/ValidatePlaylistMethod.cxx b/livesupport/products/scheduler/src/ValidatePlaylistMethod.cxx new file mode 100644 index 000000000..aa9f365b1 --- /dev/null +++ b/livesupport/products/scheduler/src/ValidatePlaylistMethod.cxx @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------------------ + + 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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ValidatePlaylistMethod.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 "XmlRpcTools.h" + +#include "ValidatePlaylistMethod.h" + + +using namespace boost; +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 ValidatePlaylistMethod::methodName + = "validatePlaylist"; + +/*------------------------------------------------------------------------------ + * The ID of this method for error reporting purposes. + *----------------------------------------------------------------------------*/ +const int ValidatePlaylistMethod::errorId = 500; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Construct the method and register it right away. + *----------------------------------------------------------------------------*/ +ValidatePlaylistMethod :: ValidatePlaylistMethod ( + Ptr::Ref xmlRpcServer) throw() + : XmlRpc::XmlRpcServerMethod(methodName, xmlRpcServer.get()) +{ +} + + +/*------------------------------------------------------------------------------ + * Execute the stop XML-RPC function call. + *----------------------------------------------------------------------------*/ +void +ValidatePlaylistMethod :: execute(XmlRpc::XmlRpcValue & parameters, + XmlRpc::XmlRpcValue & returnValue) + throw () +{ + if (!parameters.valid()) { + XmlRpcTools::markError(errorId+1, "invalid argument format", + returnValue); + return; + } + + Ptr::Ref playlistId; + try{ + playlistId = XmlRpcTools::extractPlaylistId(parameters); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+2, + "missing playlist ID argument", + returnValue); + return; + } + + Ptr::Ref scf; + Ptr::Ref storage; + scf = StorageClientFactory::getInstance(); + storage = scf->getStorageClient(); + + Ptr::Ref playlist; + try { + playlist = storage->getPlaylist(playlistId); + } + catch (std::invalid_argument &e) { + XmlRpcTools::markError(errorId+3, "playlist does not exist", + returnValue); + return; + } + + if (!playlist->getIsLockedForEditing()) { + XmlRpcTools::markError(errorId+4, + "playlist has not been opened for editing", + returnValue); + return; + } + + bool valid = playlist->valid(); // and finally, the beef + + XmlRpcTools::validStatusToXmlRpcValue(valid, returnValue); +} + diff --git a/livesupport/products/scheduler/src/ValidatePlaylistMethod.h b/livesupport/products/scheduler/src/ValidatePlaylistMethod.h new file mode 100644 index 000000000..f65923411 --- /dev/null +++ b/livesupport/products/scheduler/src/ValidatePlaylistMethod.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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ValidatePlaylistMethod.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef ValidatePlaylistMethod_h +#define ValidatePlaylistMethod_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 "LiveSupport/Core/Ptr.h" +#include "LiveSupport/Core/Playlist.h" + + +namespace LiveSupport { +namespace Scheduler { + +using namespace LiveSupport; +using namespace LiveSupport::Core; + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An XML-RPC method object to validate a playlist (specified by its ID). + * + * The name of the method when called through XML-RPC is + * "validatePlaylist". + * The expected parameter is an XML-RPC structure, with the following + * member: + *
    + *
  • playlistId - int - the unique id of the playlist.
  • + *
+ * + * The XML-RPC function returns an XML-RPC structure, containing the following + * fields: + *
    + *
  • valid - bool - true if the playlist is valid, false otherwise
  • + *
+ * + * In case of an error, an XML-RPC structure is returned, with the following + * fields: + *
    + *
  • errorCode - int - the id of the error condition
  • + *
  • errorMessage - string - a description of the error
  • + *
+ * The possible error codes are: + *
    + *
  • 501 - invalid argument format
  • + *
  • 502 - missing playlist ID argument
  • + *
  • 503 - playlist does not exist
  • + *
  • 504 - playlist has not been opened for editing
  • + *
+ * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + */ +class ValidatePlaylistMethod : 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 ID of this method for error reporting purposes. + */ + static const int errorId; + + + public: + /** + * A default constructor, for testing purposes. + */ + ValidatePlaylistMethod(void) throw () + : XmlRpc::XmlRpcServerMethod(methodName) + { + } + + /** + * Constuctor that registers the method with the server right away. + * + * @param xmlRpcServer the XML-RPC server to register with. + */ + ValidatePlaylistMethod( + Ptr::Ref xmlRpcServer) + throw (); + + /** + * Execute the display schedule 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 // ValidatePlaylistMethod_h + diff --git a/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.cxx b/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.cxx new file mode 100644 index 000000000..9a61fced4 --- /dev/null +++ b/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.cxx @@ -0,0 +1,180 @@ +/*------------------------------------------------------------------------------ + + 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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.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 "XmlRpcTools.h" + +#include "OpenPlaylistForEditingMethod.h" +#include "RemoveAudioClipFromPlaylistMethod.h" +#include "ValidatePlaylistMethod.h" + +#include "ValidatePlaylistMethodTest.h" + + +using namespace std; +using namespace LiveSupport::Db; +using namespace LiveSupport::Storage; +using namespace LiveSupport::Scheduler; + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +CPPUNIT_TEST_SUITE_REGISTRATION(ValidatePlaylistMethodTest); + +/** + * The name of the configuration file for the storage client factory. + */ +const std::string ValidatePlaylistMethodTest::storageClientConfig = + "etc/storageClient.xml"; + +/** + * The name of the configuration file for the connection manager factory. + */ +const std::string ValidatePlaylistMethodTest::connectionManagerConfig = + "etc/connectionManagerFactory.xml"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Configure a Configurable with an XML file. + *----------------------------------------------------------------------------*/ +void +ValidatePlaylistMethodTest :: 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 +ValidatePlaylistMethodTest :: setUp(void) throw () +{ + try { + Ptr::Ref scf + = StorageClientFactory::getInstance(); + configure(scf, storageClientConfig); + + Ptr::Ref cmf + = ConnectionManagerFactory::getInstance(); + configure(cmf, connectionManagerConfig); + + } 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 +ValidatePlaylistMethodTest :: tearDown(void) throw () +{ +} + + +/*------------------------------------------------------------------------------ + * Just a very simple smoke test + *----------------------------------------------------------------------------*/ +void +ValidatePlaylistMethodTest :: firstTest(void) + throw (CPPUNIT_NS::Exception) +{ + Ptr::Ref + openPlaylistMethod(new OpenPlaylistForEditingMethod()); + Ptr::Ref + removeAudioClipMethod(new RemoveAudioClipFromPlaylistMethod()); + Ptr::Ref + validatePlaylistMethod(new ValidatePlaylistMethod()); + XmlRpc::XmlRpcValue parameter; + XmlRpc::XmlRpcValue result; + + parameter["playlistId"] = 275; + validatePlaylistMethod->execute(parameter, result); + CPPUNIT_ASSERT(result.hasMember("errorCode")); + CPPUNIT_ASSERT(int(result["errorCode"]) == 503); // no such playlist + + result.clear(); + parameter.clear(); + parameter["playlistId"] = 1; + openPlaylistMethod->execute(parameter, result); + CPPUNIT_ASSERT(!result.hasMember("errorCode")); + result.clear(); + validatePlaylistMethod->execute(parameter, result); + CPPUNIT_ASSERT(result.hasMember("valid")); + CPPUNIT_ASSERT(bool(result["valid"])); + + result.clear(); + parameter["relativeOffset"] = 0; + removeAudioClipMethod->execute(parameter, result); + CPPUNIT_ASSERT(!result.hasMember("errorCode")); + result.clear(); + validatePlaylistMethod->execute(parameter, result); + CPPUNIT_ASSERT(result.hasMember("valid")); + CPPUNIT_ASSERT(!bool(result["valid"])); // has a gap at the beginning +} diff --git a/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.h b/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.h new file mode 100644 index 000000000..19abbb96f --- /dev/null +++ b/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.h @@ -0,0 +1,135 @@ +/*------------------------------------------------------------------------------ + + 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: fgerlits $ + Version : $Revision: 1.1 $ + Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/ValidatePlaylistMethodTest.h,v $ + +------------------------------------------------------------------------------*/ +#ifndef ValidatePlaylistMethodTest_h +#define ValidatePlaylistMethodTest_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 ValidatePlaylistMethod class. + * + * @author $Author: fgerlits $ + * @version $Revision: 1.1 $ + * @see ValidatePlaylistMethod + */ +class ValidatePlaylistMethodTest : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE(ValidatePlaylistMethodTest); + CPPUNIT_TEST(firstTest); + 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; + + /** + * 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); + + + 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 // ValidatePlaylistMethodTest_h + diff --git a/livesupport/products/scheduler/src/XmlRpcTools.cxx b/livesupport/products/scheduler/src/XmlRpcTools.cxx index 9a349d91d..45873ea78 100644 --- a/livesupport/products/scheduler/src/XmlRpcTools.cxx +++ b/livesupport/products/scheduler/src/XmlRpcTools.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.3 $ + Version : $Revision: 1.4 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/XmlRpcTools.cxx,v $ ------------------------------------------------------------------------------*/ @@ -87,7 +87,7 @@ XmlRpcTools :: extractPlaylistId(XmlRpc::XmlRpcValue & xmlRpcValue) throw (std::invalid_argument) { if (!xmlRpcValue.hasMember(playlistIdName)) { - throw std::invalid_argument("missing playlist ID"); + throw std::invalid_argument("missing playlist ID argument"); } Ptr::Ref id(new UniqueId((int) xmlRpcValue[playlistIdName])); @@ -103,7 +103,7 @@ XmlRpcTools :: extractAudioClipId(XmlRpc::XmlRpcValue & xmlRpcValue) throw (std::invalid_argument) { if (!xmlRpcValue.hasMember(audioClipIdName)) { - throw std::invalid_argument("missing audio clip ID"); + throw std::invalid_argument("missing audio clip ID argument"); } Ptr::Ref id(new UniqueId((int) xmlRpcValue[audioClipIdName])); @@ -119,7 +119,7 @@ XmlRpcTools :: extractRelativeOffset(XmlRpc::XmlRpcValue & xmlRpcValue) throw (std::invalid_argument) { if (!xmlRpcValue.hasMember(relativeOffsetName)) { - throw std::invalid_argument("missing relative offset"); + throw std::invalid_argument("missing relative offset argument"); } Ptr::Ref relativeOffset(new time_duration(0,0, @@ -153,3 +153,17 @@ XmlRpcTools :: markError(int errorCode, const std::string errorMessage, xmlRpcValue["errorCode"] = errorCode; xmlRpcValue["errorMessage"] = errorMessage; } + + +/*------------------------------------------------------------------------------ + * Convert the valid status of a playlist to an XmlRpcValue + *----------------------------------------------------------------------------*/ +void +XmlRpcTools :: validStatusToXmlRpcValue( + bool validStatus, + XmlRpc::XmlRpcValue & xmlRpcValue) + throw () +{ + xmlRpcValue["valid"] = XmlRpc::XmlRpcValue(validStatus); +} + diff --git a/livesupport/products/scheduler/src/XmlRpcTools.h b/livesupport/products/scheduler/src/XmlRpcTools.h index ad6adbe52..282965cef 100644 --- a/livesupport/products/scheduler/src/XmlRpcTools.h +++ b/livesupport/products/scheduler/src/XmlRpcTools.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.2 $ + Version : $Revision: 1.3 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/products/scheduler/src/Attic/XmlRpcTools.h,v $ ------------------------------------------------------------------------------*/ @@ -68,7 +68,7 @@ using namespace LiveSupport::Core; * in the Scheduler. * * @author $Author: fgerlits $ - * @version $Revision: 1.2 $ + * @version $Revision: 1.3 $ */ class XmlRpcTools { @@ -131,7 +131,7 @@ class XmlRpcTools * Convert a Playlist to an XmlRpcValue * * @param playlist the Playlist to convert. - * @param xmlRpcValue the output parameter holding the value of + * @param xmlRpcValue the output parameter holding the result of * the conversion. */ static void @@ -143,7 +143,7 @@ class XmlRpcTools * Convert an error code, message pair to an XmlRpcValue * * @param playlist the Playlist to convert. - * @param xmlRpcValue the output parameter holding the value of + * @param xmlRpcValue the output parameter holding the result of * the conversion. */ static void @@ -151,6 +151,17 @@ class XmlRpcTools XmlRpc::XmlRpcValue & xmlRpcValue) throw (); + /** + * Convert the valid status of a playlist to an XmlRpcValue + * + * @param validStatus true if the playlist is valid, false otherwise. + * @param xmlRpcValue the output parameter holding the result of + * the conversion. + */ + static void + validStatusToXmlRpcValue(bool validStatus, + XmlRpc::XmlRpcValue & xmlRpcValue) + throw (); }; /* ================================================= external data structures */