From 300a90ab83e4df6321a56ee8a9f2c8d6c16abd62 Mon Sep 17 00:00:00 2001 From: fgerlits Date: Wed, 12 Jan 2005 15:46:51 +0000 Subject: [PATCH] added documentation to the storage clients rewrote the TestStorageClient to better mirror the behavior of the WebStorageClient added copy constructors to AudioClip and Playlist (needed in TestS.C.) --- .../core/include/LiveSupport/Core/AudioClip.h | 16 +- .../core/include/LiveSupport/Core/Playlist.h | 20 ++- .../core/include/LiveSupport/Core/SessionId.h | 24 ++- .../core/include/LiveSupport/Core/UniqueId.h | 21 ++- livesupport/modules/core/src/AudioClip.cxx | 24 ++- livesupport/modules/core/src/Playlist.cxx | 25 ++- .../Storage/StorageClientInterface.h | 94 +++++++--- .../modules/storage/src/TestStorageClient.cxx | 100 +++++++---- .../modules/storage/src/TestStorageClient.h | 122 ++++++++++--- .../storage/src/TestStorageClientTest.cxx | 166 ++++++++++++------ .../modules/storage/src/WebStorageClient.cxx | 8 +- .../modules/storage/src/WebStorageClient.h | 114 ++++++++---- 12 files changed, 540 insertions(+), 194 deletions(-) diff --git a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h index 05e595524..54081205b 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h +++ b/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.17 $ + Version : $Revision: 1.18 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $ ------------------------------------------------------------------------------*/ @@ -124,7 +124,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.17 $ + * @version $Revision: 1.18 $ */ class AudioClip : public Configurable, public Playable @@ -167,6 +167,18 @@ class AudioClip : public Configurable, public: + /** + * Copy constructor. + * + * Copies the pointers for all fields except xmlAudioClip. + * These fields are immutable; if you want to modify them, call the + * appropriate setter function with (a pointer to) an object + * with the new value. + * + * @param otherAudioClip the audio clip to be copied + */ + AudioClip(const AudioClip & otherAudioClip) throw (); + /** * Default constructor. * diff --git a/livesupport/modules/core/include/LiveSupport/Core/Playlist.h b/livesupport/modules/core/include/LiveSupport/Core/Playlist.h index bd20f1ac1..ddaaf6764 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.27 $ + Version : $Revision: 1.28 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $ ------------------------------------------------------------------------------*/ @@ -93,7 +93,7 @@ using namespace boost::posix_time; * * * @author $Author: fgerlits $ - * @version $Revision: 1.27 $ + * @version $Revision: 1.28 $ */ class Playlist : public Configurable, public Playable @@ -181,6 +181,22 @@ class Playlist : public Configurable, public: + /** + * Copy constructor. + * + * Copies the pointers for all fields except elementList, + * savedCopy and metadata. A new copy of these three are created, + * but the playlists and strings contained in elementList and + * metadata are not duplicated, only a new pointer to them is created. + * The remaining fields are immutable; if you want to modify them, + * call the appropriate setter function with (a pointer to) an object + * with the new value. + * + * @param otherPlaylist the playlist to be copied + */ + Playlist(const Playlist & otherPlaylist) + throw (); + /** * Default constructor. * diff --git a/livesupport/modules/core/include/LiveSupport/Core/SessionId.h b/livesupport/modules/core/include/LiveSupport/Core/SessionId.h index 26ceb31be..215d0cbfd 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/SessionId.h +++ b/livesupport/modules/core/include/LiveSupport/Core/SessionId.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.3 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.4 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/SessionId.h,v $ ------------------------------------------------------------------------------*/ @@ -57,8 +57,8 @@ namespace Core { /** * A class representing session identifiers. * - * @author $Author: maroy $ - * @version $Revision: 1.3 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.4 $ */ class SessionId { @@ -96,7 +96,7 @@ class SessionId * Compare this is with an other one. * * @param otherId the other unqiue id to compare to. - * @return true if this an otherId have the same ID value, + * @return true if this another sessionId have the same value, * false otherwise. */ bool @@ -106,6 +106,20 @@ class SessionId return this->id == otherId.id; } + /** + * Compare this is with an other one. + * + * @param otherId the other unqiue id to compare to. + * @return true if this another sessionId do not have the same value, + * false otherwise. + */ + bool + operator!=(const SessionId & otherId) const + throw () + { + return this->id != otherId.id; + } + /** * Compare this id with an other one. * diff --git a/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h b/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h index 098095bb6..aa6bf1ace 100644 --- a/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h +++ b/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.5 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.6 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/UniqueId.h,v $ ------------------------------------------------------------------------------*/ @@ -59,8 +59,8 @@ namespace Core { /** * A class representing globally unique identifiers. * - * @author $Author: maroy $ - * @version $Revision: 1.5 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.6 $ */ class UniqueId { @@ -155,6 +155,19 @@ class UniqueId return this->id == otherId.id; } + /** + * Compare this is with an other one. + * + * @param otherId the other unqiue id to compare to. + * @return true if this an otherId do not have the same ID value, + * false otherwise. + */ + bool + operator!=(const UniqueId & otherId) const throw () + { + return this->id != otherId.id; + } + /** * Compare this id with an other one. * diff --git a/livesupport/modules/core/src/AudioClip.cxx b/livesupport/modules/core/src/AudioClip.cxx index e0e6c5c21..399064327 100644 --- a/livesupport/modules/core/src/AudioClip.cxx +++ b/livesupport/modules/core/src/AudioClip.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.15 $ + Version : $Revision: 1.16 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $ ------------------------------------------------------------------------------*/ @@ -117,6 +117,27 @@ static const std::string defaultPrefixUri ="http://www.streamonthefly.org/"; /* ============================================================= module code */ +/*------------------------------------------------------------------------------ + * Copy constructor. + *----------------------------------------------------------------------------*/ +AudioClip :: AudioClip(const AudioClip & otherAudioClip) throw () + : Playable(AudioClipType) +{ + this->id = otherAudioClip.id; + this->title = otherAudioClip.title; + this->playlength = otherAudioClip.playlength; + this->uri = otherAudioClip.uri; + this->token = otherAudioClip.token; + + if (otherAudioClip.xmlAudioClip) { + xmlAudioClip.reset(new xmlpp::Document); + xmlAudioClip->create_root_node_by_import( + otherAudioClip.xmlAudioClip->get_root_node(), + true); // true == recursive + } +} + + /*------------------------------------------------------------------------------ * Test constructor without title. *----------------------------------------------------------------------------*/ @@ -138,6 +159,7 @@ AudioClip :: AudioClip(Ptr::Ref id, setMetadata(playlengthString, extentElementName, extentElementPrefix); } + /*------------------------------------------------------------------------------ * Test constructor with title. *----------------------------------------------------------------------------*/ diff --git a/livesupport/modules/core/src/Playlist.cxx b/livesupport/modules/core/src/Playlist.cxx index 8034b1159..6cad30466 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.23 $ + Version : $Revision: 1.24 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $ ------------------------------------------------------------------------------*/ @@ -132,6 +132,29 @@ Playlist :: configure(const xmlpp::Element & element) } +/*------------------------------------------------------------------------------ + * Copy constructor. + *----------------------------------------------------------------------------*/ +Playlist :: Playlist(const Playlist & otherPlaylist) + throw () + : Playable(PlaylistType) +{ + id = otherPlaylist.id; + title = otherPlaylist.title; + playlength = otherPlaylist.playlength; + uri = otherPlaylist.uri; + token = otherPlaylist.token; + + elementList.reset(new PlaylistElementListType(*otherPlaylist.elementList)); + + if (otherPlaylist.savedCopy) { + savedCopy.reset(new Playlist(*otherPlaylist.savedCopy)); + } + + metadata = otherPlaylist.metadata; +} + + /*------------------------------------------------------------------------------ * Add a new playlist element to the playlist. *----------------------------------------------------------------------------*/ diff --git a/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h b/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h index a1cf1c48e..0a5ed506f 100644 --- a/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h +++ b/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.4 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.5 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h,v $ ------------------------------------------------------------------------------*/ @@ -64,12 +64,27 @@ using namespace Core; /** * An interface for storage clients. * - * @author $Author: maroy $ - * @version $Revision: 1.4 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.5 $ */ class StorageClientInterface { public: + /** + * Create a new, empty, playlist. Does not automatically open the + * playlist for editing; for that, use editPlaylist() and + * savePlaylist(). + * + * @param sessionId the session ID from the authentication client + * @return the newly created playlist. + * @exception XmlRpcException if there is a problem with the XML-RPC + * call. + */ + virtual Ptr::Ref + createPlaylist(Ptr::Ref sessionId) + throw (XmlRpcException) + = 0; + /** * Tell if a playlist with a given id exists. * @@ -87,7 +102,8 @@ class StorageClientInterface = 0; /** - * Return a playlist with the specified id, to be displayed. + * Return a playlist with the specified id to be displayed. + * If the playlist is being edited, its last saved state is returned. * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -103,7 +119,9 @@ class StorageClientInterface = 0; /** - * Return a playlist with the specified id, to be edited. + * Return a playlist with the specified id to be edited. + * This puts a lock on the playlist, and nobody else can edit it + * until we release it using savePlaylist(). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -114,12 +132,14 @@ class StorageClientInterface */ virtual Ptr::Ref editPlaylist(Ptr::Ref sessionId, - Ptr::Ref id) const + Ptr::Ref id) throw (XmlRpcException) = 0; /** * Save the playlist after editing. + * Can only be called after we obtained a lock on the playlist using + * editPlaylist(); this method releases the lock. * * @param sessionId the session ID from the authentication client * @param playlist the playlist to save. @@ -129,12 +149,20 @@ class StorageClientInterface */ virtual void savePlaylist(Ptr::Ref sessionId, - Ptr::Ref playlist) const + Ptr::Ref playlist) throw (XmlRpcException) = 0; /** * Acquire the resources for the playlist. + * The last saved copy of the playlist is read, and a local copy + * is created in SMIL format. (A local copy is also created for + * each sub-playlist contained in the playlist.) + * The address of this local copy is + * stored in the uri field of the playlist. The SMIL + * file can be played using the Helix client. + * For each audio clip contained (directly or indirectly) in the + * playlist, acquireAudioClip() is called * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to acquire. @@ -154,6 +182,11 @@ class StorageClientInterface /** * Release the resources (audio clips, other playlists) used * in a playlist. + * For each audio clip contained (directly or indirectly) in the + * playlist, releaseAudioClip() is called, and the local copy of + * the playlist (and sub-playlists, if any) is removed. + * The uri field of the playlist is erased (set to + * a null pointer). * * @param sessionId the session ID from the authentication client * @param playlist the playlist to release. @@ -168,6 +201,9 @@ class StorageClientInterface = 0; /** * Delete a playlist with the specified id. + * Will refuse to delete the playlist if it is being edited (i.e., + * has been opened with editPlaylist() but has not yet been released + * with savePlaylist()). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to be deleted. @@ -183,6 +219,7 @@ class StorageClientInterface /** * Return a list of all playlists in the playlist store. + * This is for testing only; will be replaced by a search method. * * @param sessionId the session ID from the authentication client * @return a vector containing the playlists. @@ -194,19 +231,6 @@ class StorageClientInterface throw (XmlRpcException) = 0; - /** - * Create a new playlist. - * - * @param sessionId the session ID from the authentication client - * @return the newly created playlist. - * @exception XmlRpcException if there is a problem with the XML-RPC - * call. - */ - virtual Ptr::Ref - createPlaylist(Ptr::Ref sessionId) - throw (XmlRpcException) - = 0; - /** * Tell if an audio clip with a given id exists. * @@ -224,7 +248,10 @@ class StorageClientInterface = 0; /** - * Return an audio clip with the specified id. + * Return an audio clip with the specified id to be displayed. + * The audio clip returned contains all the metadata (title, author, + * etc.) available for the audio clip, but no binary sound file. + * If you want to play the audio clip, use acquireAudioClip(). * * @param sessionId the session ID from the authentication client * @param id the id of the audio clip to return. @@ -241,6 +268,18 @@ class StorageClientInterface /** * Store an audio clip. + * The audio clip is expected to have valid title, + * playlength and uri fields, the latter + * containing the URI of a binary sound file. + * + * If the audio clip does not have + * an ID field (i.e., audioClip->getId() is a null + * pointer), one will be generated, and audioClip->getId() + * will contain a valid UniqueId after the method returns. + * If the audio clip had an ID already, then it remains unchanged. + * + * The size of the binary sound file must be less than 2 GB, because + * the storage server can not deal with larger files. * * @param sessionId the session ID from the authentication client * @param audioClip the audio clip to store. @@ -256,6 +295,13 @@ class StorageClientInterface /** * Acquire the resources for the audio clip with the specified id. + * The uri field of the audio clip returned by the + * method points to a binary sound file playable by the Helix client. + * This binary sound file can be randomly accessed. + * + * The returned audio clip also contains a token field + * which identifies it to the storage server; this is used by + * releaseAudioClip(). * * @param sessionId the session ID from the authentication client * @param id the id of the audio clip to acquire. @@ -273,6 +319,9 @@ class StorageClientInterface /** * Release the resource (sound file) used by an audio clip. + * After the call to this method, the binary sound file is no longer + * accessible, and the uri and token fields + * of the audioClip are erased (set to null pointers). * * @param sessionId the session ID from the authentication client * @param audioClip the id of the audio clip to release. @@ -303,6 +352,7 @@ class StorageClientInterface /** * Return a list of all audio clips in the playlist store. + * This is for testing only; will be replaced by a search method. * * @param sessionId the session ID from the authentication client * @return a vector containing the playlists. diff --git a/livesupport/modules/storage/src/TestStorageClient.cxx b/livesupport/modules/storage/src/TestStorageClient.cxx index f2e0ae828..ecf12035a 100644 --- a/livesupport/modules/storage/src/TestStorageClient.cxx +++ b/livesupport/modules/storage/src/TestStorageClient.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.26 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.27 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -183,6 +183,11 @@ TestStorageClient :: configure(const xmlpp::Element & element) const xmlpp::Element * element = dynamic_cast (*it); audioClip->configure(*element); + if (audioClip->getUri()) { + audioClipUris[audioClip->getId()->getId()] = audioClip->getUri(); + Ptr::Ref nullPointer; + audioClip->setUri(nullPointer); + } audioClipMap[audioClip->getId()->getId()] = audioClip; ++it; } @@ -209,13 +214,14 @@ TestStorageClient :: getPlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (XmlRpcException) { - PlaylistMap::const_iterator it = playlistMap.find(id->getId()); + PlaylistMapType::const_iterator it = playlistMap.find(id->getId()); if (it == playlistMap.end()) { throw XmlRpcException("no such playlist"); } - return it->second; + Ptr::Ref copyOfPlaylist(new Playlist(*it->second)); + return copyOfPlaylist; } @@ -224,16 +230,15 @@ TestStorageClient :: getPlaylist(Ptr::Ref sessionId, *----------------------------------------------------------------------------*/ Ptr::Ref TestStorageClient :: editPlaylist(Ptr::Ref sessionId, - Ptr::Ref id) const + Ptr::Ref id) throw (XmlRpcException) { - PlaylistMap::const_iterator it = playlistMap.find(id->getId()); - - if (it == playlistMap.end()) { - throw XmlRpcException("no such playlist"); + if (editedPlaylists.find(id->getId()) != editedPlaylists.end()) { + throw XmlRpcException("playlist is already being edited"); } - - return it->second; + + editedPlaylists[id->getId()] = sessionId; + return getPlaylist(sessionId, id); } @@ -242,9 +247,26 @@ TestStorageClient :: editPlaylist(Ptr::Ref sessionId, *----------------------------------------------------------------------------*/ void TestStorageClient :: savePlaylist(Ptr::Ref sessionId, - Ptr::Ref playlist) const + Ptr::Ref playlist) throw () { + EditedPlaylistsType::iterator + editIt = editedPlaylists.find(playlist->getId()->getId()); + + if ((editIt == editedPlaylists.end()) || (*editIt->second != *sessionId)) { + throw XmlRpcException("savePlaylist() called without editPlaylist()"); + } + + editedPlaylists.erase(editIt); + + PlaylistMapType::iterator + storeIt = playlistMap.find(playlist->getId()->getId()); + + if (storeIt == playlistMap.end()) { + throw XmlRpcException("playlist deleted while it was being edited???"); + } + + storeIt->second = playlist; } @@ -256,7 +278,8 @@ TestStorageClient :: acquirePlaylist(Ptr::Ref sessionId, Ptr::Ref id) const throw (XmlRpcException) { - PlaylistMap::const_iterator playlistMapIt = playlistMap.find(id->getId()); + PlaylistMapType::const_iterator playlistMapIt + = playlistMap.find(id->getId()); if (playlistMapIt == playlistMap.end()) { throw XmlRpcInvalidArgumentException("no such playlist"); @@ -406,6 +429,10 @@ TestStorageClient :: deletePlaylist(Ptr::Ref sessionId, Ptr::Ref id) throw (XmlRpcException) { + if (editedPlaylists.find(id->getId()) != editedPlaylists.end()) { + throw XmlRpcException("playlist is being edited"); + } + // erase() returns the number of entries found & erased if (!playlistMap.erase(id->getId())) { throw XmlRpcException("no such playlist"); @@ -421,7 +448,7 @@ TestStorageClient :: getAllPlaylists(Ptr::Ref sessionId) const throw () { - PlaylistMap::const_iterator it = playlistMap.begin(); + PlaylistMapType::const_iterator it = playlistMap.begin(); Ptr::Ref> >::Ref playlistVector (new std::vector::Ref>); @@ -454,7 +481,7 @@ TestStorageClient :: createPlaylist(Ptr::Ref sessionId) playlistMap[playlistId->getId()] = playlist; - return playlist; + return getPlaylist(sessionId, playlistId); // return a copy of the playlist } @@ -478,13 +505,14 @@ TestStorageClient :: getAudioClip(Ptr::Ref sessionId, Ptr::Ref id) const throw (XmlRpcException) { - AudioClipMap::const_iterator it = audioClipMap.find(id->getId()); + AudioClipMapType::const_iterator it = audioClipMap.find(id->getId()); if (it == audioClipMap.end()) { throw XmlRpcException("no such audio clip"); } - return it->second; + Ptr::Ref copyOfAudioClip(new AudioClip(*it->second)); + return copyOfAudioClip; } @@ -496,11 +524,22 @@ TestStorageClient :: storeAudioClip(Ptr::Ref sessionId, Ptr::Ref audioClip) throw (XmlRpcException) { + if (!audioClip->getUri()) { + throw XmlRpcException("audio clip has no URI field"); + } + if (!audioClip->getId()) { audioClip->setId(UniqueId::generateId()); } - audioClipMap[audioClip->getId()->getId()] = audioClip; + Ptr::Ref copyOfAudioClip(new AudioClip(*audioClip)); + + audioClipUris[copyOfAudioClip->getId()->getId()] + = copyOfAudioClip->getUri(); + Ptr::Ref nullPointer; + copyOfAudioClip->setUri(nullPointer); + + audioClipMap[copyOfAudioClip->getId()->getId()] = copyOfAudioClip; } @@ -512,34 +551,27 @@ TestStorageClient :: acquireAudioClip(Ptr::Ref sessionId, Ptr::Ref id) const throw (XmlRpcException) { - AudioClipMap::const_iterator it = audioClipMap.find(id->getId()); - - if (it == audioClipMap.end()) { - throw XmlRpcException("no such audio clip"); - } - - Ptr::Ref storedAudioClip = it->second; + AudioClipUrisType::const_iterator it = audioClipUris.find(id->getId()); - if (! storedAudioClip->getUri()) { - throw XmlRpcException("audio clip URI not found"); + if (it == audioClipUris.end()) { + throw XmlRpcException("sound file URI not found for audio clip"); } // cut the "file:" off - std::string audioClipFileName = storedAudioClip->getUri()->substr(5); + std::string audioClipFileName = it->second->substr(5); std::ifstream ifs(audioClipFileName.c_str()); if (!ifs) { ifs.close(); - throw XmlRpcException("could not read audio clip"); + throw XmlRpcException("could not open sound file"); } ifs.close(); - Ptr::Ref audioClip(new AudioClip(*storedAudioClip)); - Ptr::Ref audioClipUri(new std::string("file://")); *audioClipUri += get_current_dir_name(); // doesn't work if current *audioClipUri += "/"; // dir = /, but OK for now *audioClipUri += audioClipFileName; + Ptr::Ref audioClip = getAudioClip(sessionId, id); audioClip->setUri(audioClipUri); return audioClip; } @@ -553,8 +585,8 @@ TestStorageClient :: releaseAudioClip(Ptr::Ref sessionId, Ptr::Ref audioClip) const throw (XmlRpcException) { - if (*(audioClip->getUri()) == "") { - throw XmlRpcException("audio clip URI not found"); + if (!audioClip->getUri()) { + throw XmlRpcException("audio clip does not have a URI field"); } Ptr::Ref nullPointer; @@ -585,7 +617,7 @@ TestStorageClient :: getAllAudioClips(Ptr::Ref sessionId) const throw () { - AudioClipMap::const_iterator it = audioClipMap.begin(); + AudioClipMapType::const_iterator it = audioClipMap.begin(); Ptr::Ref> >::Ref audioClipVector (new std::vector::Ref>); diff --git a/livesupport/modules/storage/src/TestStorageClient.h b/livesupport/modules/storage/src/TestStorageClient.h index c89e34d80..8014849af 100644 --- a/livesupport/modules/storage/src/TestStorageClient.h +++ b/livesupport/modules/storage/src/TestStorageClient.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.22 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.23 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.h,v $ ------------------------------------------------------------------------------*/ @@ -89,8 +89,8 @@ using namespace LiveSupport::Core; * <!ATTLIST testStorage tempFiles CDATA #REQUIRED > * * - * @author $Author: maroy $ - * @version $Revision: 1.22 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.23 $ */ class TestStorageClient : virtual public Configurable, @@ -106,23 +106,45 @@ class TestStorageClient : * The map type containing the playlists by their ids. */ typedef std::map::Ref> - PlaylistMap; + PlaylistMapType; /** * The map holding all contained playlists, by ids. */ - PlaylistMap playlistMap; + PlaylistMapType playlistMap; + + /** + * The type for the list of playlists which are currently being edited + */ + typedef std::map::Ref> + EditedPlaylistsType; + + /** + * The list of playlists which are currently being edited + */ + EditedPlaylistsType editedPlaylists; /** * The map type containing the audio clips by their ids. */ typedef std::map::Ref> - AudioClipMap; + AudioClipMapType; /** * The map holding all contained audio clips, by ids. */ - AudioClipMap audioClipMap; + AudioClipMapType audioClipMap; + + /** + * The map type containing the URIs of the audio clips + */ + typedef std::map::Ref> + AudioClipUrisType; + + /** + * The map type containing the URIs of the audio clips + */ + AudioClipUrisType audioClipUris; /** * The path where the temporary SMIL files are strored. @@ -163,6 +185,19 @@ class TestStorageClient : throw (std::invalid_argument); + /** + * Create a new, empty, playlist. Does not automatically open the + * playlist for editing; for that, use editPlaylist() and + * savePlaylist(). + * + * @param sessionId the session ID from the authentication client + * @return the newly created playlist. + */ + virtual Ptr::Ref + createPlaylist(Ptr::Ref sessionId) + throw (); + + /** * Tell if a playlist with a given id exists. * @@ -178,7 +213,8 @@ class TestStorageClient : /** - * Return a playlist with the specified id, to be displayed. + * Return a playlist with the specified id to be displayed. + * If the playlist is being edited, its last saved state is returned. * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -193,7 +229,9 @@ class TestStorageClient : /** - * Return a playlist with the specified id, to be edited. + * Return a playlist with the specified id to be edited. + * This puts a lock on the playlist, and nobody else can edit it + * until we release it using savePlaylist(). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -203,27 +241,36 @@ class TestStorageClient : */ virtual Ptr::Ref editPlaylist(Ptr::Ref sessionId, - Ptr::Ref id) const + Ptr::Ref id) throw (XmlRpcException); /** * Save the playlist after editing. + * Can only be called after we obtained a lock on the playlist using + * editPlaylist(); this method releases the lock. * * @param sessionId the session ID from the authentication client * @param playlist the playlist to save. */ virtual void savePlaylist(Ptr::Ref sessionId, - Ptr::Ref playlist) const + Ptr::Ref playlist) throw (); /** * Acquire the resources for the playlist. + * The last saved copy of the playlist is read, and a local copy + * is created in SMIL format. (A local copy is also created for + * each sub-playlist contained in the playlist.) + * The address of this local copy is + * stored in the uri field of the playlist. The SMIL + * file can be played using the Helix client. + * For each audio clip contained (directly or indirectly) in the + * playlist, acquireAudioClip() is called * - * The Playlist returned has a uri field (read using getUri()) - * which points to a playable SMIL file. This URI is a random string + * The URI of the SMIL file is a random string * appended to the temp storage path read from the configuration file, * plus a ".smil" extension. * @@ -244,6 +291,11 @@ class TestStorageClient : /** * Release the resources (audio clips, other playlists) used * in a playlist. + * For each audio clip contained (directly or indirectly) in the + * playlist, releaseAudioClip() is called, and the local copy of + * the playlist (and sub-playlists, if any) is removed. + * The uri field of the playlist is erased (set to + * a null pointer). * * @param sessionId the session ID from the authentication client * @param playlist the playlist to release. @@ -257,6 +309,9 @@ class TestStorageClient : /** * Delete a playlist with the specified id. + * Will refuse to delete the playlist if it is being edited (i.e., + * has been opened with editPlaylist() but has not yet been released + * with savePlaylist()). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to be deleted. @@ -271,6 +326,7 @@ class TestStorageClient : /** * Return a list of all playlists in the playlist store. + * This is for testing only; will be replaced by a search method. * * @param sessionId the session ID from the authentication client * @return a vector containing the playlists. @@ -280,17 +336,6 @@ class TestStorageClient : throw (); - /** - * Create a new playlist. - * - * @param sessionId the session ID from the authentication client - * @return the newly created playlist. - */ - virtual Ptr::Ref - createPlaylist(Ptr::Ref sessionId) - throw (); - - /** * Tell if an audio clip with a given id exists. * @@ -305,7 +350,10 @@ class TestStorageClient : throw (); /** - * Return an audio clip with the specified id. + * Return an audio clip with the specified id to be displayed. + * The audio clip returned contains all the metadata (title, author, + * etc.) available for the audio clip, but no binary sound file. + * If you want to play the audio clip, use acquireAudioClip(). * * @param sessionId the session ID from the authentication client * @param id the id of the audio clip to return. @@ -320,6 +368,15 @@ class TestStorageClient : /** * Store an audio clip. + * The audio clip is expected to have valid title, + * playlength and uri fields, the latter + * containing the URI of a binary sound file. + * + * If the audio clip does not have + * an ID field (i.e., audioClip->getId() is a null + * pointer), one will be generated, and audioClip->getId() + * will contain a valid UniqueId after the method returns. + * If the audio clip had an ID already, then it remains unchanged. * * @param sessionId the session ID from the authentication client * @param audioClip the audio clip to store. @@ -333,9 +390,14 @@ class TestStorageClient : /** * Acquire the resources for the audio clip with the specified id. + * The uri field of the audio clip returned by the + * method points to a binary sound file playable by the Helix client. + * This binary sound file can be randomly accessed. + * + * The returned audio clip also contains a token field + * which identifies it to the storage server; this is used by + * releaseAudioClip(). * - * Returns an AudioClip instance with a valid uri field, which points - * to the binary sound file. * Assumes URIs in the config file are relative paths prefixed by * "file:"; e.g., "file:var/test1.mp3". * @@ -354,6 +416,9 @@ class TestStorageClient : /** * Release the resource (sound file) used by an audio clip. + * After the call to this method, the binary sound file is no longer + * accessible, and the uri and token fields + * of the audioClip are erased (set to null pointers). * * @param sessionId the session ID from the authentication client * @param audioClip the id of the audio clip to release. @@ -382,6 +447,7 @@ class TestStorageClient : /** * Return a list of all audio clips in the playlist store. + * This is for testing only; will be replaced by a search method. * * @param sessionId the session ID from the authentication client * @return a vector containing the playlists. diff --git a/livesupport/modules/storage/src/TestStorageClientTest.cxx b/livesupport/modules/storage/src/TestStorageClientTest.cxx index 6ff79b79a..06014a68b 100644 --- a/livesupport/modules/storage/src/TestStorageClientTest.cxx +++ b/livesupport/modules/storage/src/TestStorageClientTest.cxx @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.20 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.21 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClientTest.cxx,v $ ------------------------------------------------------------------------------*/ @@ -114,11 +114,25 @@ TestStorageClientTest :: firstTest(void) Ptr::Ref id1(new UniqueId(1)); Ptr::Ref id2(new UniqueId(77)); + try { CPPUNIT_ASSERT(tsc->existsPlaylist(dummySessionId, id1)); - CPPUNIT_ASSERT(!tsc->existsPlaylist(dummySessionId, id2)); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } - Ptr::Ref playlist = tsc->getPlaylist(dummySessionId, id1); - CPPUNIT_ASSERT(playlist->getId()->getId() == id1->getId()); + try { + CPPUNIT_ASSERT(!tsc->existsPlaylist(dummySessionId, id2)); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } + + Ptr::Ref playlist; + try { + playlist = tsc->getPlaylist(dummySessionId, id1); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(playlist->getId()->getId() == id1->getId()); } @@ -129,24 +143,26 @@ void TestStorageClientTest :: deletePlaylistTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref id1(new UniqueId(0x1)); - Ptr::Ref id2(new UniqueId(0x77)); + Ptr::Ref id1(new UniqueId(0x1)); + Ptr::Ref id2(new UniqueId(0x77)); - try { - tsc->deletePlaylist(dummySessionId, id2); - CPPUNIT_FAIL("allowed to delete non-existent playlist"); - } catch (XmlRpcException &e) { - } - try { - tsc->deletePlaylist(dummySessionId, id1); - } catch (XmlRpcException &e) { - CPPUNIT_FAIL("cannot delete existing playlist"); - } - try { - tsc->deletePlaylist(dummySessionId, id1); - CPPUNIT_FAIL("allowed to delete non-existent playlist"); - } catch (XmlRpcException &e) { - } + try { + tsc->deletePlaylist(dummySessionId, id2); + CPPUNIT_FAIL("allowed to delete non-existent playlist"); + } catch (XmlRpcException &e) { + } + + try { + tsc->deletePlaylist(dummySessionId, id1); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL("cannot delete existing playlist"); + } + + try { + tsc->deletePlaylist(dummySessionId, id1); + CPPUNIT_FAIL("allowed to delete non-existent playlist"); + } catch (XmlRpcException &e) { + } } @@ -157,12 +173,21 @@ void TestStorageClientTest :: getAllPlaylistsTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref> >::Ref - playlistVector = tsc->getAllPlaylists(dummySessionId); + Ptr::Ref> >::Ref playlistVector; + try { + playlistVector = tsc->getAllPlaylists(dummySessionId); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } CPPUNIT_ASSERT(playlistVector->size() == 2); - Ptr::Ref playlist = (*playlistVector)[0]; - CPPUNIT_ASSERT((int) (playlist->getId()->getId()) == 0x1); + Ptr::Ref playlist; + try { + playlist = (*playlistVector)[0]; + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } + CPPUNIT_ASSERT(int(playlist->getId()->getId()) == 1); } @@ -173,9 +198,18 @@ void TestStorageClientTest :: createPlaylistTest(void) throw (CPPUNIT_NS::Exception) { - Ptr::Ref playlist = tsc->createPlaylist(dummySessionId); + Ptr::Ref playlist; + try { + playlist = tsc->createPlaylist(dummySessionId); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } - CPPUNIT_ASSERT(tsc->existsPlaylist(dummySessionId, playlist->getId())); + try { + CPPUNIT_ASSERT(tsc->existsPlaylist(dummySessionId, playlist->getId())); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } } @@ -189,23 +223,39 @@ TestStorageClientTest :: audioClipTest(void) Ptr::Ref id02(new UniqueId(0x10002)); Ptr::Ref id77(new UniqueId(0x10077)); - CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, id02)); - CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id77)); + try { + CPPUNIT_ASSERT( tsc->existsAudioClip(dummySessionId, id02)); + CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id77)); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } - Ptr::Ref audioClip = tsc->getAudioClip(dummySessionId, id02); + Ptr::Ref audioClip; + try { + audioClip = tsc->getAudioClip(dummySessionId, id02); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } CPPUNIT_ASSERT(audioClip->getId()->getId() == id02->getId()); CPPUNIT_ASSERT(audioClip->getPlaylength()->total_seconds() == 30*60); - Ptr::Ref> >::Ref - audioClipVector - = tsc->getAllAudioClips(dummySessionId); + Ptr::Ref> >::Ref audioClipVector; + try { + audioClipVector = tsc->getAllAudioClips(dummySessionId); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } CPPUNIT_ASSERT(audioClipVector->size() == 3); audioClip = (*audioClipVector)[0]; CPPUNIT_ASSERT((int) (audioClip->getId()->getId()) == 0x10001); - tsc->deleteAudioClip(dummySessionId, id02); + try { + tsc->deleteAudioClip(dummySessionId, id02); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } CPPUNIT_ASSERT(!tsc->existsAudioClip(dummySessionId, id02)); Ptr::Ref title(new Glib::ustring("New Title")); @@ -213,11 +263,29 @@ TestStorageClientTest :: audioClipTest(void) Ptr::Ref uri; Ptr::Ref newAudioClip(new AudioClip(title, playlength, uri)); - CPPUNIT_ASSERT(!newAudioClip->getId()); - tsc->storeAudioClip(dummySessionId, newAudioClip); - Ptr::Ref newId = newAudioClip->getId(); - CPPUNIT_ASSERT(newId); - CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, newId)); + + try { + tsc->storeAudioClip(dummySessionId, newAudioClip); + CPPUNIT_FAIL("Allowed to store audio clip without binary sound file."); + } catch (XmlRpcException &e) { + } + + uri.reset(new std::string("file:var/test10001.mp3")); + newAudioClip->setUri(uri); + try { + CPPUNIT_ASSERT(!newAudioClip->getId()); + tsc->storeAudioClip(dummySessionId, newAudioClip); + CPPUNIT_ASSERT(newAudioClip->getId()); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } + + try { + CPPUNIT_ASSERT(tsc->existsAudioClip(dummySessionId, + newAudioClip->getId())); + } catch (XmlRpcException &e) { + CPPUNIT_FAIL(e.what()); + } } @@ -234,8 +302,7 @@ TestStorageClientTest :: acquireAudioClipTest(void) try { audioClip = tsc->acquireAudioClip(dummySessionId, id2); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { std::string eMsg = "could not acquire audio clip:\n"; eMsg += e.what(); CPPUNIT_FAIL(eMsg); @@ -247,8 +314,7 @@ TestStorageClientTest :: acquireAudioClipTest(void) try { tsc->releaseAudioClip(dummySessionId, audioClip); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { std::string eMsg = "could not release audio clip:\n"; eMsg += e.what(); CPPUNIT_FAIL(eMsg); @@ -257,8 +323,7 @@ TestStorageClientTest :: acquireAudioClipTest(void) try { audioClip = tsc->acquireAudioClip(dummySessionId, id77); CPPUNIT_FAIL("allowed to acquire non-existent audio clip"); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { } } @@ -276,8 +341,7 @@ TestStorageClientTest :: acquirePlaylistTest(void) try { playlist = tsc->acquirePlaylist(dummySessionId, id1); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { std::string eMsg = "could not acquire playlist:\n"; eMsg += e.what(); CPPUNIT_FAIL(eMsg); @@ -295,8 +359,7 @@ TestStorageClientTest :: acquirePlaylistTest(void) string savedTempFilePath = playlist->getUri()->substr(7); try { tsc->releasePlaylist(dummySessionId, playlist); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { std::string eMsg = "could not release playlist:\n"; eMsg += e.what(); CPPUNIT_FAIL(eMsg); @@ -312,7 +375,6 @@ TestStorageClientTest :: acquirePlaylistTest(void) try { playlist = tsc->acquirePlaylist(dummySessionId, id77); CPPUNIT_FAIL("allowed to acquire non-existent playlist"); - } - catch (XmlRpcException &e) { + } catch (XmlRpcException &e) { } } diff --git a/livesupport/modules/storage/src/WebStorageClient.cxx b/livesupport/modules/storage/src/WebStorageClient.cxx index 3750831db..54c9c17eb 100644 --- a/livesupport/modules/storage/src/WebStorageClient.cxx +++ b/livesupport/modules/storage/src/WebStorageClient.cxx @@ -22,7 +22,7 @@ Author : $Author: fgerlits $ - Version : $Revision: 1.22 $ + Version : $Revision: 1.23 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.cxx,v $ ------------------------------------------------------------------------------*/ @@ -814,7 +814,7 @@ WebStorageClient :: getPlaylist(Ptr::Ref sessionId, *----------------------------------------------------------------------------*/ Ptr::Ref WebStorageClient :: editPlaylist(Ptr::Ref sessionId, - Ptr::Ref id) const + Ptr::Ref id) throw (Core::XmlRpcException) { Ptr::Ref playlist(new Playlist(id)); @@ -848,7 +848,7 @@ void WebStorageClient :: editPlaylistGetUrl(Ptr::Ref sessionId, Ptr::Ref id, Ptr::Ref& url, - Ptr::Ref& token) const + Ptr::Ref& token) throw (Core::XmlRpcException) { XmlRpcValue parameters; @@ -905,7 +905,7 @@ WebStorageClient :: editPlaylistGetUrl(Ptr::Ref sessionId, *----------------------------------------------------------------------------*/ void WebStorageClient :: savePlaylist(Ptr::Ref sessionId, - Ptr::Ref playlist) const + Ptr::Ref playlist) throw (Core::XmlRpcException) { if (!playlist || !playlist->getToken()) { diff --git a/livesupport/modules/storage/src/WebStorageClient.h b/livesupport/modules/storage/src/WebStorageClient.h index 7a15602a3..22cea4064 100644 --- a/livesupport/modules/storage/src/WebStorageClient.h +++ b/livesupport/modules/storage/src/WebStorageClient.h @@ -21,8 +21,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Author : $Author: maroy $ - Version : $Revision: 1.16 $ + Author : $Author: fgerlits $ + Version : $Revision: 1.17 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.h,v $ ------------------------------------------------------------------------------*/ @@ -98,8 +98,8 @@ using namespace LiveSupport::Core; * <!ATTLIST location path CDATA #REQUIRED > * * - * @author $Author: maroy $ - * @version $Revision: 1.16 $ + * @author $Author: fgerlits $ + * @version $Revision: 1.17 $ */ class WebStorageClient : virtual public Configurable, @@ -147,7 +147,7 @@ class WebStorageClient : editPlaylistGetUrl(Ptr::Ref sessionId, Ptr::Ref id, Ptr::Ref& url, - Ptr::Ref& token) const + Ptr::Ref& token) throw (XmlRpcException); public: @@ -184,6 +184,20 @@ class WebStorageClient : throw (std::invalid_argument); + /** + * Create a new, empty, playlist. Does not automatically open the + * playlist for editing; for that, use editPlaylist() and + * savePlaylist(). + * + * @param sessionId the session ID from the authentication client + * @return the newly created playlist. + * @exception XmlRpcException if there is a problem with the XML-RPC + * call. + */ + virtual Ptr::Ref + createPlaylist(Ptr::Ref sessionId) + throw (XmlRpcException); + /** * Tell if a playlist with a given id exists. * @@ -200,7 +214,8 @@ class WebStorageClient : throw (XmlRpcException); /** - * Return a playlist with the specified id, to be displayed. + * Return a playlist with the specified id to be displayed. + * If the playlist is being edited, its last saved state is returned. * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -216,7 +231,9 @@ class WebStorageClient : /** - * Return a playlist with the specified id, to be edited. + * Return a playlist with the specified id to be edited. + * This puts a lock on the playlist, and nobody else can edit it + * until we release it using savePlaylist(). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to return. @@ -227,11 +244,13 @@ class WebStorageClient : */ virtual Ptr::Ref editPlaylist(Ptr::Ref sessionId, - Ptr::Ref id) const + Ptr::Ref id) throw (XmlRpcException); /** * Save the playlist after editing. + * Can only be called after we obtained a lock on the playlist using + * editPlaylist(); this method releases the lock. * * @param sessionId the session ID from the authentication client * @param playlist the playlist to save. @@ -241,15 +260,22 @@ class WebStorageClient : */ virtual void savePlaylist(Ptr::Ref sessionId, - Ptr::Ref playlist) const + Ptr::Ref playlist) throw (XmlRpcException); /** * Acquire the resources for the playlist. + * The last saved copy of the playlist is read, and a local copy + * is created in SMIL format. (A local copy is also created for + * each sub-playlist contained in the playlist.) + * The address of this local copy is + * stored in the uri field of the playlist. The SMIL + * file can be played using the Helix client. + * For each audio clip contained (directly or indirectly) in the + * playlist, acquireAudioClip() is called * - * The Playlist returned has a uri field (read using getUri()) - * which points to a playable SMIL file. This URI is a random string + * The URI of the SMIL file is a random string * appended to the temp storage path read from the configuration file, * plus a ".smil" extension. * @@ -269,8 +295,12 @@ class WebStorageClient : /** * Release the resources (audio clips, other playlists) used - * in a playlist. The uri of the playlist is no longer valid, and - * the uri field is deleted. + * in a playlist. + * For each audio clip contained (directly or indirectly) in the + * playlist, releaseAudioClip() is called, and the local copy of + * the playlist (and sub-playlists, if any) is removed. + * The uri field of the playlist is erased (set to + * a null pointer). * * @param sessionId the session ID from the authentication client * @param playlist the playlist to release. @@ -285,6 +315,9 @@ class WebStorageClient : /** * Delete a playlist with the specified id. + * Will refuse to delete the playlist if it is being edited (i.e., + * has been opened with editPlaylist() but has not yet been released + * with savePlaylist()). * * @param sessionId the session ID from the authentication client * @param id the id of the playlist to be deleted. @@ -299,6 +332,7 @@ class WebStorageClient : /** * Return a list of all playlists in the playlist store. + * This is for testing only; will be replaced by a search method. * * Since this makes no sense whatsoever, this method currently returns * an empty list. It will be replaced by a method which uses @@ -313,18 +347,6 @@ class WebStorageClient : getAllPlaylists(Ptr::Ref sessionId) const throw (XmlRpcException); - /** - * Create a new playlist. - * - * @param sessionId the session ID from the authentication client - * @return the newly created playlist. - * @exception XmlRpcException if there is a problem with the XML-RPC - * call. - */ - virtual Ptr::Ref - createPlaylist(Ptr::Ref sessionId) - throw (XmlRpcException); - /** * Tell if an audio clip with a given id exists. * @@ -341,7 +363,10 @@ class WebStorageClient : throw (XmlRpcException); /** - * Return an audio clip with the specified id. + * Return an audio clip with the specified id to be displayed. + * The audio clip returned contains all the metadata (title, author, + * etc.) available for the audio clip, but no binary sound file. + * If you want to play the audio clip, use acquireAudioClip(). * * @param sessionId the session ID from the authentication client * @param id the id of the audio clip to return. @@ -356,15 +381,20 @@ class WebStorageClient : throw (XmlRpcException); /** - * Store an audio clip. The uri field of the audio clip - * is expected to contain the valid URI of a binary audio file. + * Store an audio clip. + * The audio clip is expected to have valid title, + * playlength and uri fields, the latter + * containing the URI of a binary sound file. * - * If the ID of the audio clip is UniqueId::NoId, a new globally unique - * ID is generated, and the audioClip ID is changed to the new ID. - * - * In this testing version, the audio clip URI is expected in the - * form file:relative_path/file_name.mp3. Later this - * should be changed to an absolute URI. + * If the audio clip does not have + * an ID field (i.e., audioClip->getId() is a null + * pointer), one will be generated, and audioClip->getId() + * will contain a valid UniqueId after the method returns. + * If the audio clip had an ID already, then it remains unchanged. + * + * In this testing version, the audio clip URI is expected in the form + * file:relative_path/file_name.mp3. + * Later this should be changed to an absolute URI. * * The size of the binary file must be less than 2 GB, because the * storage server can not deal with larger files. @@ -382,9 +412,13 @@ class WebStorageClient : /** * Acquire the resources for the audio clip with the specified id. + * The uri field of the audio clip returned by the + * method points to a binary sound file playable by the Helix client. + * This binary sound file can be randomly accessed. * - * Returns an AudioClip instance with a valid uri field, which points - * to the binary sound file. + * The returned audio clip also contains a token field + * which identifies it to the storage server; this is used by + * releaseAudioClip(). * * @param sessionId the session ID from the authentication client * @param id the id of the audio clip to acquire. @@ -400,9 +434,10 @@ class WebStorageClient : throw (XmlRpcException); /** - * Release the resource (sound file) used by an audio clip. The - * uri of the audio clip is no longer valid, and the uri field is - * deleted. + * Release the resource (sound file) used by an audio clip. + * After the call to this method, the binary sound file is no longer + * accessible, and the uri and token fields + * of the audioClip are erased (set to null pointers). * * @param sessionId the session ID from the authentication client * @param audioClip the id of the audio clip to release. @@ -431,6 +466,7 @@ class WebStorageClient : /** * Return a list of all audio clips in the playlist store. + * This is for testing only; will be replaced by a search method. * * Since this makes no sense whatsoever, this method currently returns * an empty list. It will be replaced by a method which uses