Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / rdf.cpp
index 0a8fd51f6de4e39e4b64593a31965bcb2a1b068e..c9378cf530a8aec6b4332c9d4ded4b7514458b06 100644 (file)
@@ -6,6 +6,7 @@
 /* Authors:
  *   Kees Cook <kees@outflux.net>
  *   Jon Phillips <jon@rejon.org>
+ *   Jon A. Cruz <jon@joncruz.org>
  *
  * Copyright (C) 2004 Kees Cook <kees@outflux.net>
  * Copyright (C) 2006 Jon Phillips <jon@rejon.org>
@@ -226,68 +227,68 @@ struct rdf_license_t rdf_licenses [] = {
 // Remember when using the "title" and "tip" elements to pass them through
 // the localization functions when you use them!
 struct rdf_work_entity_t rdf_work_entities [] = {
-    { "title", N_("Title"), "dc:title", RDF_CONTENT,
-      N_("Name by which this document is formally known."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "title", N_("Title:"), "dc:title", RDF_CONTENT,
+      N_("Name by which this document is formally known"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "date", N_("Date"), "dc:date", RDF_CONTENT,
-      N_("Date associated with the creation of this document (YYYY-MM-DD)."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "date", N_("Date:"), "dc:date", RDF_CONTENT,
+      N_("Date associated with the creation of this document (YYYY-MM-DD)"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "format", N_("Format"), "dc:format", RDF_CONTENT,
-      N_("The physical or digital manifestation of this document (MIME type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
+    { "format", N_("Format:"), "dc:format", RDF_CONTENT,
+      N_("The physical or digital manifestation of this document (MIME type)"), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
     },
-    { "type", N_("Type"), "dc:type", RDF_RESOURCE,
-      N_("Type of document (DCMI Type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
+    { "type", N_("Type:"), "dc:type", RDF_RESOURCE,
+      N_("Type of document (DCMI Type)"), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
     },
 
-    { "creator", N_("Creator"), "dc:creator", RDF_AGENT,
-      N_("Name of entity primarily responsible for making the content of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "creator", N_("Creator:"), "dc:creator", RDF_AGENT,
+      N_("Name of entity primarily responsible for making the content of this document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "rights", N_("Rights"), "dc:rights", RDF_AGENT,
-      N_("Name of entity with rights to the Intellectual Property of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "rights", N_("Rights:"), "dc:rights", RDF_AGENT,
+      N_("Name of entity with rights to the Intellectual Property of this document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "publisher", N_("Publisher"), "dc:publisher", RDF_AGENT,
-      N_("Name of entity responsible for making this document available."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "publisher", N_("Publisher:"), "dc:publisher", RDF_AGENT,
+      N_("Name of entity responsible for making this document available"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
 
-    { "identifier", N_("Identifier"), "dc:identifier", RDF_CONTENT,
-      N_("Unique URI to reference this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "identifier", N_("Identifier:"), "dc:identifier", RDF_CONTENT,
+      N_("Unique URI to reference this document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "source", N_("Source"), "dc:source", RDF_CONTENT,
-      N_("Unique URI to reference the source of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "source", N_("Source:"), "dc:source", RDF_CONTENT,
+      N_("Unique URI to reference the source of this document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "relation", N_("Relation"), "dc:relation", RDF_CONTENT,
-      N_("Unique URI to a related document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "relation", N_("Relation:"), "dc:relation", RDF_CONTENT,
+      N_("Unique URI to a related document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "language", N_("Language"), "dc:language", RDF_CONTENT,
-      N_("Two-letter language tag with optional subtags for the language of this document (e.g. 'en-GB')"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "language", N_("Language:"), "dc:language", RDF_CONTENT,
+      N_("Two-letter language tag with optional subtags for the language of this document (e.g. 'en-GB')"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
-    { "subject", N_("Keywords"), "dc:subject", RDF_BAG,
-      N_("The topic of this document as comma-separated key words, phrases, or classifications."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "subject", N_("Keywords:"), "dc:subject", RDF_BAG,
+      N_("The topic of this document as comma-separated key words, phrases, or classifications"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
     // TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content.
     // For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/
-    { "coverage", N_("Coverage"), "dc:coverage", RDF_CONTENT,
-      N_("Extent or scope of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
+    { "coverage", N_("Coverage:"), "dc:coverage", RDF_CONTENT,
+      N_("Extent or scope of this document"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
     },
 
-    { "description", N_("Description"), "dc:description", RDF_CONTENT,
-      N_("A short account of the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
+    { "description", N_("Description:"), "dc:description", RDF_CONTENT,
+      N_("A short account of the content of this document"), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
     },
 
     // FIXME: need to handle 1 agent per line of input
-    { "contributor", N_("Contributors"), "dc:contributor", RDF_AGENT,
-      N_("Names of entities responsible for making contributions to the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
+    { "contributor", N_("Contributors:"), "dc:contributor", RDF_AGENT,
+      N_("Names of entities responsible for making contributions to the content of this document"), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
     },
 
     // TRANSLATORS: URL to a page that defines the license for the document
-    { "license_uri", N_("URI"), "cc:license", RDF_RESOURCE,
+    { "license_uri", N_("URI:"), "cc:license", RDF_RESOURCE,
       // TRANSLATORS: this is where you put a URL to a page that defines the license
-      N_("URI to this document's license's namespace definition."), RDF_FORMAT_LINE, RDF_EDIT_SPECIAL,
+      N_("URI to this document's license's namespace definition"), RDF_FORMAT_LINE, RDF_EDIT_SPECIAL,
     },
 
       // TRANSLATORS: fragment of XML representing the license of the document
-    { "license_fragment", N_("Fragment"), "License", RDF_XML,
-      N_("XML fragment for the RDF 'License' section."), RDF_FORMAT_MULTILINE, RDF_EDIT_SPECIAL,
+    { "license_fragment", N_("Fragment:"), "License", RDF_XML,
+      N_("XML fragment for the RDF 'License' section"), RDF_FORMAT_MULTILINE, RDF_EDIT_SPECIAL,
     },
     
     { NULL, NULL, NULL, RDF_CONTENT,
@@ -295,6 +296,50 @@ struct rdf_work_entity_t rdf_work_entities [] = {
     }
 };
 
+
+// Simple start of C++-ification:
+class RDFImpl
+{
+public:
+    /**
+     * Some implementations do not put RDF stuff inside <metadata>,
+     * so we need to check for it and add it if we don't see it.
+     */
+    static void ensureParentIsMetadata( SPDocument *doc, Inkscape::XML::Node *node );
+
+    static Inkscape::XML::Node const *getRdfRootRepr( SPDocument const * doc );
+    static Inkscape::XML::Node *ensureRdfRootRepr( SPDocument * doc );
+
+    static Inkscape::XML::Node const *getXmlRepr( SPDocument const * doc, gchar const * name );
+    static Inkscape::XML::Node *getXmlRepr( SPDocument * doc, gchar const * name );
+    static Inkscape::XML::Node *ensureXmlRepr( SPDocument * doc, gchar const * name );
+
+    static Inkscape::XML::Node const *getWorkRepr( SPDocument const * doc, gchar const * name );
+    static Inkscape::XML::Node *ensureWorkRepr( SPDocument * doc, gchar const * name );
+
+    static const gchar *getWorkEntity(SPDocument const * doc, struct rdf_work_entity_t & entity);
+    static unsigned int setWorkEntity(SPDocument * doc, struct rdf_work_entity_t & entity, gchar const * text);
+
+    static void setDefaults( SPDocument * doc );
+
+    /**
+     *  \brief   Pull the text out of an RDF entity, depends on how it's stored
+     *  \return  A pointer to the entity's static contents as a string
+     *  \param   repr    The XML element to extract from
+     *  \param   entity  The desired RDF/Work entity
+     *  
+     */
+    static const gchar *getReprText( Inkscape::XML::Node const * repr, struct rdf_work_entity_t const & entity );
+
+    static unsigned int setReprText( Inkscape::XML::Node * repr,
+                                     struct rdf_work_entity_t const & entity,
+                                     gchar const * text );
+
+    static struct rdf_license_t *getLicense(SPDocument const * document);
+
+    static void setLicense(SPDocument * doc, struct rdf_license_t const * license);
+};
+
 /**
  *  \brief   Retrieves a known RDF/Work entity by name
  *  \return  A pointer to an RDF/Work entity
@@ -431,23 +476,14 @@ rdf_string(struct rdf_t * rdf)
 */
 
 
-/**
- *  \brief   Pull the text out of an RDF entity, depends on how it's stored
- *  \return  A pointer to the entity's static contents as a string
- *  \param   repr    The XML element to extract from
- *  \param   entity  The desired RDF/Work entity
- *  
- */
-const gchar *
-rdf_get_repr_text ( Inkscape::XML::Node * repr, struct rdf_work_entity_t * entity )
+const gchar *RDFImpl::getReprText( Inkscape::XML::Node const * repr, struct rdf_work_entity_t const & entity )
 {
     g_return_val_if_fail (repr != NULL, NULL);
-    g_return_val_if_fail (entity != NULL, NULL);
     static gchar * bag = NULL;
     gchar * holder = NULL;
 
-    Inkscape::XML::Node * temp=NULL;
-    switch (entity->datatype) {
+    Inkscape::XML::Node const * temp = NULL;
+    switch (entity.datatype) {
         case RDF_CONTENT:
             temp = sp_repr_children(repr);
             if ( temp == NULL ) return NULL;
@@ -510,13 +546,11 @@ rdf_get_repr_text ( Inkscape::XML::Node * repr, struct rdf_work_entity_t * entit
     return NULL;
 }
 
-unsigned int
-rdf_set_repr_text ( Inkscape::XML::Node * repr,
-                    struct rdf_work_entity_t * entity,
-                    gchar const * text )
+unsigned int RDFImpl::setReprText( Inkscape::XML::Node * repr,
+                                   struct rdf_work_entity_t const & entity,
+                                   gchar const * text )
 {
     g_return_val_if_fail ( repr != NULL, 0);
-    g_return_val_if_fail ( entity != NULL, 0);
     g_return_val_if_fail ( text != NULL, 0);
     gchar * str = NULL;
     gchar** strlist = NULL;
@@ -530,12 +564,12 @@ rdf_set_repr_text ( Inkscape::XML::Node * repr,
     g_return_val_if_fail (xmldoc != NULL, FALSE);
 
     // set document's title element to the RDF title
-    if (!strcmp(entity->name, "title")) {
+    if (!strcmp(entity.name, "title")) {
         SPDocument *doc = SP_ACTIVE_DOCUMENT;
         if(doc && doc->root) doc->root->setTitle(text);
     }
 
-    switch (entity->datatype) {
+    switch (entity.datatype) {
         case RDF_CONTENT:
             temp = sp_repr_children(parent);
             if ( temp == NULL ) {
@@ -643,187 +677,263 @@ rdf_set_repr_text ( Inkscape::XML::Node * repr,
     return 0;
 }
 
-Inkscape::XML::Node *
-rdf_get_rdf_root_repr ( SPDocument * doc, bool build )
+void RDFImpl::ensureParentIsMetadata( SPDocument *doc, Inkscape::XML::Node *node )
 {
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
-
-    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-    g_return_val_if_fail (xmldoc != NULL, NULL);
-
-    Inkscape::XML::Node * rdf = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_RDF );
+    if ( !node ) {
+        g_critical("Null node passed to ensureParentIsMetadata().");
+    } else if ( !node->parent() ) {
+        g_critical( "No parent node when verifying <metadata> placement." );
+    } else {
+        Inkscape::XML::Node * currentParent = node->parent();
+        if ( strcmp( currentParent->name(), XML_TAG_NAME_METADATA ) != 0 ) {
+            Inkscape::XML::Node * metadata = doc->getReprDoc()->createElement( XML_TAG_NAME_METADATA );
+            if ( !metadata ) {
+                g_critical("Unable to create metadata element.");
+            } else {
+                // attach the metadata node
+                currentParent->appendChild( metadata );
+                Inkscape::GC::release( metadata );
+
+                // move the node into it
+                Inkscape::GC::anchor( node );
+                sp_repr_unparent( node );
+                metadata->appendChild( node );
+                Inkscape::GC::release( node );
+            }
+        }
+    }
+}
 
-    if (rdf == NULL) {
-        //printf("missing XML '%s'\n",XML_TAG_NAME_RDF);
-        if (!build) return NULL;
+Inkscape::XML::Node const *RDFImpl::getRdfRootRepr( SPDocument const * doc )
+{
+    Inkscape::XML::Node const *rdf = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to getRdfRootRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else {
+        rdf = sp_repr_lookup_name( doc->getReprDoc(), XML_TAG_NAME_RDF );
+    }
 
-        Inkscape::XML::Node * svg = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_SVG );
-        g_return_val_if_fail ( svg != NULL, NULL );
+    return rdf;
+}
 
-        Inkscape::XML::Node * parent = sp_repr_lookup_name ( svg, XML_TAG_NAME_METADATA );
-        if ( parent == NULL ) {
-            parent = xmldoc->createElement( XML_TAG_NAME_METADATA );
-            g_return_val_if_fail ( parent != NULL, NULL);
+Inkscape::XML::Node *RDFImpl::ensureRdfRootRepr( SPDocument * doc )
+{
+    Inkscape::XML::Node *rdf = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to ensureRdfRootRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else {
+        rdf = sp_repr_lookup_name( doc->getReprDoc(), XML_TAG_NAME_RDF );
+        if ( !rdf ) {
+            Inkscape::XML::Node * svg = sp_repr_lookup_name( doc->getReprRoot(), XML_TAG_NAME_SVG );
+            if ( !svg ) {
+                g_critical("Unable to locate svg element.");
+            } else {
+                Inkscape::XML::Node * parent = sp_repr_lookup_name( svg, XML_TAG_NAME_METADATA );
+                if ( parent == NULL ) {
+                    parent = doc->getReprDoc()->createElement( XML_TAG_NAME_METADATA );
+                    if ( !parent ) {
+                        g_critical("Unable to create metadata element");
+                    } else {
+                        svg->appendChild(parent);
+                        Inkscape::GC::release(parent);
+                    }
+                }
 
-            svg->appendChild(parent);
-            Inkscape::GC::release(parent);
+                if ( parent && !parent->document() ) {
+                    g_critical("Parent has no document");
+                } else if ( parent ) {
+                    rdf = parent->document()->createElement( XML_TAG_NAME_RDF );
+                    if ( !rdf ) {
+                        g_critical("Unable to create root RDF element.");
+                    } else {
+                        parent->appendChild(rdf);
+                        Inkscape::GC::release(rdf);
+                    }
+                }
+            }
         }
-
-        Inkscape::XML::Document * xmldoc = parent->document();
-        g_return_val_if_fail (xmldoc != NULL, FALSE);
-
-        rdf = xmldoc->createElement( XML_TAG_NAME_RDF );
-        g_return_val_if_fail (rdf != NULL, NULL);
-
-        parent->appendChild(rdf);
-        Inkscape::GC::release(rdf);
     }
 
-    /*
-     * some implementations do not put RDF stuff inside <metadata>,
-     * so we need to check for it and add it if we don't see it
-     */
-    Inkscape::XML::Node * want_metadata = sp_repr_parent ( rdf );
-    g_return_val_if_fail (want_metadata != NULL, NULL);
-    if (strcmp( want_metadata->name(), XML_TAG_NAME_METADATA )) {
-            Inkscape::XML::Node * metadata = xmldoc->createElement( XML_TAG_NAME_METADATA );
-            g_return_val_if_fail (metadata != NULL, NULL);
-
-            /* attach the metadata node */
-            want_metadata->appendChild(metadata);
-            Inkscape::GC::release(metadata);
-
-            /* move the RDF into it */
-            Inkscape::GC::anchor(rdf);
-            sp_repr_unparent ( rdf );
-            metadata->appendChild(rdf);
-            Inkscape::GC::release(rdf);
+    if ( rdf ) {
+        ensureParentIsMetadata( doc, rdf );
     }
-    
+
     return rdf;
 }
 
-Inkscape::XML::Node *
-rdf_get_xml_repr( SPDocument * doc, gchar const * name, bool build )
+Inkscape::XML::Node const *RDFImpl::getXmlRepr( SPDocument const * doc, gchar const * name )
 {
-    g_return_val_if_fail (name       != NULL, NULL);
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
-
-    Inkscape::XML::Node * rdf = rdf_get_rdf_root_repr ( doc, build );
-    if (!rdf) return NULL;
-
-    Inkscape::XML::Node * xml = sp_repr_lookup_name ( rdf, name );
-    if (xml == NULL) {
-        //printf("missing XML '%s'\n",name);
-        if (!build) return NULL;
-
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_val_if_fail (xmldoc != NULL, NULL);
+    Inkscape::XML::Node const * xml = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to getXmlRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else if (!name) {
+        g_critical("Null name passed to getXmlRepr()");        
+    } else {
+        Inkscape::XML::Node const * rdf = getRdfRootRepr( doc );
+        if ( rdf ) {
+            xml = sp_repr_lookup_name( rdf, name );
+        }
+    }
+    return xml;
+}
 
-        xml = xmldoc->createElement( name );
-        g_return_val_if_fail (xml != NULL, NULL);
+Inkscape::XML::Node *RDFImpl::getXmlRepr( SPDocument * doc, gchar const * name )
+{
+    Inkscape::XML::Node const *xml = getXmlRepr( const_cast<SPDocument const *>(doc), name );
 
-        xml->setAttribute("rdf:about", "" );
+    return const_cast<Inkscape::XML::Node *>(xml);
+}
 
-        rdf->appendChild(xml);
-        Inkscape::GC::release(xml);
+Inkscape::XML::Node *RDFImpl::ensureXmlRepr( SPDocument * doc, gchar const * name )
+{
+    Inkscape::XML::Node * xml = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to ensureXmlRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else if (!name) {
+        g_critical("Null name passed to ensureXmlRepr()");        
+    } else {
+        Inkscape::XML::Node * rdf = ensureRdfRootRepr( doc );
+        if ( rdf ) {
+            xml = sp_repr_lookup_name( rdf, name );
+            if ( !xml ) {
+                xml = doc->getReprDoc()->createElement( name );
+                if ( !xml ) {
+                    g_critical("Unable to create xml element <%s>.", name);
+                } else {
+                    xml->setAttribute("rdf:about", "" );
+
+                    rdf->appendChild(xml);
+                    Inkscape::GC::release(xml);
+                }
+            }
+        }
     }
-
     return xml;
 }
 
-Inkscape::XML::Node *
-rdf_get_work_repr( SPDocument * doc, gchar const * name, bool build )
+Inkscape::XML::Node const *RDFImpl::getWorkRepr( SPDocument const * doc, gchar const * name )
 {
-    g_return_val_if_fail (name       != NULL, NULL);
-    g_return_val_if_fail (doc        != NULL, NULL);
-    g_return_val_if_fail (doc->rroot != NULL, NULL);
+    Inkscape::XML::Node const * item = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to getWorkRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else if (!name) {
+        g_critical("Null name passed to getWorkRepr()");        
+    } else {
+        Inkscape::XML::Node const* work = getXmlRepr( doc, XML_TAG_NAME_WORK );
+        if ( work ) {
+            item = sp_repr_lookup_name( work, name, 1 );
+        }
+    }
+    return item;
+}
 
-    Inkscape::XML::Node * work = rdf_get_xml_repr ( doc, XML_TAG_NAME_WORK, build );
-    if (!work) return NULL;
+Inkscape::XML::Node *RDFImpl::ensureWorkRepr( SPDocument * doc, gchar const * name )
+{
+    Inkscape::XML::Node * item = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to ensureWorkRepr()");
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else if (!name) {
+        g_critical("Null name passed to ensureWorkRepr()");        
+    } else {
+        Inkscape::XML::Node * work = ensureXmlRepr( doc, XML_TAG_NAME_WORK );
+        if ( work ) {
+            item = sp_repr_lookup_name( work, name, 1 );
+            if ( !item ) {
+                //printf("missing XML '%s'\n",name);
+                item = doc->getReprDoc()->createElement( name );
+                if ( !item ) {
+                    g_critical("Unable to create xml element <%s>", name);
+                } else {
+                    work->appendChild(item);
+                    Inkscape::GC::release(item);
+                }
+            }
+        }
+    }
+    return item;
+}
 
-    Inkscape::XML::Node * item = sp_repr_lookup_name ( work, name, 1 );
-    if (item == NULL) {
-        //printf("missing XML '%s'\n",name);
-        if (!build) return NULL;
 
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_val_if_fail (xmldoc != NULL, NULL);
+// Public API:
+const gchar *rdf_get_work_entity(SPDocument const * doc, struct rdf_work_entity_t * entity)
+{
+    const gchar *result = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to rdf_get_work_entity()");
+    } else if ( entity ) {
+        //g_message("want '%s'\n",entity->title);
 
-        item = xmldoc->createElement( name );
-        g_return_val_if_fail (item != NULL, NULL);
+        result = RDFImpl::getWorkEntity( doc, *entity );
 
-        work->appendChild(item);
-        Inkscape::GC::release(item);
+        //g_message("found '%s' == '%s'\n", entity->title, result );
     }
-
-    return item;
+    return result;
 }
 
-
-
-/**
- *  \brief   Retrieves a known RDF/Work entity's contents from the document XML by name
- *  \return  A pointer to the entity's static contents as a string, or NULL if no entity exists
- *  \param   entity  The desired RDF/Work entity
- *  
- */
-const gchar *
-rdf_get_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity)
+const gchar *RDFImpl::getWorkEntity(SPDocument const * doc, struct rdf_work_entity_t & entity)
 {
-    g_return_val_if_fail (doc    != NULL, NULL);
-    if ( entity == NULL ) return NULL;
-    //printf("want '%s'\n",entity->title);
-    bool bIsTitle = !strcmp(entity->name, "title");
+    gchar const *result = 0;
 
-    Inkscape::XML::Node * item;
-    if ( entity->datatype == RDF_XML ) {
-        item = rdf_get_xml_repr ( doc, entity->tag, FALSE );
-    }
-    else {
-        item = rdf_get_work_repr( doc, entity->tag, bIsTitle ); // build title if necessary
+    Inkscape::XML::Node const * item = getWorkRepr( doc, entity.tag );
+    if ( item ) {
+        result = getReprText( item, entity );
+        // TODO note that this is the location that used to set the title if needed. Ensure code it not required.
     }
-    if ( item == NULL ) return NULL;
-    const gchar * result = rdf_get_repr_text ( item, entity );
-    if(!result && bIsTitle && doc->root) {         // if RDF title not set
-        result = doc->root->title();               // get the document's <title>
-        rdf_set_work_entity(doc, entity, result);  // and set the RDF
+
+    return result;
+}
+
+// Public API:
+unsigned int rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity,
+                                 const gchar * text)
+{
+    unsigned int result = 0;
+    if ( !doc ) {
+        g_critical("Null doc passed to rdf_set_work_entity()");
+    } else if ( entity ) {
+        result = RDFImpl::setWorkEntity( doc, *entity, text );
     }
-    //printf("found '%s' == '%s'\n", entity->title, result );
+
     return result;
 }
 
-/**
- *  \brief   Stores a string into a named RDF/Work entity in the document XML
- *  \param   entity The desired RDF/Work entity to replace
- *  \param   string The string to replace the entity contents with
- *  
- */
-unsigned int
-rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity,
-                    const gchar * text)
+unsigned int RDFImpl::setWorkEntity(SPDocument * doc, struct rdf_work_entity_t & entity, const gchar * text)
 {
-    g_return_val_if_fail ( entity != NULL, 0 );
-    if (text == NULL) {
+    int result = 0;
+    if ( !text ) {
         // FIXME: on a "NULL" text, delete the entity.  For now, blank it.
-        text="";
+        text = "";
     }
 
     /*
-    printf("changing '%s' (%s) to '%s'\n",
-        entity->title,
-        entity->tag,
-        text);
+      printf("changing '%s' (%s) to '%s'\n",
+      entity->title,
+      entity->tag,
+      text);
     */
 
-    Inkscape::XML::Node * item = rdf_get_work_repr( doc, entity->tag, TRUE );
-    g_return_val_if_fail ( item != NULL, 0 );
-
-    return rdf_set_repr_text ( item, entity, text );
+    Inkscape::XML::Node * item = ensureWorkRepr( doc, entity.tag );
+    if ( !item ) {
+        g_critical("Unable to get work element");
+    } else {
+        result = setReprText( item, entity, text );
+    }
+    return result;
 }
 
+
 #undef DEBUG_MATCH
 
 static bool
@@ -912,19 +1022,20 @@ rdf_match_license(Inkscape::XML::Node const *repr, struct rdf_license_t const *l
     return result;
 }
 
-/**
- *  \brief   Attempts to match and retrieve a known RDF/License from the document XML
- *  \return  A pointer to the static RDF license structure
- *  
- */
-struct rdf_license_t *
-rdf_get_license(SPDocument * document)
+// Public API:
+struct rdf_license_t *rdf_get_license(SPDocument const * document)
 {
-    Inkscape::XML::Node const *repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, FALSE );
+    return RDFImpl::getLicense(document);
+}
+
+struct rdf_license_t *RDFImpl::getLicense(SPDocument const *document)
+{
+    Inkscape::XML::Node const *repr = getXmlRepr( document, XML_TAG_NAME_LICENSE );
     if (repr) {
-        for (struct rdf_license_t * license = rdf_licenses;
-             license->name; license++ ) {
-            if ( rdf_match_license ( repr, license ) ) return license;
+        for ( struct rdf_license_t * license = rdf_licenses; license->name; license++ ) {
+            if ( rdf_match_license( repr, license ) ) {
+                return license;
+            }
         }
     }
 #ifdef DEBUG_MATCH
@@ -935,38 +1046,39 @@ rdf_get_license(SPDocument * document)
     return NULL;
 }
 
-/**
- *  \brief   Stores an RDF/License XML in the document XML
- *  \param   document  Which document to update
- *  \param   license   The desired RDF/License structure to store; NULL drops old license, so can be used for proprietary license. 
- *  
- */
-void
-rdf_set_license(SPDocument * doc, struct rdf_license_t const * license)
+// Public API:
+void rdf_set_license(SPDocument * doc, struct rdf_license_t const * license)
 {
-    // drop old license section
-    Inkscape::XML::Node * repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, FALSE );
-    if (repr) sp_repr_unparent(repr);
-
-    if (!license) return;
+    RDFImpl::setLicense( doc, license );
+}
 
-    // build new license section
-    repr = rdf_get_xml_repr ( doc, XML_TAG_NAME_LICENSE, TRUE );
-    g_assert ( repr );
+void RDFImpl::setLicense(SPDocument * doc, struct rdf_license_t const * license)
+{
+    // drop old license section
+    Inkscape::XML::Node * repr = getXmlRepr( doc, XML_TAG_NAME_LICENSE );
+    if (repr) {
+        sp_repr_unparent(repr);
+    }
 
-    repr->setAttribute("rdf:about", license->uri );
+    if ( !license ) {
+        // All done
+    } else if ( !doc->getReprDoc() ) {
+        g_critical("XML doc is null.");
+    } else {
+        // build new license section
+        repr = ensureXmlRepr( doc, XML_TAG_NAME_LICENSE );
+        g_assert( repr );
 
-    Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-    g_return_if_fail (xmldoc != NULL);
+        repr->setAttribute("rdf:about", license->uri );
 
-    for (struct rdf_double_t const * detail = license->details;
-         detail->name; detail++) {
-        Inkscape::XML::Node * child = xmldoc->createElement( detail->name );
-        g_assert ( child != NULL );
+        for (struct rdf_double_t const * detail = license->details; detail->name; detail++) {
+            Inkscape::XML::Node * child = doc->getReprDoc()->createElement( detail->name );
+            g_assert ( child != NULL );
 
-        child->setAttribute("rdf:resource", detail->resource );
-        repr->appendChild(child);
-        Inkscape::GC::release(child);
+            child->setAttribute("rdf:resource", detail->resource );
+            repr->appendChild(child);
+            Inkscape::GC::release(child);
+        }
     }
 }
 
@@ -980,37 +1092,46 @@ struct rdf_entity_default_t rdf_defaults[] = {
     { NULL,          NULL, }
 };
 
-void
-rdf_set_defaults ( SPDocument * doc )
+// Public API:
+void rdf_set_defaults( SPDocument * doc )
+{
+    RDFImpl::setDefaults( doc );
+
+}
+
+void RDFImpl::setDefaults( SPDocument * doc )
 {
-    g_assert ( doc != NULL );
+    g_assert( doc != NULL );
 
     // Create metadata node if it doesn't already exist
-    if (!sp_item_group_get_child_by_name ((SPGroup *) doc->root, NULL,
+    if (!sp_item_group_get_child_by_name((SPGroup *) doc->root, NULL,
                                           XML_TAG_NAME_METADATA)) {
-        // create repr
-        Inkscape::XML::Document * xmldoc = sp_document_repr_doc(doc);
-        g_return_if_fail (xmldoc != NULL);
-        Inkscape::XML::Node * rnew = xmldoc->createElement (XML_TAG_NAME_METADATA);
-        // insert into the document
-        doc->rroot->addChild(rnew, NULL);
-        // clean up
-        Inkscape::GC::release(rnew);
-    }
-
-    /* install defaults */
-    for ( struct rdf_entity_default_t * rdf_default = rdf_defaults;
-          rdf_default->name;
-          rdf_default++) {
-        struct rdf_work_entity_t * entity = rdf_find_entity ( rdf_default->name );
-        g_assert ( entity != NULL );
-
-        if ( rdf_get_work_entity ( doc, entity ) == NULL ) {
-            rdf_set_work_entity ( doc, entity, rdf_default->text );
+        if ( !doc->getReprDoc()) {
+            g_critical("XML doc is null.");
+        } else {
+            // create repr
+            Inkscape::XML::Node * rnew = doc->getReprDoc()->createElement(XML_TAG_NAME_METADATA);
+
+            // insert into the document
+            doc->getReprRoot()->addChild(rnew, NULL);
+
+            // clean up
+            Inkscape::GC::release(rnew);
+        }
+    }
+
+    // install defaults
+    for ( struct rdf_entity_default_t * rdf_default = rdf_defaults; rdf_default->name; rdf_default++) {
+        struct rdf_work_entity_t * entity = rdf_find_entity( rdf_default->name );
+        g_assert( entity != NULL );
+
+        if ( getWorkEntity( doc, *entity ) == NULL ) {
+            setWorkEntity( doc, *entity, rdf_default->text );
         }
     }
 }
 
+
 /*
   Local Variables:
   mode:c++
@@ -1020,4 +1141,4 @@ rdf_set_defaults ( SPDocument * doc )
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :