From: <svn...@op...> - 2005-04-05 14:36:39
|
Author: abauer Date: 2005-04-05 16:37:54 +0200 (Tue, 05 Apr 2005) New Revision: 439 Added: branches/experimental-branch/formats/vformats-xml/xml-vnote.h Modified: branches/experimental-branch/formats/note.c branches/experimental-branch/formats/vformats-xml/Makefile.am branches/experimental-branch/formats/vformats-xml/xml-vnote.c branches/experimental-branch/osengine/osengine_mapcmds.c branches/experimental-branch/tools/osyncplugin.c Log: Implemented the vnote conversion and comparison correctly Modified: branches/experimental-branch/formats/note.c =================================================================== --- branches/experimental-branch/formats/note.c 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/formats/note.c 2005-04-05 14:37:54 UTC (rev 439) @@ -1,6 +1,7 @@ #include <opensync/opensync.h> #include <glib.h> #include <stdio.h> +#include <string.h> static osync_bool detect_plain_as_vnote(OSyncFormatEnv *env, const char *data, int size) { @@ -17,10 +18,20 @@ return CONV_DATA_MISMATCH; } +static void create_vnote11(OSyncChange *change) +{ + char *vnote = g_strdup_printf("BEGIN:VNOTE\r\nVERSION:1.1\r\nBODY:%s\r\nSUMMARY:%s\r\nEND:VNOTE", osync_rand_str(20), osync_rand_str(6)); + + osync_change_set_data(change, vnote, strlen(vnote) + 1, TRUE); + if (!osync_change_get_uid(change)) + osync_change_set_uid(change, osync_rand_str(8)); +} + void get_info(OSyncEnv *env) { osync_env_register_objtype(env, "note"); osync_env_register_objformat(env, "note", "vnote11"); osync_env_register_detector(env, "plain", "vnote11", detect_plain_as_vnote); + osync_env_format_set_create_func(env, "vnote11", create_vnote11); osync_env_format_set_compare_func(env, "vnote11", compare_vnote); } Modified: branches/experimental-branch/formats/vformats-xml/Makefile.am =================================================================== --- branches/experimental-branch/formats/vformats-xml/Makefile.am 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/formats/vformats-xml/Makefile.am 2005-04-05 14:37:54 UTC (rev 439) @@ -9,7 +9,8 @@ vformat.h \ opensync-xml.h \ xml-vcard.h \ - xml-vcal.h + xml-vcal.h \ + xml-vnote.h opensyncheader_HEADERS = opensync-xml.h Modified: branches/experimental-branch/formats/vformats-xml/xml-vnote.c =================================================================== --- branches/experimental-branch/formats/vformats-xml/xml-vnote.c 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/formats/vformats-xml/xml-vnote.c 2005-04-05 14:37:54 UTC (rev 439) @@ -1,5 +1,5 @@ /* - * xml-vcard - A plugin for parsing vcard objects for the opensync framework + * xml-vnote - A plugin for parsing vnote objects for the opensync framework * Copyright (C) 2004-2005 Armin Bauer <arm...@op...> * * This library is free software; you can redistribute it and/or @@ -20,93 +20,190 @@ #include "opensync-xml.h" #include "vformat.h" +#include "xml-vnote.h" #include <glib.h> -static osync_bool conv_vnote_to_xml(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error) +static void handle_unknown_parameter(xmlNode *current, VFormatParam *param) { - osync_debug("VNOTE", 4, "start: %s", __func__); - printf("input is %i\n%s\n", inpsize, input); + osync_trace(TRACE_INTERNAL, "Handling unknown parameter %s", vformat_attribute_param_get_name(param)); + xmlNode *property = xmlNewChild(current, NULL, (xmlChar*)"UnknownParam", + (xmlChar*)vformat_attribute_param_get_nth_value(param, 0)); + osxml_node_add(property, "ParamName", vformat_attribute_param_get_name(param)); +} + +static xmlNode *handle_created_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling created attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"DateCreated", NULL); + osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0)); + return current; +} + +static xmlNode *handle_last_modified_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling last_modified attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"LastModified", NULL); + osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0)); + return current; +} + +static xmlNode *handle_summary_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling summary attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"Summary", NULL); + osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0)); + return current; +} + +static xmlNode *handle_categories_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling Categories attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"Categories", NULL); - /*GList *p = NULL; - GList *a = NULL; + GList *values = vformat_attribute_get_values_decoded(attr); + for (; values; values = values->next) { + GString *retstr = (GString *)values->data; + g_assert(retstr); + osxml_node_add(current, "Category", retstr->str); + } - VFormat *vcard = vformat_new_from_string(input); - vformat_dump_structure (vcard); - GList *attributes = vformat_get_attributes(vcard); - xmlDoc *doc = xmlNewDoc("1.0"); - xmlNode *root = osxml_node_add_root(doc, "note"); + return current; +} + +static xmlNode *handle_body_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling body attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"Body", NULL); + osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0)); + return current; +} + +static xmlNode *handle_class_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling Class attribute"); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"Class", NULL); + osxml_node_add(current, "Content", vformat_attribute_get_nth_value(attr, 0)); + return current; +} + +static void handle_type_parameter(xmlNode *current, VFormatParam *param) +{ + osync_trace(TRACE_INTERNAL, "Handling type parameter %s", vformat_attribute_param_get_name(param)); + xmlNewChild(current, NULL, (xmlChar*)"Type", + (xmlChar*)vformat_attribute_param_get_nth_value(param, 0)); +} + +static xmlNode *handle_unknown_attribute(xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_INTERNAL, "Handling unknown attribute %s", vformat_attribute_get_name(attr)); + xmlNode *current = xmlNewChild(root, NULL, (xmlChar*)"UnknownNode", NULL); + osxml_node_add(current, "NodeName", vformat_attribute_get_name(attr)); + GList *values = vformat_attribute_get_values_decoded(attr); + for (; values; values = values->next) { + GString *retstr = (GString *)values->data; + g_assert(retstr); + osxml_node_add(current, "Content", retstr->str); + } + return current; +} + +static void vnote_handle_parameter(GHashTable *hooks, xmlNode *current, VFormatParam *param) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, hooks, current, param); - for (a = attributes; a; a = a->next) { - VFormatAttribute *attr = a->data; - const char *name = vformat_attribute_get_name(attr); + //Find the handler for this parameter + void (* param_handler)(xmlNode *, VFormatParam *); + char *paramname = g_strdup_printf("%s=%s", vformat_attribute_param_get_name(param), vformat_attribute_param_get_nth_value(param, 0)); + param_handler = g_hash_table_lookup(hooks, paramname); + g_free(paramname); + if (!param_handler) + param_handler = g_hash_table_lookup(hooks, vformat_attribute_param_get_name(param)); + + if (param_handler == HANDLE_IGNORE) { + osync_trace(TRACE_EXIT, "%s: Ignored", __func__); + return; + } + + if (param_handler) + param_handler(current, param); + else + handle_unknown_parameter(current, param); + + osync_trace(TRACE_EXIT, "%s", __func__); +} - if (!strcmp(name, "VERSION")) - continue; - - if (!strcmp(name, "BEGIN")) { - root = osxml_node_add_root(doc, "note"); - continue; - } - - xmlNode *current = xmlNewChild(root, NULL, "", NULL); - - //Created - if (!strcmp(name, "DCREATED")) { - osxml_node_set(current, "Created", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } +static void vnote_handle_attribute(GHashTable *hooks, xmlNode *root, VFormatAttribute *attr) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, root, attr, attr ? vformat_attribute_get_name(attr) : "None"); + xmlNode *current = NULL; + + //Dont add empty stuff + GList *v; + for (v = vformat_attribute_get_values(attr); v; v = v->next) { + char *value = v->data; + if (strlen(value) != 0) + goto has_value; + } + osync_trace(TRACE_EXIT, "%s: No values", __func__); + return; + +has_value:; + + //We need to find the handler for this attribute + xmlNode *(* attr_handler)(xmlNode *, VFormatAttribute *) = g_hash_table_lookup(hooks, vformat_attribute_get_name(attr)); + osync_trace(TRACE_INTERNAL, "Hook is: %p", attr_handler); + if (attr_handler == HANDLE_IGNORE) { + osync_trace(TRACE_EXIT, "%s: Ignored", __func__); + return; + } + if (attr_handler) + current = attr_handler(root, attr); + else + current = handle_unknown_attribute(root, attr); - //LastModified - if (!strcmp(name, "LAST_MODIFIED")) { - osxml_node_set(current, "LastModified", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } - - //Summary - if (!strcmp(name, "SUMMARY")) { - osxml_node_set(current, "Summary", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } - - //Body - if (!strcmp(name, "BODY")) { - osxml_node_set(current, "Body", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } - - //Categories - if (!strcmp(name, "CATEGORIES")) { - osxml_node_set(current, "Categories", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } - - //Class - if (!strcmp(name, "CLASS")) { - osxml_node_set(current, "Class", vformat_attribute_get_nth_value(attr, 0), encoding); - continue; - } - - //Unknown tag. - osxml_node_mark_unknown(current); - GList *values = vformat_attribute_get_values(attr); - GString *string = g_string_new(vformat_attribute_get_nth_value(attr, 0)); - for (p = values->next; p; p = p->next) { - g_string_sprintfa(string, ";%s", (char *)p->data); - } - osxml_node_add(current, "NodeName", name); - osxml_node_set(current, "UnknownNode", string->str, encoding); - g_string_free(string, 1); - }*/ + //Handle all parameters of this attribute + GList *params = vformat_attribute_get_params(attr); + GList *p = NULL; + for (p = params; p; p = p->next) { + VFormatParam *param = p->data; + vnote_handle_parameter(hooks, current, param); + } + osync_trace(TRACE_EXIT, "%s", __func__); +} + +static osync_bool conv_vnote_to_xml(void *conv_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, conv_data, input, inpsize, output, outpsize, free_input, error); + GHashTable *hooks = (GHashTable *)conv_data; + + osync_trace(TRACE_INTERNAL, "Input vnote is:\n%s", input); + + //Parse the vnote + VFormat *vnote = vformat_new_from_string(input); + + osync_trace(TRACE_INTERNAL, "Creating xml doc"); + + //Create a new xml document + xmlDoc *doc = xmlNewDoc((xmlChar*)"1.0"); + xmlNode *root = osxml_node_add_root(doc, "Note"); + + osync_trace(TRACE_INTERNAL, "parsing attributes"); + + //For every attribute we have call the handling hook + GList *attributes = vformat_get_attributes(vnote); + GList *a = NULL; + for (a = attributes; a; a = a->next) { + VFormatAttribute *attr = a->data; + vnote_handle_attribute(hooks, root, attr); + } + + osync_trace(TRACE_INTERNAL, "Output XML is:\n%s", osxml_write_to_string(doc)); + *free_input = TRUE; - //*output = (char *)doc; - /*FIXME: this is not really the size of the data pointed by doc. - * But this shouldn't cause problems, anyway, because this - * size field should never be used for xml docs. Actually, - * what needs fixing is the code that uses the size - * field for changes with xml data. - */ - //*outpsize = sizeof(doc); + *output = (char *)doc; + *outpsize = sizeof(doc); + osync_trace(TRACE_EXIT, "%s: TRUE", __func__); return TRUE; } @@ -155,89 +252,200 @@ g_free(tmp); } +static void handle_xml_type_parameter(VFormatAttribute *attr, xmlNode *current) +{ + osync_trace(TRACE_INTERNAL, "Handling type xml parameter"); + char *content = (char*)xmlNodeGetContent(current); + vformat_attribute_add_param_with_value(attr, "TYPE", content); + g_free(content); +} + +static void handle_xml_category_parameter(VFormatAttribute *attr, xmlNode *current) +{ + osync_trace(TRACE_INTERNAL, "Handling category xml parameter"); + char *content = (char*)xmlNodeGetContent(current); + vformat_attribute_add_value(attr, content); + g_free(content); +} + +static void xml_handle_unknown_parameter(VFormatAttribute *attr, xmlNode *current) +{ + osync_trace(TRACE_INTERNAL, "Handling unknown xml parameter %s", current->name); + char *content = (char*)xmlNodeGetContent(current); + vformat_attribute_add_param_with_value(attr, (char*)current->name, content); + g_free(content); +} + +static VFormatAttribute *handle_xml_categories_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + osync_trace(TRACE_INTERNAL, "Handling categories xml attribute"); + VFormatAttribute *attr = vformat_attribute_new(NULL, "CATEGORIES"); + vformat_add_attribute(vnote, attr); + return attr; +} + +static VFormatAttribute *handle_xml_class_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + osync_trace(TRACE_INTERNAL, "Handling class xml attribute"); + VFormatAttribute *attr = vformat_attribute_new(NULL, "CLASS"); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vnote, attr); + return attr; +} + +static VFormatAttribute *handle_xml_summary_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + VFormatAttribute *attr = vformat_attribute_new(NULL, "SUMMARY"); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vnote, attr); + return attr; +} + +static VFormatAttribute *handle_xml_body_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + VFormatAttribute *attr = vformat_attribute_new(NULL, "BODY"); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vnote, attr); + return attr; +} + +static VFormatAttribute *handle_xml_created_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + VFormatAttribute *attr = vformat_attribute_new(NULL, "DCREATED"); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vnote, attr); + return attr; +} + +static VFormatAttribute *handle_xml_last_modified_attribute(VFormat *vcard, xmlNode *root, const char *encoding) +{ + VFormatAttribute *attr = vformat_attribute_new(NULL, "LAST-MODIFIED"); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vcard, attr); + return attr; +} + +static void xml_vnote_handle_parameter(OSyncHookTables *hooks, VFormatAttribute *attr, xmlNode *current) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, attr, current, current ? (char *)current->name : "None"); + + //Find the handler for this parameter + void (* xml_param_handler)(VFormatAttribute *attr, xmlNode *); + char *content = (char*)xmlNodeGetContent(current); + char *paramname = g_strdup_printf("%s=%s", current->name, content); + g_free(content); + xml_param_handler = g_hash_table_lookup(hooks->parameters, paramname); + g_free(paramname); + if (!xml_param_handler) + xml_param_handler = g_hash_table_lookup(hooks->parameters, current->name); + + if (xml_param_handler == HANDLE_IGNORE) { + osync_trace(TRACE_EXIT, "%s: Ignored", __func__); + return; + } + + if (xml_param_handler) + xml_param_handler(attr, current); + + osync_trace(TRACE_EXIT, "%s", __func__); +} + +static VFormatAttribute *xml_handle_unknown_attribute(VFormat *vnote, xmlNode *root, const char *encoding) +{ + osync_trace(TRACE_INTERNAL, "Handling unknown xml attribute %s", root->name); + char *name = osxml_find_node(root, "Name"); + VFormatAttribute *attr = vformat_attribute_new(NULL, name); + add_value(attr, root, "Content", encoding); + vformat_add_attribute(vnote, attr); + return attr; +} + +static void xml_vnote_handle_attribute(OSyncHookTables *hooks, VFormat *vnote, xmlNode *root, const char *encoding) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p:%s)", __func__, hooks, vnote, root, root ? (char *)root->name : "None"); + VFormatAttribute *attr = NULL; + + //We need to find the handler for this attribute + VFormatAttribute *(* xml_attr_handler)(VFormat *vnote, xmlNode *root, const char *) = g_hash_table_lookup(hooks->attributes, root->name); + osync_trace(TRACE_INTERNAL, "xml hook is: %p", xml_attr_handler); + if (xml_attr_handler == HANDLE_IGNORE) { + osync_trace(TRACE_EXIT, "%s: Ignored", __func__); + return; + } + if (xml_attr_handler) + attr = xml_attr_handler(vnote, root, encoding); + else { + osync_trace(TRACE_EXIT, "%s: Ignored2", __func__); + return; + } + + //Handle all parameters of this attribute + xmlNode *child = root->xmlChildrenNode; + while (child) { + xml_vnote_handle_parameter(hooks, attr, child); + child = child->next; + } + osync_trace(TRACE_EXIT, "%s", __func__); +} + static osync_bool conv_xml_to_vnote(void *user_data, char *input, int inpsize, char **output, int *outpsize, osync_bool *free_input, OSyncError **error) { - osync_debug("VNOTE", 4, "start: %s", __func__); - xmlDocDump(stdout, (xmlDoc *)input); - VFormatAttribute *attr = NULL; - xmlNode *root = osxml_node_get_root((xmlDoc *)input, "note", error); - if (!root) + osync_trace(TRACE_ENTRY, "%s(%p, %p, %i, %p, %p, %p, %p)", __func__, user_data, input, inpsize, output, outpsize, free_input, error); + + osync_trace(TRACE_INTERNAL, "Input XML is:\n%s", osxml_write_to_string((xmlDoc *)input)); + + //Get the root node of the input document + xmlNode *root = osxml_node_get_root((xmlDoc *)input, "Note", error); + if (!root) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to get root element of xml-note"); + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); return FALSE; + } - VFormat *vcard = vformat_new(); + //Make the new vnote + VFormat *vnote = vformat_new(); - const char *std_encoding = "QUOTED-PRINTABLE"; - + osync_trace(TRACE_INTERNAL, "parsing xml attributes"); while (root) { - if (!strcmp((char*)root->name, "Created")) { - //Created - attr = vformat_attribute_new(NULL, "DCREATED"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "LastModifed")) { - //LastModifed - attr = vformat_attribute_new(NULL, "LAST-MODIFIED"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "Summary")) { - //Summary - attr = vformat_attribute_new(NULL, "SUMMARY"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "Body")) { - //Body - attr = vformat_attribute_new(NULL, "BODY"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "Categories")) { - //Categories - attr = vformat_attribute_new(NULL, "CATEGORIES"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "Class")) { - //Class - attr = vformat_attribute_new(NULL, "CLASS"); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } else if (!strcmp((char*)root->name, "UnknownNode")) { - //Unknown Node - attr = vformat_attribute_new(NULL, osxml_find_node(root, "NodeName")); - add_value(attr, root, "Content", std_encoding); - vformat_add_attribute(vcard, attr); - } - + xml_vnote_handle_attribute((OSyncHookTables *)user_data, vnote, root, "QUOTED-PRINTABLE"); root = root->next; } *free_input = TRUE; - *output = vformat_to_string(vcard, VFORMAT_NOTE); - *outpsize = strlen(*output); + *output = vformat_to_string(vnote, VFORMAT_NOTE); + osync_trace(TRACE_INTERNAL, "vnote output is: \n%s", *output); + *outpsize = strlen(*output) + 1; + osync_trace(TRACE_EXIT, "%s", __func__); + return TRUE; } static OSyncConvCmpResult compare_notes(OSyncChange *leftchange, OSyncChange *rightchange) { + osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, leftchange, rightchange); + OSyncXMLScore score[] = { - {50, "/note/Summary"}, - {50, "/note/Class"}, - {50, "/note/Body"}, + {100, "/Note/Summary"}, + {100, "/Note/Body"}, + {0, "/Note/*/Type"}, + {0, "/Note/Uid"}, + {0, "/Note/LastModified"}, + {0, "/Note/DateCreated"}, {0, NULL} }; - return osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 10, 50); + OSyncConvCmpResult ret = osxml_compare((xmlDoc*)osync_change_get_data(leftchange), (xmlDoc*)osync_change_get_data(rightchange), score, 0, 199); + + osync_trace(TRACE_EXIT, "%s: %i", __func__, ret); + return ret; } static char *print_note(OSyncChange *change) { - osync_debug("VNOTE", 4, "start: %s", __func__); xmlDoc *doc = (xmlDoc *)osync_change_get_data(change); - char *result; - int size; - osync_bool free; - if (!conv_xml_to_vnote(NULL, (char*)doc, 0, &result, &size, &free, NULL)) - return NULL; - return result; + + return osxml_write_to_string(doc); } static void destroy_xml(char *data, size_t size) @@ -245,15 +453,110 @@ xmlFreeDoc((xmlDoc *)data); } +static void *init_vnote_to_xml(void) +{ + osync_trace(TRACE_ENTRY, "%s", __func__); + GHashTable *table = g_hash_table_new(g_str_hash, g_str_equal); + + g_hash_table_insert(table, "X-IRMC-LUID", HANDLE_IGNORE); + g_hash_table_insert(table, "DCREATED", handle_created_attribute); + g_hash_table_insert(table, "LAST-MODIFIED", handle_last_modified_attribute); + g_hash_table_insert(table, "SUMMARY", handle_summary_attribute); + g_hash_table_insert(table, "BODY", handle_body_attribute); + g_hash_table_insert(table, "CLASS", handle_class_attribute); + g_hash_table_insert(table, "CATEGORIES", handle_categories_attribute); + + g_hash_table_insert(table, "VERSION", HANDLE_IGNORE); + g_hash_table_insert(table, "BEGIN", HANDLE_IGNORE); + g_hash_table_insert(table, "END", HANDLE_IGNORE); + + g_hash_table_insert(table, "ENCODING", HANDLE_IGNORE); + g_hash_table_insert(table, "CHARSET", HANDLE_IGNORE); + + g_hash_table_insert(table, "TYPE", handle_type_parameter); + + osync_trace(TRACE_EXIT, "%s: %p", __func__, table); + return (void *)table; +} + +static void fin_vnote_to_xml(void *data) +{ + g_hash_table_destroy((GHashTable *)data); +} + +static void *init_xml_to_vnote(void) +{ + osync_trace(TRACE_ENTRY, "%s", __func__); + + OSyncHookTables *hooks = g_malloc0(sizeof(OSyncHookTables)); + + hooks->attributes = g_hash_table_new(g_str_hash, g_str_equal); + hooks->parameters = g_hash_table_new(g_str_hash, g_str_equal); + + g_hash_table_insert(hooks->attributes, "Summary", handle_xml_summary_attribute); + g_hash_table_insert(hooks->attributes, "Body", handle_xml_body_attribute); + g_hash_table_insert(hooks->attributes, "Class", handle_xml_class_attribute); + g_hash_table_insert(hooks->attributes, "Categories", handle_xml_categories_attribute); + g_hash_table_insert(hooks->attributes, "UnknownNode", xml_handle_unknown_attribute); + g_hash_table_insert(hooks->attributes, "DateCreated", handle_xml_created_attribute); + g_hash_table_insert(hooks->attributes, "LastModified", handle_xml_last_modified_attribute); + + g_hash_table_insert(hooks->parameters, "Type", handle_xml_type_parameter); + g_hash_table_insert(hooks->parameters, "Category", handle_xml_category_parameter); + + g_hash_table_insert(hooks->parameters, "UnknownParameter", xml_handle_unknown_parameter); + + osync_trace(TRACE_EXIT, "%s: %p", __func__, hooks); + return (void *)hooks; +} + +static void fin_xml_to_vnote(void *data) +{ + OSyncHookTables *hooks = (OSyncHookTables *)hooks; + g_hash_table_destroy(hooks->attributes); + g_hash_table_destroy(hooks->parameters); + g_free(hooks); +} + +static time_t get_revision(OSyncChange *change, OSyncError **error) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, change, error); + + xmlDoc *doc = (xmlDoc *)osync_change_get_data(change); + + xmlXPathObject *xobj = osxml_get_nodeset(doc, "/Note/LastModified"); + + xmlNodeSet *nodes = xobj->nodesetval; + + int size = (nodes) ? nodes->nodeNr : 0; + if (size != 1) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "Unable to find the revision"); + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return -1; + } + + char *revision = (char*)osxml_find_node(nodes->nodeTab[0], "Content"); + + osync_trace(TRACE_INTERNAL, "About to convert string %s", revision); + time_t time = vformat_time_to_unix(revision); + g_free(revision); + xmlXPathFreeObject(xobj); + osync_trace(TRACE_EXIT, "%s: %i", __func__, time); + return time; +} + void get_info(OSyncEnv *env) { osync_env_register_objtype(env, "note"); osync_env_register_objformat(env, "note", "xml-note"); - osync_env_format_set_compare_func(env, "xml-note", compare_notes); osync_env_format_set_destroy_func(env, "xml-note", destroy_xml); osync_env_format_set_print_func(env, "xml-note", print_note); + osync_env_format_set_copy_func(env, "xml-note", osxml_copy); + osync_env_format_set_revision_func(env, "xml-note", get_revision); osync_env_register_converter(env, CONVERTER_CONV, "vnote11", "xml-note", conv_vnote_to_xml); + osync_env_converter_set_init(env, "vnote11", "xml-note", init_vnote_to_xml, fin_vnote_to_xml); osync_env_register_converter(env, CONVERTER_CONV, "xml-note", "vnote11", conv_xml_to_vnote); + osync_env_converter_set_init(env, "xml-note", "vnote11", init_xml_to_vnote, fin_xml_to_vnote); } Added: branches/experimental-branch/formats/vformats-xml/xml-vnote.h =================================================================== --- branches/experimental-branch/formats/vformats-xml/xml-vnote.h 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/formats/vformats-xml/xml-vnote.h 2005-04-05 14:37:54 UTC (rev 439) @@ -0,0 +1,11 @@ +#ifndef _XMLVNOTE_H_ +#define _XMLVNOTE_H_ + +typedef struct OSyncHookTables { + GHashTable *attributes; + GHashTable *parameters; +} OSyncHookTables; + +#define HANDLE_IGNORE (void *)1 + +#endif //_XMLVNOTE_H_ Modified: branches/experimental-branch/osengine/osengine_mapcmds.c =================================================================== --- branches/experimental-branch/osengine/osengine_mapcmds.c 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/osengine/osengine_mapcmds.c 2005-04-05 14:37:54 UTC (rev 439) @@ -447,7 +447,7 @@ */ osync_bool osengine_mapping_solve_latest(OSyncEngine *engine, OSyncMapping *mapping, OSyncError **error) { - osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, engine, mapping, error); + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, engine, mapping, error); time_t time = 0; time_t latesttime = 0; @@ -488,6 +488,55 @@ return TRUE; } +/** @brief Checks if the mapping could be solved with solve_latest + * + * This functions checks all changes to see if they contain valid + * timestamp information and if they could be used to solve but does + * not actually solve the mapping + * + * @param engine The engine + * @param mapping The conflicting mapping + * @param error A pointer to an error + * @returns TRUE if the mapping could be solved, FALSE otherwise + * + */ +osync_bool osengine_mapping_check_timestamps(OSyncEngine *engine, OSyncMapping *mapping, OSyncError **error) +{ + osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, engine, mapping, error); + + time_t time = 0; + time_t latesttime = 0; + osync_bool preveq = FALSE; + + GList *e = NULL; + for (e = mapping->entries; e; e = e->next) { + OSyncMappingEntry *entry = e->data; + + if (osync_change_get_changetype(entry->change) != CHANGE_UNKNOWN) { + time = osync_change_get_revision(entry->change, error); + if (time == -1) { + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return FALSE; + } + + if (time > latesttime) { + latesttime = time; + preveq = FALSE; + } else if (time == latesttime) + preveq = TRUE; + } + } + + if (preveq == TRUE) { + osync_error_set(error, OSYNC_ERROR_GENERIC, "Could not decide for one entry. Timestamps where equal"); + osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); + return FALSE; + } + + osync_trace(TRACE_EXIT, "%s", __func__); + return TRUE; +} + /** @brief Solves a mapping by setting an updated change * * Solves the mapping by setting an updated change. The change should have been edited by the user. Modified: branches/experimental-branch/tools/osyncplugin.c =================================================================== --- branches/experimental-branch/tools/osyncplugin.c 2005-04-05 14:36:18 UTC (rev 438) +++ branches/experimental-branch/tools/osyncplugin.c 2005-04-05 14:37:54 UTC (rev 439) @@ -312,16 +312,19 @@ char *config; int size; - if (!osync_file_read(configfile, &config, &size, &error)) { - fprintf(stderr, "Unable to read config: %s\n", osync_error_print(&error)); - osync_error_free(&error); - return 1; + if (configfile) { + if (!osync_file_read(configfile, &config, &size, &error)) { + fprintf(stderr, "Unable to read config: %s\n", osync_error_print(&error)); + osync_error_free(&error); + return 1; + } } char *testdir = g_strdup_printf("%s/plgtest.XXXXXX", g_get_tmp_dir()); mkdtemp(testdir); - osync_member_set_config(member, config, size); + if (configfile) + osync_member_set_config(member, config, size); osync_member_set_pluginname(member, pluginname); osync_member_set_configdir(member, testdir); OSyncMemberFunctions *functions = osync_member_get_memberfunctions(member); |