/** @file
* RDF manipulation functions.
*
* @todo move these to xml/ instead of dialogs/
*/
/* 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>
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "rdf.h"
#include "sp-item-group.h"
#include "inkscape.h"
#include "sp-root.h"
#include "preferences.h"
/*
Example RDF XML from various places...
<rdf:RDF xmlns="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="">
<dc:title>title of work</dc:title>
<dc:date>year</dc:date>
<dc:description>description of work</dc:description>
<dc:creator><Agent>
<dc:title>creator</dc:title>
</Agent></dc:creator>
<dc:rights><Agent>
<dc:title>holder</dc:title>
</Agent></dc:rights>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:source rdf:resource="source"/>
<license rdf:resource="http://creativecommons.org/licenses/by/4.0/"
/>
</Work>
<rdf:RDF xmlns="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="">
<dc:title>SVG Road Signs</dc:title>
<dc:rights><Agent>
<dc:title>John Cliff</dc:title>
</Agent></dc:rights>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<license rdf:resource="http://creativecommons.org/ns#PublicDomain" />
</Work>
<License rdf:about="http://creativecommons.org/ns#PublicDomain">
<permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</License>
</rdf:RDF>
Bag example:
<dc:subject>
<rdf:Bag>
<rdf:li>open clip art logo</rdf:li>
<rdf:li>images</rdf:li>
<rdf:li>logo</rdf:li>
<rdf:li>clip art</rdf:li>
<rdf:li>ocal</rdf:li>
<rdf:li>logotype</rdf:li>
<rdf:li>filetype</rdf:li>
</rdf:Bag>
</dc:subject>
*/
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
{ "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
{ "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
{ "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
{ "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
{ "cc:prohibits", "http://creativecommons.org/ns#CommercialUse", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
};
{ "cc:permits", "http://creativecommons.org/ns#Reproduction", },
{ "cc:permits", "http://creativecommons.org/ns#Distribution", },
{ "cc:permits", "http://creativecommons.org/ns#DerivativeWorks", },
{ "cc:requires", "http://creativecommons.org/ns#ShareAlike", },
{ "cc:requires", "http://creativecommons.org/ns#Notice", },
{ "cc:requires", "http://creativecommons.org/ns#Attribution", },
};
{ "cc:permits", "http://scripts.sil.org/pub/OFL/Reproduction", },
{ "cc:permits", "http://scripts.sil.org/pub/OFL/Distribution", },
{ "cc:permits", "http://scripts.sil.org/pub/OFL/Embedding", },
{ "cc:permits", "http://scripts.sil.org/pub/OFL/DerivativeWorks", },
{ "cc:requires", "http://scripts.sil.org/pub/OFL/Notice", },
{ "cc:requires", "http://scripts.sil.org/pub/OFL/Attribution", },
{ "cc:requires", "http://scripts.sil.org/pub/OFL/ShareAlike", },
{ "cc:requires", "http://scripts.sil.org/pub/OFL/DerivativeRenaming", },
{ "cc:requires", "http://scripts.sil.org/pub/OFL/BundlingWhenSelling", },
};
{ N_("CC Attribution"),
},
{ N_("CC Attribution-ShareAlike"),
},
{ N_("CC Attribution-NoDerivs"),
},
{ N_("CC Attribution-NonCommercial"),
},
{ N_("CC Attribution-NonCommercial-ShareAlike"),
},
{ N_("CC Attribution-NonCommercial-NoDerivs"),
},
{ N_("CC0 Public Domain Dedication"),
},
{ N_("FreeArt"),
},
{ N_("Open Font License"),
},
};
// Note the lowercase L!
// Remember when using the "title" and "tip" elements to pass them through
// the localization functions when you use them!
},
N_("A point or period of time associated with an event in the lifecycle of the resource"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
},
N_("The file format, physical medium, or dimensions of the resource"), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED,
},
},
},
},
},
N_("An unambiguous reference to the resource within a given context"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
},
N_("A related resource from which the described resource is derived"), 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/
N_("The spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC,
},
},
// FIXME: need to handle 1 agent per line of input
N_("An entity responsible for making contributions to the resource"), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC,
},
// TRANSLATORS: URL to a page that defines the license for the document
// TRANSLATORS: this is where you put a URL to a page that defines the license
},
// TRANSLATORS: fragment of XML representing the license of the document
},
}
};
// 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 unsigned int setWorkEntity(SPDocument * doc, struct rdf_work_entity_t & entity, gchar const * text);
/**
* 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
*
*/
static const gchar *getReprText( Inkscape::XML::Node const * repr, struct rdf_work_entity_t const & entity );
struct rdf_work_entity_t const & entity,
};
/**
*
*
*/
{
}
return NULL;
}
/*
* Takes the inkscape rdf struct and spits out a static RDF, which is only
* useful for testing. We must merge the rdf struct into the XML DOM for
* changes to be saved.
*/
/*
Since g_markup_printf_escaped doesn't exist for most people's glib
right now, this function will remain commented out since it's only
for generic debug anyway. --Kees
gchar *
rdf_string(struct rdf_t * rdf)
{
gulong overall=0;
gchar *string=NULL;
gchar *rdf_head="\
<rdf:RDF xmlns=\"http://creativecommons.org/ns#\"\
xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\
xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\
";
gchar *work_head="\
<Work rdf:about=\"\">\
<dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" />\
";
gchar *work_title=NULL;
gchar *work_date=NULL;
gchar *work_description=NULL;
gchar *work_creator=NULL;
gchar *work_owner=NULL;
gchar *work_source=NULL;
gchar *work_license=NULL;
gchar *license_head=NULL;
gchar *license=NULL;
gchar *license_end="</License>\n";
gchar *work_end="</Work>\n";
gchar *rdf_end="</rdf:RDF>\n";
if (rdf && rdf->work_title && rdf->work_title[0]) {
work_title=g_markup_printf_escaped(" <dc:title>%s</dc:title>\n",
rdf->work_title);
overall+=strlen(work_title);
}
if (rdf && rdf->work_date && rdf->work_date[0]) {
work_date=g_markup_printf_escaped(" <dc:date>%s</dc:date>\n",
rdf->work_date);
overall+=strlen(work_date);
}
if (rdf && rdf->work_description && rdf->work_description[0]) {
work_description=g_markup_printf_escaped(" <dc:description>%s</dc:description>\n",
rdf->work_description);
overall+=strlen(work_description);
}
if (rdf && rdf->work_creator && rdf->work_creator[0]) {
work_creator=g_markup_printf_escaped(" <dc:creator><Agent>\
<dc:title>%s</dc:title>\
</Agent></dc:creator>\n",
rdf->work_creator);
overall+=strlen(work_creator);
}
if (rdf && rdf->work_owner && rdf->work_owner[0]) {
work_owner=g_markup_printf_escaped(" <dc:rights><Agent>\
<dc:title>%s</dc:title>\
</Agent></dc:rights>\n",
rdf->work_owner);
overall+=strlen(work_owner);
}
if (rdf && rdf->work_source && rdf->work_source[0]) {
work_source=g_markup_printf_escaped(" <dc:source rdf:resource=\"%s\" />\n",
rdf->work_source);
overall+=strlen(work_source);
}
if (rdf && rdf->license && rdf->license->work_rdf && rdf->license->work_rdf[0]) {
work_license=g_markup_printf_escaped(" <license rdf:resource=\"%s\" />\n",
rdf->license->work_rdf);
overall+=strlen(work_license);
license_head=g_markup_printf_escaped("<License rdf:about=\"%s\">\n",
rdf->license->work_rdf);
overall+=strlen(license_head);
overall+=strlen(rdf->license->license_rdf);
overall+=strlen(license_end);
}
overall+=strlen(rdf_head)+strlen(rdf_end);
overall+=strlen(work_head)+strlen(work_end);
overall++; // NULL term
if (!(string=(gchar*)g_malloc(overall))) {
return NULL;
}
string[0]='\0';
strcat(string,rdf_head);
strcat(string,work_head);
if (work_title) strcat(string,work_title);
if (work_date) strcat(string,work_date);
if (work_description) strcat(string,work_description);
if (work_creator) strcat(string,work_creator);
if (work_owner) strcat(string,work_owner);
if (work_source) strcat(string,work_source);
if (work_license) strcat(string,work_license);
strcat(string,work_end);
if (license_head) {
strcat(string,license_head);
strcat(string,rdf->license->license_rdf);
strcat(string,license_end);
}
strcat(string,rdf_end);
return string;
}
*/
const gchar *RDFImpl::getReprText( Inkscape::XML::Node const * repr, struct rdf_work_entity_t const & entity )
{
case RDF_CONTENT:
case RDF_AGENT:
case RDF_RESOURCE:
case RDF_XML:
return "xml goes here";
case RDF_BAG:
/* clear the static string. yucky. */
/* backwards compatible: read contents */
}
temp ;
temp->firstChild()) {
if (bag) {
}
else {
}
}
}
return bag;
default:
break;
}
return NULL;
}
struct rdf_work_entity_t const & entity,
{
int i;
// set document's title element to the RDF title
}
}
case RDF_CONTENT:
return TRUE;
}
else {
return TRUE;
}
case RDF_AGENT:
}
}
return TRUE;
}
else {
return TRUE;
}
case RDF_RESOURCE:
return true;
case RDF_XML:
return 1;
case RDF_BAG:
/* backward compatibility: drop the dc:subject contents */
}
}
/* toss all the old list items */
}
/* chop our list up on commas */
}
g_strfreev( strlist );
return 1;
default:
break;
}
return 0;
}
{
if ( !node ) {
g_critical("Null node passed to ensureParentIsMetadata().");
g_critical( "No parent node when verifying <metadata> placement." );
} else {
if ( !metadata ) {
g_critical("Unable to create metadata element.");
} else {
// attach the metadata node
// move the node into it
sp_repr_unparent( node );
}
}
}
}
{
if ( !doc ) {
g_critical("Null doc passed to getRdfRootRepr()");
} else if ( !doc->getReprDoc() ) {
g_critical("XML doc is null.");
} else {
}
return rdf;
}
{
if ( !doc ) {
g_critical("Null doc passed to ensureRdfRootRepr()");
} else if ( !doc->getReprDoc() ) {
g_critical("XML doc is null.");
} else {
if ( !rdf ) {
if ( !svg ) {
g_critical("Unable to locate svg element.");
} else {
if ( !parent ) {
g_critical("Unable to create metadata element");
} else {
}
}
g_critical("Parent has no document");
} else if ( parent ) {
if ( !rdf ) {
g_critical("Unable to create root RDF element.");
} else {
}
}
}
}
}
if ( rdf ) {
}
return rdf;
}
{
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 {
if ( rdf ) {
}
}
return xml;
}
{
}
{
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 {
if ( rdf ) {
if ( !xml ) {
if ( !xml ) {
} else {
}
}
}
}
return xml;
}
{
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 {
if ( work ) {
}
}
return item;
}
{
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 {
if ( work ) {
if ( !item ) {
//printf("missing XML '%s'\n",name);
if ( !item ) {
} else {
}
}
}
}
return item;
}
// Public API:
{
if ( !doc ) {
g_critical("Null doc passed to rdf_get_work_entity()");
} else if ( entity ) {
//g_message("want '%s'\n",entity->title);
//g_message("found '%s' == '%s'\n", entity->title, result );
}
return result;
}
{
if ( item ) {
// TODO note that this is the location that used to set the title if needed. Ensure code it not required.
}
return result;
}
// Public API:
{
unsigned int result = 0;
if ( !doc ) {
g_critical("Null doc passed to rdf_set_work_entity()");
} else if ( entity ) {
}
return result;
}
unsigned int RDFImpl::setWorkEntity(SPDocument * doc, struct rdf_work_entity_t & entity, const gchar * text)
{
int result = 0;
if ( !text ) {
// FIXME: on a "NULL" text, delete the entity. For now, blank it.
text = "";
}
/*
printf("changing '%s' (%s) to '%s'\n",
entity->title,
entity->tag,
text);
*/
if ( !item ) {
g_critical("Unable to get work element");
} else {
}
return result;
}
static bool
{
#ifdef DEBUG_MATCH
#endif
int count = 0;
count++;
}
#ifdef DEBUG_MATCH
#endif
for (int i=0; i<count; i++) {
// skip already matched items
if (matched[i]) continue;
#ifdef DEBUG_MATCH
#endif
#ifdef DEBUG_MATCH
printf("\t\tgood!\n");
#endif
break;
}
}
if (!found_match) {
// if we checked each known item of the license
// and didn't find it, we must abort
#ifdef DEBUG_MATCH
#endif
break;
}
}
#ifdef DEBUG_MATCH
#endif
// scan looking for an unmatched item
if (matched[i]==0) {
#ifdef DEBUG_MATCH
#endif
}
}
#ifdef DEBUG_MATCH
#endif
#ifdef DEBUG_MATCH
#endif
return result;
}
// Public API:
{
}
{
// Base license lookup on the URI of cc:license rather than the license
// properties, per instructions from the ccREL gurus.
g_critical("Can't find internal entity structure for 'license_uri'");
return NULL;
}
break;
}
}
}
// To improve backward compatibility, the old license matching code is
// kept as fallback and to warn about and fix discrepancies.
// TODO: would it be better to do this code on document load? Is
// sp_metadata_build() then the right place to put the call to sort out
// any RDF mess?
if (repr) {
break;
}
}
}
// Both property and structure, use property
if (license_by_uri != license_by_properties) {
// TODO: this should be a user-visible warning, but how?
g_warning("Mismatch between %s and %s metadata:\n"
"%s value URI: %s (using this one!)\n"
"%s derived URI: %s",
}
// Reset license structure to match so the document is consistent
// (and this will also silence the warning above on repeated calls).
return license_by_uri;
}
else if (license_by_uri != NULL) {
// Only cc:license property, set structure for backward compatiblity
return license_by_uri;
}
else if (license_by_properties != NULL) {
// Only cc:License structure
// TODO: this could be a user-visible warning too
g_warning("No %s metadata found, derived license URI from %s: %s",
// Set license property to match
return license_by_properties;
}
// No license info at all
return NULL;
}
// Public API:
{
}
{
// When basing license check on only the license URI (see fix for
// https://bugs.launchpad.net/inkscape/+bug/372427 above) we should
// really drop this license section, but keep writing it for a while for
// compatibility with older versions.
// drop old license section
if (repr) {
}
if ( !license ) {
// All done
} else if ( !doc->getReprDoc() ) {
g_critical("XML doc is null.");
} else {
// build new license section
}
}
}
struct rdf_entity_default_t {
};
{ "type", "http://purl.org/dc/dcmitype/StillImage", },
};
// Public API:
{
}
{
// Create metadata node if it doesn't already exist
if ( !doc->getReprDoc()) {
g_critical("XML doc is null.");
} else {
// create repr
// insert into the document
// clean up
}
}
// install defaults
}
}
}
/*
* Add the metadata stored in the users preferences to the document if
* b) there is no metadata already in the file (such as from a template)
*/
{
return;
}
// If there is already some metadata in the doc (from a template) dont add default metadata
return;
}
}
// Put the metadata from user preferences into the doc
}
}
}
}
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :