implemented search() in Storage; it works in the TestStorageClient,

does not work yet in the WebStorageClient
This commit is contained in:
fgerlits 2005-01-19 20:51:48 +00:00
parent 5aef002241
commit 83d1971639
14 changed files with 782 additions and 89 deletions

View File

@ -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/src/AudioClip.cxx,v $
------------------------------------------------------------------------------*/
@ -240,13 +240,17 @@ AudioClip :: configure(const xmlpp::Element & element)
if (!playlength
&& (attribute = element.get_attribute(playlengthAttrName))) {
playlength.reset(new time_duration(
duration_from_string(attribute->get_value())));
playlength.reset(new time_duration(duration_from_string(
attribute->get_value() )));
Ptr<const Glib::ustring>::Ref playlengthString(new const Glib::ustring(
attribute->get_value() ));
setMetadata(playlengthString, extentElementName, extentElementPrefix);
}
if (!title
&& (attribute = element.get_attribute(titleAttrName))) {
title.reset(new const Glib::ustring(attribute->get_value()));
setMetadata(title, titleElementName, titleElementPrefix);
}
if (!uri
@ -326,10 +330,6 @@ AudioClip :: configure(const xmlpp::Element & element)
throw std::invalid_argument(eMsg);
}
Ptr<const Glib::ustring>::Ref playlengthString(new const Glib::ustring(
to_simple_string(*playlength) ));
setMetadata(playlengthString, extentElementName, extentElementPrefix);
if (!title) {
std::string eMsg = "missing attribute ";
eMsg += titleAttrName;
@ -337,8 +337,6 @@ AudioClip :: configure(const xmlpp::Element & element)
eMsg += titleElementPrefix + ":" + titleElementName;
throw std::invalid_argument(eMsg);
}
setMetadata(title, titleElementName, titleElementPrefix);
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.26 $
Version : $Revision: 1.27 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $
------------------------------------------------------------------------------*/
@ -106,12 +106,16 @@ Playlist :: configure(const xmlpp::Element & element)
}
playlength.reset(new time_duration(
duration_from_string(attribute->get_value())));
Ptr<Glib::ustring>::Ref playlengthString(new Glib::ustring(
attribute->get_value() ));
metadata["dcterms:extent"] = playlengthString;
if ((attribute = element.get_attribute(titleAttrName))) {
title.reset(new const Glib::ustring(attribute->get_value()));
} else {
title.reset(new const Glib::ustring(""));
}
metadata["dc:title"] = title;
xmlpp::Node::NodeList childNodes
= element.get_children(elementListAttrName);

View File

@ -7,6 +7,7 @@
<!ELEMENT playlist (playlistElement*) >
<!ATTLIST playlist id NMTOKEN #REQUIRED >
<!ATTLIST playlist playlength NMTOKEN #REQUIRED >
<!ATTLIST playlist title CDATA "" >
<!ELEMENT playlistElement ((audioClip|playlist), fadeInfo?) >
<!ATTLIST playlistElement id NMTOKEN #REQUIRED >
@ -24,9 +25,10 @@
<!ATTLIST fadeInfo fadeOut NMTOKEN #REQUIRED >
]>
<testStorage tempFiles="file:///tmp/tempPlaylist">
<playlist id="0000000000000001" playlength="00:00:34.000" >
<playlist id="0000000000000001" playlength="00:00:34.000"
title="Playlist One">
<playlistElement id="0000000000000101" relativeOffset="0" >
<audioClip id="0000000000010001" playlength="00:00:11.000"
<audioClip id="0000000000010001" playlength="00:00:11.000000"
title="one"
uri="file:var/test10001.mp3" />
</playlistElement>
@ -41,30 +43,31 @@
<playlistElement id="0000000000000103"
relativeOffset="00:00:23.000000" >
<playlist id="0000000000000002"
playlength="00:00:11.000000" >
playlength="00:00:11.000000" title="Playlist Two">
<playlistElement id="0000000000000111" relativeOffset="0" >
<audioClip id="0000000000010003"
playlength="00:00:11.000"
playlength="00:00:11.000000"
title="three"
uri="file:var/test10003.mp3" />
</playlistElement>
</playlist>
</playlistElement>
</playlist>
<playlist id="0000000000000002" playlength="00:00:11.000000" >
<playlist id="0000000000000002" playlength="00:00:11.000000"
title="Playlist Two">
<playlistElement id="0000000000000111" relativeOffset="0" >
<audioClip id="0000000000010003" playlength="00:00:11.000"
title="three"
uri="file:var/test10003.mp3" />
</playlistElement>
</playlist>
<audioClip id="0000000000010001" playlength="01:00:00.000"
<audioClip id="0000000000010001" playlength="00:00:11.000000"
title="one"
uri="file:var/test10001.mp3" />
<audioClip id="0000000000010002" playlength="00:30:00.000"
<audioClip id="0000000000010002" playlength="00:00:12.000000"
title="two"
uri="file:var/test10002.mp3" />
<audioClip id="0000000000010003" playlength="00:30:00.000"
<audioClip id="0000000000010003" playlength="00:00:11.000000"
title="three"
uri="file:var/test10003.mp3" />
</testStorage>

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.1 $
Version : $Revision: 1.2 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/Attic/SearchCriteria.h,v $
------------------------------------------------------------------------------*/
@ -47,6 +47,8 @@
namespace LiveSupport {
namespace Storage {
class TestStorageClient; // forward declaration of friend class
/* ================================================================ constants */
@ -143,6 +145,12 @@ class SearchCriteria
return returnValue;
}
/**
* Give access of private members to the TestStorageClient.
*/
friend class Storage::TestStorageClient;
public:
/**
@ -158,7 +166,7 @@ class SearchCriteria
: limit(0), offset(0)
{
setType(type);
setOperator(logicalOperator);
setLogicalOperator(logicalOperator);
}
/**
@ -202,7 +210,7 @@ class SearchCriteria
* @param logicalOperator either "and" or "or"
*/
void
setOperator(const std::string & logicalOperator)
setLogicalOperator(const std::string & logicalOperator)
throw(std::invalid_argument)
{
std::string lowerCaseOp = lowerCase(logicalOperator);

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.6 $
Version : $Revision: 1.7 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/include/LiveSupport/Storage/StorageClientInterface.h,v $
------------------------------------------------------------------------------*/
@ -47,6 +47,8 @@
#include "LiveSupport/Core/SessionId.h"
#include "LiveSupport/Core/XmlRpcException.h"
#include "LiveSupport/Storage/SearchCriteria.h"
namespace LiveSupport {
namespace Storage {
@ -65,7 +67,7 @@ using namespace Core;
* An interface for storage clients.
*
* @author $Author: fgerlits $
* @version $Revision: 1.6 $
* @version $Revision: 1.7 $
*/
class StorageClientInterface
{
@ -363,6 +365,45 @@ class StorageClientInterface
getAllAudioClips(Ptr<SessionId>::Ref sessionId) const
throw (XmlRpcException)
= 0;
/**
* Search for audio clips or playlists. The results can be read
* using getAudioClipIds() and getPlaylistIds().
*
* @param sessionId the session ID from the authentication client
* @param searchCriteria an object containing the search criteria
* @return the number of items found.
* @exception XmlRpcException if there is a problem with the XML-RPC
* call.
*/
virtual int
search(Ptr<SessionId>::Ref sessionId,
Ptr<SearchCriteria>::Ref searchCriteria)
throw (XmlRpcException)
= 0;
/**
* Return the list of audio clip IDs found by the search method.
*
* (Or the list of audio clip IDs returned by the reset() method
* in WebStorageClient -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getAudioClipIds(void) throw () = 0;
/**
* Return the list of playlist IDs found by the search method.
*
* (Or the list of playlist IDs returned by the reset() method
* in WebStorageClient -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getPlaylistIds(void) throw () = 0;
};

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.31 $
Version : $Revision: 1.32 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.cxx,v $
------------------------------------------------------------------------------*/
@ -199,8 +199,12 @@ TestStorageClient :: configure(const xmlpp::Element & element)
*----------------------------------------------------------------------------*/
Ptr<UniqueId>::Ref
TestStorageClient :: createPlaylist(Ptr<SessionId>::Ref sessionId)
throw ()
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
// generate a new UniqueId -- TODO: fix UniqueId to make sure
// this is really unique; not checked here!
Ptr<UniqueId>::Ref playlistId =
@ -224,8 +228,12 @@ TestStorageClient :: createPlaylist(Ptr<SessionId>::Ref sessionId)
const bool
TestStorageClient :: existsPlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw ()
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
return playlistMap.count(id->getId()) == 1 ? true : false;
}
@ -238,6 +246,10 @@ TestStorageClient :: getPlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
Ptr<Playlist>::Ref playlist;
EditedPlaylistsType::const_iterator
@ -266,6 +278,10 @@ TestStorageClient :: editPlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (editedPlaylists.find(id->getId()) != editedPlaylists.end()) {
throw XmlRpcException("playlist is already being edited");
}
@ -287,6 +303,10 @@ TestStorageClient :: savePlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<Playlist>::Ref playlist)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (! playlist->getToken()) {
throw XmlRpcException("savePlaylist() called without editPlaylist()");
}
@ -327,6 +347,10 @@ TestStorageClient :: acquirePlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
PlaylistMapType::const_iterator playlistMapIt
= playlistMap.find(id->getId());
@ -416,6 +440,10 @@ TestStorageClient :: releasePlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<Playlist>::Ref playlist) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (! playlist->getUri()) {
throw XmlRpcInvalidArgumentException("playlist URI not found");
}
@ -474,6 +502,10 @@ TestStorageClient :: deletePlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (editedPlaylists.find(id->getId()) != editedPlaylists.end()) {
throw XmlRpcException("playlist is being edited");
}
@ -491,8 +523,12 @@ TestStorageClient :: deletePlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<std::vector<Ptr<Playlist>::Ref> >::Ref
TestStorageClient :: getAllPlaylists(Ptr<SessionId>::Ref sessionId)
const
throw ()
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
PlaylistMapType::const_iterator it = playlistMap.begin();
Ptr<std::vector<Ptr<Playlist>::Ref> >::Ref
playlistVector (new std::vector<Ptr<Playlist>::Ref>);
@ -512,8 +548,12 @@ TestStorageClient :: getAllPlaylists(Ptr<SessionId>::Ref sessionId)
const bool
TestStorageClient :: existsAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw ()
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
return audioClipMap.count(id->getId()) == 1 ? true : false;
}
@ -526,6 +566,10 @@ TestStorageClient :: getAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
AudioClipMapType::const_iterator it = audioClipMap.find(id->getId());
if (it == audioClipMap.end()) {
@ -545,6 +589,10 @@ TestStorageClient :: storeAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<AudioClip>::Ref audioClip)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (!audioClip->getUri()) {
throw XmlRpcException("audio clip has no URI field");
}
@ -572,6 +620,10 @@ TestStorageClient :: acquireAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
AudioClipUrisType::const_iterator it = audioClipUris.find(id->getId());
if (it == audioClipUris.end()) {
@ -606,6 +658,10 @@ TestStorageClient :: releaseAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<AudioClip>::Ref audioClip) const
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
if (!audioClip->getUri()) {
throw XmlRpcException("audio clip does not have a URI field");
}
@ -623,6 +679,10 @@ TestStorageClient :: deleteAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
// erase() returns the number of entries found & erased
if (!audioClipMap.erase(id->getId())) {
throw XmlRpcException("no such audio clip");
@ -636,8 +696,12 @@ TestStorageClient :: deleteAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<std::vector<Ptr<AudioClip>::Ref> >::Ref
TestStorageClient :: getAllAudioClips(Ptr<SessionId>::Ref sessionId)
const
throw ()
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
AudioClipMapType::const_iterator it = audioClipMap.begin();
Ptr<std::vector<Ptr<AudioClip>::Ref> >::Ref
audioClipVector (new std::vector<Ptr<AudioClip>::Ref>);
@ -650,3 +714,164 @@ TestStorageClient :: getAllAudioClips(Ptr<SessionId>::Ref sessionId)
return audioClipVector;
}
/*------------------------------------------------------------------------------
* Search for audio clips or playlists.
*----------------------------------------------------------------------------*/
int
TestStorageClient :: search(Ptr<SessionId>::Ref sessionId,
Ptr<SearchCriteria>::Ref searchCriteria)
throw (XmlRpcException)
{
if (!sessionId) {
throw XmlRpcException("missing session ID argument");
}
int counter = 0;
int first = searchCriteria->offset;
int last;
if (searchCriteria->limit) {
last = searchCriteria->offset + searchCriteria->limit;
} else {
last = 0;
}
audioClipIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
playlistIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
if (searchCriteria->type == "audioclip" || searchCriteria->type == "all") {
AudioClipMapType::const_iterator it = audioClipMap.begin();
while (it != audioClipMap.end()) {
if (matchesCriteria(it->second, searchCriteria)) {
if (counter >= first) {
audioClipIds->push_back(it->second->getId());
}
++counter;
if (last && counter >= last) {
return (counter - first);
}
}
++it;
}
}
if (searchCriteria->type == "playlist" || searchCriteria->type == "all") {
PlaylistMapType::const_iterator it = playlistMap.begin();
while (it != playlistMap.end()) {
if (matchesCriteria(it->second, searchCriteria)) {
if (counter >= first) {
playlistIds->push_back(it->second->getId());
}
++counter;
if (last && counter >= last) {
return (counter - first);
}
}
++it;
}
}
return (counter - first);
}
/*------------------------------------------------------------------------------
* See if the Playable instance satisfies the search criteria
*----------------------------------------------------------------------------*/
bool
TestStorageClient :: matchesCriteria(Ptr<Playable>::Ref playable,
Ptr<SearchCriteria>::Ref criteria)
throw (XmlRpcException)
{
bool vetoValue;
if (criteria->logicalOperator == "and") {
vetoValue = false;
} else if (criteria->logicalOperator == "or") {
vetoValue = true;
} else {
std::string eMsg = "unknown logical operator: ";
eMsg += criteria->type;
throw XmlRpcException(eMsg);
}
bool foundAVetoValue = false;
SearchCriteria::SearchConditionListType::const_iterator
it = criteria->searchConditions.begin();
while (it != criteria->searchConditions.end()) {
if (satisfiesCondition(playable, *it) == vetoValue) {
foundAVetoValue = true;
break;
}
++it;
}
if (foundAVetoValue) {
return vetoValue;
} else {
return !vetoValue;
}
}
/*------------------------------------------------------------------------------
* See if the Playable instance satisfies a single condition
*----------------------------------------------------------------------------*/
bool
TestStorageClient :: satisfiesCondition(
Ptr<Playable>::Ref playable,
const SearchCriteria::SearchConditionType & condition)
throw (XmlRpcException)
{
std::string name, nameSpace;
separateNameAndNameSpace(condition.key, name, nameSpace);
Ptr<Glib::ustring>::Ref value = playable->getMetadata(name, nameSpace);
if (!value) {
return false;
}
std::string op = condition.comparisonOperator;
if (op == "=") {
return (*value == condition.value);
} else if (op == "partial") {
return (value->find(condition.value) != std::string::npos);
} else if (op == "prefix") {
return (value->find(condition.value) == 0);
} else if (op == "<") {
return (*value < condition.value);
} else if (op == "<=") {
return (*value <= condition.value);
} else if (op == ">") {
return (*value > condition.value);
} else if (op == ">=") {
return (*value >= condition.value);
} else {
std::string eMsg = "unknown comparison operator: ";
eMsg += op;
throw XmlRpcException(eMsg);
}
}
/*------------------------------------------------------------------------------
* Separate a key into the metadata name and its namespace
*----------------------------------------------------------------------------*/
void
LiveSupport::Storage :: separateNameAndNameSpace(const std::string & key,
std::string & name,
std::string & nameSpace)
throw ()
{
unsigned int colonPosition = key.find(':');
if (colonPosition != std::string::npos) { // there is a colon
nameSpace = key.substr(0, colonPosition);
name = key.substr(colonPosition+1);
} else { // no colon found
nameSpace = "";
name = key;
}
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.25 $
Version : $Revision: 1.26 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.h,v $
------------------------------------------------------------------------------*/
@ -42,11 +42,7 @@
#include <stdexcept>
#include "LiveSupport/Core/Ptr.h"
#include "LiveSupport/Core/UniqueId.h"
#include "LiveSupport/Core/Playlist.h"
#include "LiveSupport/Core/Configurable.h"
#include "LiveSupport/Core/SessionId.h"
#include "LiveSupport/Storage/StorageClientInterface.h"
@ -90,7 +86,7 @@ using namespace LiveSupport::Core;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.25 $
* @version $Revision: 1.26 $
*/
class TestStorageClient :
virtual public Configurable,
@ -151,6 +147,34 @@ class TestStorageClient :
*/
std::string localTempStorage;
/**
* A vector containing the unique IDs of the audio clips returned
* by search().
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref audioClipIds;
/**
* A vector containing the unique IDs of the playlists returned
* by search().
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref playlistIds;
/**
* Auxilliary method used by search().
*/
bool
matchesCriteria(Ptr<Playable>::Ref playable,
Ptr<SearchCriteria>::Ref criteria)
throw (XmlRpcException);
/**
* Auxilliary method used by matchesCriteria().
*/
bool
satisfiesCondition(
Ptr<Playable>::Ref playable,
const SearchCriteria::SearchConditionType & condition)
throw (XmlRpcException);
public:
/**
@ -195,7 +219,7 @@ class TestStorageClient :
*/
virtual Ptr<UniqueId>::Ref
createPlaylist(Ptr<SessionId>::Ref sessionId)
throw ();
throw (XmlRpcException);
/**
@ -209,7 +233,7 @@ class TestStorageClient :
virtual const bool
existsPlaylist(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw ();
throw (XmlRpcException);
/**
@ -344,7 +368,7 @@ class TestStorageClient :
*/
virtual Ptr<std::vector<Ptr<Playlist>::Ref> >::Ref
getAllPlaylists(Ptr<SessionId>::Ref sessionId) const
throw ();
throw (XmlRpcException);
/**
@ -358,7 +382,7 @@ class TestStorageClient :
virtual const bool
existsAudioClip(Ptr<SessionId>::Ref sessionId,
Ptr<UniqueId>::Ref id) const
throw ();
throw (XmlRpcException);
/**
* Return an audio clip with the specified id to be displayed.
@ -465,7 +489,57 @@ class TestStorageClient :
*/
virtual Ptr<std::vector<Ptr<AudioClip>::Ref> >::Ref
getAllAudioClips(Ptr<SessionId>::Ref sessionId) const
throw ();
throw (XmlRpcException);
/**
* Search for audio clips or playlists. The results can be read
* using getAudioClipIds() and getPlaylistIds().
*
* If an audio clip or playlist does not have a metadata field X,
* it does not match any condition about field X. In particular,
* a search for ("X", "partial", "") returns all records
* which contain a metadata field X.
*
* @param sessionId the session ID from the authentication client
* @param searchCriteria an object containing the search criteria
* @return the number of items found.
* @exception XmlRpcException if there is a problem with the XML-RPC
* call.
*/
virtual int
search(Ptr<SessionId>::Ref sessionId,
Ptr<SearchCriteria>::Ref searchCriteria)
throw (XmlRpcException);
/**
* Return the list of audio clip IDs found by the search method.
*
* (Or the list of audio clip IDs returned by the reset() method
* -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getAudioClipIds(void) throw ()
{
return audioClipIds;
}
/**
* Return the list of playlist IDs found by the search method.
*
* (Or the list of playlist IDs returned by the reset() method
* -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getPlaylistIds(void) throw ()
{
return playlistIds;
}
};
@ -474,8 +548,16 @@ class TestStorageClient :
/* ====================================================== function prototypes */
/**
* Auxilliary method used by satisfiesCondition().
*/
void
separateNameAndNameSpace(const std::string & key,
std::string & name,
std::string & nameSpace)
throw ();
} // namespace Core
} // namespace Storage
} // namespace LiveSupport
#endif // TestStorageClient_h

View File

@ -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/TestStorageClientTest.cxx,v $
------------------------------------------------------------------------------*/
@ -132,6 +132,7 @@ TestStorageClientTest :: firstTest(void)
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(playlist->getId());
CPPUNIT_ASSERT(playlist->getId()->getId() == id1->getId());
}
@ -238,7 +239,7 @@ TestStorageClientTest :: audioClipTest(void)
}
CPPUNIT_ASSERT(audioClip->getId()->getId() == id02->getId());
CPPUNIT_ASSERT(audioClip->getPlaylength()->total_seconds()
== 30*60);
== 12);
Ptr<std::vector<Ptr<AudioClip>::Ref> >::Ref audioClipVector;
try {
@ -378,3 +379,68 @@ TestStorageClientTest :: acquirePlaylistTest(void)
} catch (XmlRpcException &e) {
}
}
/*------------------------------------------------------------------------------
* Search test.
*----------------------------------------------------------------------------*/
void
TestStorageClientTest :: searchTest(void)
throw (CPPUNIT_NS::Exception)
{
try {
Ptr<SearchCriteria>::Ref criteria(new SearchCriteria(
"audioClip",
"dcterms:extent", "=", "00:00:11.000000"));
int numberFound = tsc->search(dummySessionId, criteria);
CPPUNIT_ASSERT(numberFound == 2);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->size() == 2);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->at(0)->getId() == 0x10001);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->at(1)->getId() == 0x10003);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->size() == 0);
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL(e.what());
} catch (Core::XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
try {
Ptr<SearchCriteria>::Ref criteria(new SearchCriteria("all", "or"));
criteria->addCondition("dcterms:extent", ">", "00:00:11.000000");
criteria->addCondition("dc:title", "prefix", "Playlist");
int numberFound = tsc->search(dummySessionId, criteria);
CPPUNIT_ASSERT(numberFound == 3);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->size() == 1);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->at(0)->getId() == 0x10002);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->size() == 2);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->at(0)->getId() == 1);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->at(1)->getId() == 2);
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL(e.what());
} catch (Core::XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
try {
Ptr<SearchCriteria>::Ref criteria(new SearchCriteria);
criteria->setType("all");
criteria->addCondition("dc:title", "partial", "t");
criteria->setLimit(2);
criteria->setOffset(1);
int numberFound = tsc->search(dummySessionId, criteria);
CPPUNIT_ASSERT(numberFound == 2);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->size() == 1);
CPPUNIT_ASSERT(tsc->getAudioClipIds()->at(0)->getId() == 0x10003);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->size() == 1);
CPPUNIT_ASSERT(tsc->getPlaylistIds()->at(0)->getId() == 1);
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL(e.what());
} catch (Core::XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.8 $
Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClientTest.h,v $
------------------------------------------------------------------------------*/
@ -58,7 +58,7 @@ namespace Storage {
* Unit test for the UploadPlaylistMetohd class.
*
* @author $Author: fgerlits $
* @version $Revision: 1.8 $
* @version $Revision: 1.9 $
* @see TestStorageClient
*/
class TestStorageClientTest : public CPPUNIT_NS::TestFixture
@ -71,6 +71,7 @@ class TestStorageClientTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(audioClipTest);
CPPUNIT_TEST(acquireAudioClipTest);
CPPUNIT_TEST(acquirePlaylistTest);
CPPUNIT_TEST(searchTest);
CPPUNIT_TEST_SUITE_END();
private:
@ -142,6 +143,14 @@ class TestStorageClientTest : public CPPUNIT_NS::TestFixture
void
acquirePlaylistTest(void) throw (CPPUNIT_NS::Exception);
/**
* Testing the search operations.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
searchTest(void) throw (CPPUNIT_NS::Exception);
public:

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.29 $
Version : $Revision: 1.30 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.cxx,v $
------------------------------------------------------------------------------*/
@ -197,6 +197,35 @@ static const std::string resetStorageAudioClipResultParamName = "audioclips";
static const std::string resetStoragePlaylistResultParamName = "playlists";
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: search */
/*------------------------------------------------------------------------------
* The name of the search method on the storage server
*----------------------------------------------------------------------------*/
static const std::string searchMethodName
= "locstor.searchMetadata";
/*------------------------------------------------------------------------------
* The name of the session ID parameter in the input structure
*----------------------------------------------------------------------------*/
static const std::string searchSessionIdParamName = "sessid";
/*------------------------------------------------------------------------------
* The name of the search criteria parameter in the input structure
*----------------------------------------------------------------------------*/
static const std::string searchCriteriaParamName = "criteria";
/*------------------------------------------------------------------------------
* The name of the audio clips result parameter returned by the method
*----------------------------------------------------------------------------*/
static const std::string searchAudioClipResultParamName = "audioClipResults";
/*------------------------------------------------------------------------------
* The name of the playlists result parameter returned by the method
*----------------------------------------------------------------------------*/
static const std::string searchPlaylistResultParamName = "playlistResults";
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ playlist methods */
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ storage server constants: createPlaylist */
@ -1864,7 +1893,7 @@ WebStorageClient :: reset(void)
}
XmlRpcValue audioClipArray = result[resetStorageAudioClipResultParamName];
testAudioClipIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
audioClipIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
for (int i=0; i < audioClipArray.size(); i++) {
if (audioClipArray[i].getType() != XmlRpcValue::TypeString) {
@ -1877,11 +1906,11 @@ WebStorageClient :: reset(void)
}
Ptr<UniqueId>::Ref uniqueId(new UniqueId(std::string(
audioClipArray[i])));
testAudioClipIds->push_back(uniqueId);
audioClipIds->push_back(uniqueId);
}
XmlRpcValue playlistArray = result[resetStoragePlaylistResultParamName];
testPlaylistIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
playlistIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
for (int i=0; i < playlistArray.size(); i++) {
if (playlistArray[i].getType() != XmlRpcValue::TypeString) {
@ -1894,7 +1923,101 @@ WebStorageClient :: reset(void)
}
Ptr<UniqueId>::Ref uniqueId(new UniqueId(std::string(
playlistArray[i])));
testPlaylistIds->push_back(uniqueId);
playlistIds->push_back(uniqueId);
}
}
/*------------------------------------------------------------------------------
* Search for audio clips or playlists.
*----------------------------------------------------------------------------*/
int
WebStorageClient :: search(Ptr<SessionId>::Ref sessionId,
Ptr<SearchCriteria>::Ref searchCriteria)
throw (XmlRpcException)
{
XmlRpcValue parameters;
XmlRpcValue result;
XmlRpcClient xmlRpcClient(storageServerName.c_str(), storageServerPort,
storageServerPath.c_str(), false);
parameters.clear();
parameters[searchSessionIdParamName]
= sessionId->getId();
parameters[searchCriteriaParamName]
= *searchCriteria;
// std::cerr << "\nparams: " << parameters.toXml() << "\n";
result.clear();
if (!xmlRpcClient.execute(searchMethodName.c_str(),
parameters, result)) {
xmlRpcClient.close();
std::string eMsg = "cannot execute XML-RPC method '";
eMsg += searchMethodName;
eMsg += "'";
throw XmlRpcCommunicationException(eMsg);
}
xmlRpcClient.close();
// std::cerr << "result: " << result.toXml() << "\n";
if (xmlRpcClient.isFault()) {
std::stringstream eMsg;
eMsg << "XML-RPC method '"
<< searchMethodName
<< "' returned error message:\n"
<< result;
throw XmlRpcMethodFaultException(eMsg.str());
}
if (! result.hasMember(searchAudioClipResultParamName)
|| result[searchAudioClipResultParamName].getType()
!= XmlRpcValue::TypeArray
|| ! result.hasMember(searchPlaylistResultParamName)
|| result[searchPlaylistResultParamName].getType()
!= XmlRpcValue::TypeArray) {
std::stringstream eMsg;
eMsg << "XML-RPC method '"
<< searchMethodName
<< "' returned unexpected value:\n"
<< result;
throw XmlRpcMethodResponseException(eMsg.str());
}
XmlRpcValue audioClipArray = result[searchAudioClipResultParamName];
audioClipIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
for (int i=0; i < audioClipArray.size(); i++) {
if (audioClipArray[i].getType() != XmlRpcValue::TypeString) {
std::stringstream eMsg;
eMsg << "Non-string audio clip gunid returned by XML-RPC method '"
<< searchMethodName
<< "':\n"
<< result;
throw XmlRpcMethodResponseException(eMsg.str());
}
Ptr<UniqueId>::Ref uniqueId(new UniqueId(std::string(
audioClipArray[i])));
audioClipIds->push_back(uniqueId);
}
XmlRpcValue playlistArray = result[searchPlaylistResultParamName];
playlistIds.reset(new std::vector<Ptr<UniqueId>::Ref>);
for (int i=0; i < playlistArray.size(); i++) {
if (playlistArray[i].getType() != XmlRpcValue::TypeString) {
std::stringstream eMsg;
eMsg << "Non-string playlist gunid returned by XML-RPC method '"
<< searchMethodName
<< "':\n"
<< result;
throw XmlRpcMethodResponseException(eMsg.str());
}
Ptr<UniqueId>::Ref uniqueId(new UniqueId(std::string(
playlistArray[i])));
playlistIds->push_back(uniqueId);
}
return audioClipIds->size() + playlistIds->size();
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.20 $
Version : $Revision: 1.21 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClient.h,v $
------------------------------------------------------------------------------*/
@ -42,11 +42,8 @@
#include <stdexcept>
#include "LiveSupport/Core/Ptr.h"
#include "LiveSupport/Core/UniqueId.h"
#include "LiveSupport/Core/Playlist.h"
#include "LiveSupport/Core/Configurable.h"
#include "LiveSupport/Core/SessionId.h"
#include "LiveSupport/Storage/StorageClientInterface.h"
@ -99,7 +96,7 @@ using namespace LiveSupport::Core;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.20 $
* @version $Revision: 1.21 $
*/
class WebStorageClient :
virtual public Configurable,
@ -162,6 +159,19 @@ class WebStorageClient :
Ptr<const std::string>::Ref& token)
throw (XmlRpcException);
/**
* A vector containing the unique IDs of the audio clips returned
* by reset() (for testing) or by search().
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref audioClipIds;
/**
* A vector containing the unique IDs of the playlists returned
* by reset() (for testing) or by search().
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref playlistIds;
public:
/**
* A virtual destructor, as this class has virtual functions.
@ -505,18 +515,6 @@ class WebStorageClient :
throw (XmlRpcException);
/**
* A vector containing the unique IDs of the audio clips in the
* storage. Set by reset(). Used for testing.
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref testAudioClipIds;
/**
* A vector containing the unique IDs of the playlists in the
* storage. Set by reset(). Used for testing.
*/
Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref testPlaylistIds;
/**
* Reset the storage to its initial state.
* Calls locstor.resetStorage, and puts the unique IDs returned
@ -527,6 +525,51 @@ class WebStorageClient :
void
reset(void)
throw (XmlRpcException);
/**
* Search for audio clips or playlists. The results can be read
* using getAudioClipIds() and getPlaylistIds().
*
* @param sessionId the session ID from the authentication client
* @param searchCriteria an object containing the search criteria
* @return the number of items found.
* @exception XmlRpcException if there is a problem with the XML-RPC
* call.
*/
virtual int
search(Ptr<SessionId>::Ref sessionId,
Ptr<SearchCriteria>::Ref searchCriteria)
throw (XmlRpcException);
/**
* Return the list of audio clip IDs found by the search method.
*
* (Or the list of audio clip IDs returned by the reset() method
* -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getAudioClipIds(void) throw ()
{
return audioClipIds;
}
/**
* Return the list of playlist IDs found by the search method.
*
* (Or the list of playlist IDs returned by the reset() method
* -- used for testing.)
*
* @return a vector of UniqueId objects.
*/
virtual Ptr<std::vector<Ptr<UniqueId>::Ref> >::Ref
getPlaylistIds(void) throw ()
{
return playlistIds;
}
};

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.30 $
Version : $Revision: 1.31 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.cxx,v $
------------------------------------------------------------------------------*/
@ -186,8 +186,8 @@ WebStorageClientTest :: playlistTest(void)
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->testAudioClipIds->size() >= 3);
Ptr<UniqueId>::Ref audioClipId = wsc->testAudioClipIds->at(0);
CPPUNIT_ASSERT(wsc->getAudioClipIds()->size() >= 3);
Ptr<UniqueId>::Ref audioClipId = wsc->getAudioClipIds()->at(0);
Ptr<SessionId>::Ref sessionId;
try {
@ -365,12 +365,12 @@ WebStorageClientTest :: audioClipTest(void)
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->testAudioClipIds->size() >= 2);
Ptr<UniqueId>::Ref id01 = wsc->testAudioClipIds->at(1);
CPPUNIT_ASSERT(wsc->getAudioClipIds()->size() >= 2);
Ptr<UniqueId>::Ref id01 = wsc->getAudioClipIds()->at(1);
// std::cout << "\nReset storage result:\n";
// for (unsigned i=0; i < wsc->testAudioClipIds->size(); i++) {
// std::cout << std::hex << std::string(*wsc->testAudioClipIds->at(i))
// for (unsigned i=0; i < wsc->getAudioClipIds()->size(); i++) {
// std::cout << std::hex << std::string(*wsc->getAudioClipIds()->at(i))
// << std::endl;
// }
@ -504,8 +504,8 @@ WebStorageClientTest :: simplePlaylistTest(void)
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->testAudioClipIds->size() >= 3);
Ptr<UniqueId>::Ref audioClipId = wsc->testAudioClipIds->at(0);
CPPUNIT_ASSERT(wsc->getAudioClipIds()->size() >= 3);
Ptr<UniqueId>::Ref audioClipId = wsc->getAudioClipIds()->at(0);
Ptr<SessionId>::Ref sessionId;
try {
@ -575,6 +575,74 @@ WebStorageClientTest :: simplePlaylistTest(void)
}
CPPUNIT_ASSERT(!newPlaylist->getUri());
*/
try{
authentication->logout(sessionId);
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
}
/*------------------------------------------------------------------------------
* Search test.
*----------------------------------------------------------------------------*/
void
WebStorageClientTest :: searchTest(void)
throw (CPPUNIT_NS::Exception)
{
/*
try {
wsc->reset();
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->getAudioClipIds()->size() >= 3);
Ptr<UniqueId>::Ref audioClip0 = wsc->getAudioClipIds()->at(0);
Ptr<UniqueId>::Ref audioClip1 = wsc->getAudioClipIds()->at(1);
Ptr<UniqueId>::Ref audioClip2 = wsc->getAudioClipIds()->at(2);
CPPUNIT_ASSERT(wsc->getPlaylistIds()->size() >= 1);
Ptr<UniqueId>::Ref playlist0 = wsc->getPlaylistIds()->at(0);
Ptr<SessionId>::Ref sessionId;
try {
sessionId = authentication->login("root", "q");
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(sessionId);
try {
Ptr<SearchCriteria>::Ref criteria(new SearchCriteria(
"audioClip",
"dc:title", "prefix", "File"));
int results = wsc->search(sessionId, criteria);
CPPUNIT_ASSERT(results == 2);
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->getAudioClipIds()->size() == 2);
CPPUNIT_ASSERT(*wsc->getAudioClipIds()->at(0) == *audioClip0);
CPPUNIT_ASSERT(*wsc->getAudioClipIds()->at(1) == *audioClip1);
try {
Ptr<SearchCriteria>::Ref criteria(new SearchCriteria(
"playlist", "or"));
criteria->addCondition("dcterms:extent", ">=", "0");
criteria->setLimit(10);
int results = wsc->search(sessionId, criteria);
CPPUNIT_ASSERT(results == 1);
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
CPPUNIT_ASSERT(wsc->getPlaylistIds()->size() == 1);
CPPUNIT_ASSERT(*wsc->getPlaylistIds()->at(0) == *playlist0);
try{
authentication->logout(sessionId);
} catch (XmlRpcException &e) {
CPPUNIT_FAIL(e.what());
}
*/
}

View File

@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Author : $Author: maroy $
Version : $Revision: 1.6 $
Author : $Author: fgerlits $
Version : $Revision: 1.7 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/WebStorageClientTest.h,v $
------------------------------------------------------------------------------*/
@ -62,8 +62,8 @@ using namespace LiveSupport::Authentication;
/**
* Unit test for the UploadPlaylistMetohd class.
*
* @author $Author: maroy $
* @version $Revision: 1.6 $
* @author $Author: fgerlits $
* @version $Revision: 1.7 $
* @see WebStorageClient
*/
class WebStorageClientTest : public CPPUNIT_NS::TestFixture
@ -73,6 +73,7 @@ class WebStorageClientTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(simplePlaylistTest);
CPPUNIT_TEST(playlistTest);
CPPUNIT_TEST(audioClipTest);
CPPUNIT_TEST(searchTest);
CPPUNIT_TEST_SUITE_END();
private:
@ -120,6 +121,14 @@ class WebStorageClientTest : public CPPUNIT_NS::TestFixture
void
playlistTest(void) throw (CPPUNIT_NS::Exception);
/**
* Testing the search operations.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
searchTest(void) throw (CPPUNIT_NS::Exception);
public:

View File

@ -1,9 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<smil>
<body>
<seq>
<audio src="gunid:///123456789abcdef1"/>
<audio src="gunid:///123456789abcdef2"/>
</seq>
</body>
</smil>
<playlist id="1" playlength="00:00:23.000"
title="My First Playlist">
<playlistElement id="101" relativeOffset="0" >
<audioClip id="10001" playlength="00:00:11.000"
title="one" />
</playlistElement>
<playlistElement id="102" relativeOffset="00:00:11.000000" >
<audioClip id="10002" playlength="00:00:12.000000"
title="two" />
</playlistElement>
<metadata
xmlns="http://www.streamonthefly.org/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns:xbmf="http://www.streamonthefly.org/xbmf"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<dc:title>My First Playlist</dc:title>
<dc:creator>Me, myself and I</dc:creator>
<dcterms:extent>00:00:23.000000</dcterms:extent>
</metadata>
</playlist>