From df58fd8fcf0185b17c183079ee3df08461c2c0ff Mon Sep 17 00:00:00 2001
From: fgerlits <fgerlits@cfc7b370-4200-0410-a6e3-cb6bdb053afe>
Date: Fri, 21 Jan 2005 21:15:21 +0000
Subject: [PATCH] added TagConversion class to module core

---
 livesupport/modules/core/etc/Makefile.in      |  10 +-
 .../modules/core/etc/tagConversionTable.xml   |  22 ++
 .../include/LiveSupport/Core/TagConversion.h  | 191 ++++++++++++++++++
 .../modules/core/src/TagConversion.cxx        | 139 +++++++++++++
 .../modules/core/src/TagConversionTest.cxx    | 135 +++++++++++++
 .../modules/core/src/TagConversionTest.h      | 107 ++++++++++
 6 files changed, 600 insertions(+), 4 deletions(-)
 create mode 100644 livesupport/modules/core/etc/tagConversionTable.xml
 create mode 100644 livesupport/modules/core/include/LiveSupport/Core/TagConversion.h
 create mode 100644 livesupport/modules/core/src/TagConversion.cxx
 create mode 100644 livesupport/modules/core/src/TagConversionTest.cxx
 create mode 100644 livesupport/modules/core/src/TagConversionTest.h

diff --git a/livesupport/modules/core/etc/Makefile.in b/livesupport/modules/core/etc/Makefile.in
index f1e37bd8a..28fa8e3cf 100644
--- a/livesupport/modules/core/etc/Makefile.in
+++ b/livesupport/modules/core/etc/Makefile.in
@@ -20,8 +20,8 @@
 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
 #
-#   Author   : $Author: maroy $
-#   Version  : $Revision: 1.23 $
+#   Author   : $Author: fgerlits $
+#   Version  : $Revision: 1.24 $
 #   Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/etc/Makefile.in,v $
 #
 #   @configure_input@
@@ -119,7 +119,8 @@ CORE_LIB_OBJS = ${TMP_DIR}/UniqueId.o \
                 ${TMP_DIR}/LocalizedConfigurable.o \
                 ${TMP_DIR}/Md5.o \
                 ${TMP_DIR}/XmlRpcTools.o \
-                ${TMP_DIR}/XmlRpcException.o
+                ${TMP_DIR}/XmlRpcException.o \
+                ${TMP_DIR}/TagConversion.o
 
 TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
                    ${TMP_DIR}/UniqueIdTest.o \
@@ -133,7 +134,8 @@ TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
                    ${TMP_DIR}/LocalizedObjectTest.o \
                    ${TMP_DIR}/LocalizedConfigurableTest.o \
                    ${TMP_DIR}/Md5Test.o \
-                   ${TMP_DIR}/XmlRpcToolsTest.o
+                   ${TMP_DIR}/XmlRpcToolsTest.o \
+                   ${TMP_DIR}/TagConversionTest.o
 
 TEST_RUNNER_RES = ${TMP_DIR}/${PACKAGE_NAME}_root.res \
                   ${TMP_DIR}/${PACKAGE_NAME}_en.res \
diff --git a/livesupport/modules/core/etc/tagConversionTable.xml b/livesupport/modules/core/etc/tagConversionTable.xml
new file mode 100644
index 000000000..c426e8746
--- /dev/null
+++ b/livesupport/modules/core/etc/tagConversionTable.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE tagConversionTable [
+<!ELEMENT tagConversionTable (tag*) >
+<!ELEMENT tag ((id3, dc)*) >
+<!ELEMENT id3 (CDATA) >
+<!ELEMENT dc  (CDATA) >
+]>
+
+<tagConversionTable>
+    <tag>
+        <id3>Title</id3>
+        <dc>dc:title</dc>
+    </tag>
+    <tag>
+        <id3>Artist</id3>
+        <dc>dc:creator</dc>
+    </tag>
+    <tag>
+        <id3>Length</id3>
+        <dc>dcterms:extent</dc>
+    </tag>
+</tagConversionTable>
diff --git a/livesupport/modules/core/include/LiveSupport/Core/TagConversion.h b/livesupport/modules/core/include/LiveSupport/Core/TagConversion.h
new file mode 100644
index 000000000..6a987d3c0
--- /dev/null
+++ b/livesupport/modules/core/include/LiveSupport/Core/TagConversion.h
@@ -0,0 +1,191 @@
+/*------------------------------------------------------------------------------
+
+    Copyright (c) 2004 Media Development Loan Fund
+ 
+    This file is part of the LiveSupport project.
+    http://livesupport.campware.org/
+    To report bugs, send an e-mail to bugs@campware.org
+ 
+    LiveSupport is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+  
+    LiveSupport is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with LiveSupport; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+ 
+    Author   : $Author: fgerlits $
+    Version  : $Revision: 1.1 $
+    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Attic/TagConversion.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef LiveSupport_Core_TagConversion_h
+#define LiveSupport_Core_TagConversion_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include <stdexcept>
+#include <string>
+#include <libxml++/libxml++.h>
+
+#include "LiveSupport/Core/Ptr.h"
+
+
+namespace LiveSupport {
+namespace Core {
+
+using namespace LiveSupport::Core;
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ *  A class wrapper of an id3v2-to-Dublin Core conversion table.
+ *  
+ *  For a description of these metadata tag standards, see 
+ *  http://www.id3.org/id3v2.4.0-frames.txt
+ *  and http://dublincore.org/documents/dces/.
+ * 
+ *  This object has to be configured with an XML configuration element
+ *  called tagConversionTable. This may look like the following:
+ *
+ *  <pre><code>
+ *  &lt;tagConversionTable&gt;
+ *         &lt;tag&gt;
+ *             &lt;id3&gt;Title&lt;/id3&gt;
+ *             &lt;dc&gt;dc:title&lt;/dc&gt;
+ *         &lt;/tag&gt;
+ *         &lt;tag&gt;
+ *             &lt;id3&gt;Length&lt;/id3&gt;
+ *             &lt;dc&gt;dcterms:extent&lt;/dc&gt;
+ *         &lt;/tag&gt;
+ *             ...
+ *  &lt;/tagConversionTable&gt;
+ *  </code></pre>
+ *
+ *  @author  $Author: fgerlits $
+ *  @version $Revision: 1.1 $
+ */
+class TagConversion
+{
+    private:
+        /**
+         *  The name of the configuration XML element used by this class.
+         */
+        static const std::string            configElementNameStr;
+
+        /**
+         *  The type for the conversion table.
+         */
+        typedef std::map<const std::string, const std::string>
+                                            TableType;
+
+        /**
+         *  The conversion table, as read from the configuration file.
+         */
+        static Ptr<TableType>::Ref          table;
+
+        /**
+         *  The default constructor.
+         */
+        TagConversion(void)                        throw ()
+        {
+        }
+
+
+    public:
+        /**
+         *  Return the name of the XML element this class expects
+         *  to be sent to a call to configure().
+         *  
+         *  @return the name of the expected XML configuration element.
+         */
+        static const std::string
+        getConfigElementName(void)                      throw ()
+        {
+            return configElementNameStr;
+        }
+
+        /**
+         *  Configure the class based on the XML element supplied.
+         *  The supplied element is expected to be of the name
+         *  returned by configElementName().
+         *
+         *  @param element the XML element to configure the object from.
+         *  @exception std::invalid_argument if the supplied XML element
+         *             contains bad configuration information
+         */
+        static void
+        configure(const xmlpp::Element    & element)
+                                                throw (std::invalid_argument);
+
+        /**
+         *  Check whether the class has been configured.
+         *
+         *  @return true or false
+         */
+        static bool
+        isConfigured(void)                      throw ()
+        {
+            return (table.get() != 0);
+        }
+
+        /**
+         *  Check whether a given id3v2 tag is listed in the table.
+         *
+         *  @return true or false
+         */
+        static bool
+        existsId3Tag(const std::string &id3Tag) throw (std::invalid_argument)
+        {
+            if (table) {
+                return (table->find(id3Tag) != table->end());
+            } else {
+                throw std::invalid_argument("conversion table has "
+                                            "not been configured");
+            }
+        }
+
+        /**
+         *  Convert an id3v2 tag to a Dublin Core tag (with namespace).
+         *
+         *  @return the converted tag
+         */
+        static const std::string &
+        id3ToDublinCore(const std::string &id3Tag)
+                                                throw (std::invalid_argument);
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Core
+} // namespace LiveSupport
+
+#endif // LiveSupport_Core_TagConversion_h
+
diff --git a/livesupport/modules/core/src/TagConversion.cxx b/livesupport/modules/core/src/TagConversion.cxx
new file mode 100644
index 000000000..b7c611cfc
--- /dev/null
+++ b/livesupport/modules/core/src/TagConversion.cxx
@@ -0,0 +1,139 @@
+/*------------------------------------------------------------------------------
+
+    Copyright (c) 2004 Media Development Loan Fund
+ 
+    This file is part of the LiveSupport project.
+    http://livesupport.campware.org/
+    To report bugs, send an e-mail to bugs@campware.org
+ 
+    LiveSupport is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+  
+    LiveSupport is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with LiveSupport; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+ 
+    Author   : $Author: fgerlits $
+    Version  : $Revision: 1.1 $
+    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Attic/TagConversion.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include "LiveSupport/Core/TagConversion.h"
+
+
+using namespace xmlpp;
+using namespace LiveSupport::Core;
+
+/* ===================================================  local data structures */
+
+/*------------------------------------------------------------------------------
+ *  The name of the config element for this class
+ *----------------------------------------------------------------------------*/
+const std::string   TagConversion::configElementNameStr = "tagConversionTable";
+
+/*------------------------------------------------------------------------------
+ *  Initialize the table to a null pointer at program start
+ *----------------------------------------------------------------------------*/
+Ptr<TagConversion::TableType>::Ref
+                    TagConversion::table = Ptr<TagConversion::TableType>::Ref();
+
+
+/* ================================================  local constants & macros */
+
+/**
+ *  The name of the tag child element.
+ */
+static const std::string    tagElementName = "tag";
+
+/**
+ *  The name of the id3v2 tag grandchild element.
+ */
+static const std::string    id3TagElementName = "id3";
+
+/**
+ *  The name of the dublin core tag grandchild element.
+ */
+static const std::string    dcTagElementName = "dc";
+
+
+/* ===============================================  local function prototypes */
+
+
+/* =============================================================  module code */
+
+/*------------------------------------------------------------------------------
+ *  Configure the class based on the XML element supplied.
+ *----------------------------------------------------------------------------*/
+void
+TagConversion :: configure(const xmlpp::Element  & element)
+                                               throw (std::invalid_argument)
+{
+    if (element.get_name() != configElementNameStr) {
+        std::string eMsg = "bad configuration element ";
+        eMsg += element.get_name();
+        throw std::invalid_argument(eMsg);
+    }
+    
+    table.reset(new TableType);         // discard old table, if any
+    
+    Node::NodeList
+                listOfTags  = element.get_children(tagElementName);
+    Node::NodeList::iterator
+                listIt      = listOfTags.begin();
+
+    while (listIt != listOfTags.end()) {
+        Node::NodeList  id3Tags = (*listIt)->get_children(id3TagElementName);
+        Node::NodeList  dcTags  = (*listIt)->get_children(dcTagElementName);
+        
+        if (id3Tags.size() != 1 || dcTags.size() != 1) {
+            std::string eMsg = "bad <";
+            eMsg += tagElementName;
+            eMsg += "> element found";
+            throw std::invalid_argument(eMsg);
+        }
+
+        Element*    id3Element  = dynamic_cast<Element*> (id3Tags.front());
+        Element*    dcElement   = dynamic_cast<Element*> (dcTags.front());
+
+        table->insert(std::make_pair(
+                                id3Element->get_child_text()->get_content(),
+                                dcElement ->get_child_text()->get_content() ));
+        ++listIt;
+    }
+}
+
+
+/*------------------------------------------------------------------------------
+ *  Convert an id3v2 tag to a Dublin Core tag (with namespace).
+ *----------------------------------------------------------------------------*/
+const std::string &
+TagConversion :: id3ToDublinCore(const std::string &id3Tag)
+                                               throw (std::invalid_argument)
+{
+    if (!table) {
+        throw std::invalid_argument("conversion table has not been configured");
+    }
+
+    TableType::const_iterator   it = table->find(id3Tag);
+    if (it != table->end()) {
+        return (*table)[id3Tag];
+    } else {
+        throw std::invalid_argument("unknown id3 tag name");
+    }
+}
+
diff --git a/livesupport/modules/core/src/TagConversionTest.cxx b/livesupport/modules/core/src/TagConversionTest.cxx
new file mode 100644
index 000000000..31ecb2f39
--- /dev/null
+++ b/livesupport/modules/core/src/TagConversionTest.cxx
@@ -0,0 +1,135 @@
+/*------------------------------------------------------------------------------
+
+    Copyright (c) 2004 Media Development Loan Fund
+ 
+    This file is part of the LiveSupport project.
+    http://livesupport.campware.org/
+    To report bugs, send an e-mail to bugs@campware.org
+ 
+    LiveSupport is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+  
+    LiveSupport is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with LiveSupport; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+ 
+    Author   : $Author: fgerlits $
+    Version  : $Revision: 1.1 $
+    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Attic/TagConversionTest.cxx,v $
+
+------------------------------------------------------------------------------*/
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include <string>
+#include <iostream>
+
+#include "LiveSupport/Core/TagConversion.h"
+#include "TagConversionTest.h"
+
+
+using namespace LiveSupport::Core;
+
+/* ===================================================  local data structures */
+
+
+/* ================================================  local constants & macros */
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TagConversionTest);
+
+/**
+ *  The name of the configuration file.
+ */
+static const std::string configFileName = "etc/tagConversionTable.xml";
+
+
+/* ===============================================  local function prototypes */
+
+
+/* =============================================================  module code */
+
+/*------------------------------------------------------------------------------
+ *  Set up the test environment
+ *----------------------------------------------------------------------------*/
+void
+TagConversionTest :: setUp(void)                         throw ()
+{
+}
+
+
+/*------------------------------------------------------------------------------
+ *  Clean up the test environment
+ *----------------------------------------------------------------------------*/
+void
+TagConversionTest :: tearDown(void)                      throw ()
+{
+}
+
+
+/*------------------------------------------------------------------------------
+ *  A simple test
+ *----------------------------------------------------------------------------*/
+void
+TagConversionTest :: firstTest(void)
+                                                throw (CPPUNIT_NS::Exception)
+{
+    try {
+        TagConversion::existsId3Tag("Title");
+        CPPUNIT_FAIL("allowed to use class before configuration");
+    } catch (std::invalid_argument &e) {
+    }
+
+    try {
+        TagConversion::id3ToDublinCore("Title");
+        CPPUNIT_FAIL("allowed to use class before configuration");
+    } catch (std::invalid_argument &e) {
+    }
+
+    CPPUNIT_ASSERT(!TagConversion::isConfigured());
+    try {
+        Ptr<xmlpp::DomParser>::Ref  parser(
+                                new xmlpp::DomParser(configFileName, false));
+        const xmlpp::Document * document = parser->get_document();
+        const xmlpp::Element  * root     = document->get_root_node();
+        TagConversion::configure(*root);
+    } catch (std::invalid_argument &e) {
+        CPPUNIT_FAIL(e.what());
+    } catch (xmlpp::exception &e) {
+        CPPUNIT_FAIL(e.what());
+    }
+    CPPUNIT_ASSERT( TagConversion::isConfigured());
+
+    try {
+        CPPUNIT_ASSERT( TagConversion::existsId3Tag("Title"));
+        CPPUNIT_ASSERT(!TagConversion::existsId3Tag("Groovicity"));
+    } catch (std::invalid_argument &e) {
+        CPPUNIT_FAIL(e.what());
+    }
+
+    try {
+        CPPUNIT_ASSERT(TagConversion::id3ToDublinCore("Title") == "dc:title");
+        std::string    dcTag = TagConversion::id3ToDublinCore("Artist");
+        CPPUNIT_ASSERT(dcTag == "dc:creator");
+    } catch (std::invalid_argument &e) {
+        CPPUNIT_FAIL(e.what());
+    }
+
+    try {
+        std::string    dcTag = TagConversion::id3ToDublinCore("Boringness");
+        CPPUNIT_FAIL("allowed to convert non-existent tag");
+    } catch (std::invalid_argument &e) {
+    }
+}
+
diff --git a/livesupport/modules/core/src/TagConversionTest.h b/livesupport/modules/core/src/TagConversionTest.h
new file mode 100644
index 000000000..f2c387e68
--- /dev/null
+++ b/livesupport/modules/core/src/TagConversionTest.h
@@ -0,0 +1,107 @@
+/*------------------------------------------------------------------------------
+
+    Copyright (c) 2004 Media Development Loan Fund
+ 
+    This file is part of the LiveSupport project.
+    http://livesupport.campware.org/
+    To report bugs, send an e-mail to bugs@campware.org
+ 
+    LiveSupport is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+  
+    LiveSupport is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with LiveSupport; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ 
+ 
+    Author   : $Author: fgerlits $
+    Version  : $Revision: 1.1 $
+    Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Attic/TagConversionTest.h,v $
+
+------------------------------------------------------------------------------*/
+#ifndef TagConversionTest_h
+#define TagConversionTest_h
+
+#ifndef __cplusplus
+#error This is a C++ include file
+#endif
+
+
+/* ============================================================ include files */
+
+#ifdef HAVE_CONFIG_H
+#include "configure.h"
+#endif
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+namespace LiveSupport {
+namespace Core {
+
+/* ================================================================ constants */
+
+
+/* =================================================================== macros */
+
+
+/* =============================================================== data types */
+
+/**
+ *  Unit test for the TagConversion class.
+ *
+ *  @author  $Author: fgerlits $
+ *  @version $Revision: 1.1 $
+ *  @see TagConversion
+ */
+class TagConversionTest : public CPPUNIT_NS::TestFixture
+{
+    CPPUNIT_TEST_SUITE(TagConversionTest);
+    CPPUNIT_TEST(firstTest);
+    CPPUNIT_TEST_SUITE_END();
+
+    protected:
+
+        /**
+         *  Test conversion from struct timeval to ptime
+         *
+         *  @exception CPPUNIT_NS::Exception on test failures.
+         */
+        void
+        firstTest(void)                         throw (CPPUNIT_NS::Exception);
+
+
+    public:
+        
+        /**
+         *  Set up the environment for the test case.
+         */
+        void
+        setUp(void)                                     throw ();
+
+        /**
+         *  Clean up the environment after the test case.
+         */
+        void
+        tearDown(void)                                  throw ();
+};
+
+
+/* ================================================= external data structures */
+
+
+/* ====================================================== function prototypes */
+
+
+} // namespace Core
+} // namespace LiveSupport
+
+#endif // TagConversionTest_h
+