c++/lib c++/tests schemas/ical

Christian Mollekopf mollekopf at kolabsys.com
Thu Feb 23 11:37:30 CET 2012


 c++/lib/CMakeLists.txt            |    2 
 c++/lib/kolabcontainers.h         |    3 
 c++/lib/kolabformat.cpp           |   14 -
 c++/lib/kolabformat.h             |    1 
 c++/lib/kolabjournal.cpp          |  191 +++++++++++++++++++++++++
 c++/lib/kolabjournal.h            |   86 +++++++++++
 c++/lib/xcalconversions.h         |  281 ++++++++++++++++++++++----------------
 c++/tests/bindingstest.cpp        |   83 +++++++++++
 c++/tests/bindingstest.h          |    1 
 schemas/ical/kolabformat-xcal.xsd |    2 
 10 files changed, 534 insertions(+), 130 deletions(-)

New commits:
commit 20baaf576d4d937648f303cbccdc6a0f456b3e31
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Feb 23 11:37:20 2012 +0100

    Journals

diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index e98acdc..4eda448 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -9,7 +9,7 @@ SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1)
 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC " ) #always generate shared libraries with -fPIC
 
 #Library with serialization/deserialization code and kolab-containers
-add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
+add_library(kolabxml SHARED kolabformat.cpp kolabcontainers.cpp kolabevent.cpp kolabtodo.cpp kolabjournal.cpp kolabcontact.cpp utils.cpp base64.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
 target_link_libraries(kolabxml ${XERCES_C})
 
 #For the core library we can be stricter when compiling. This doesn't work with the auto generated code though.
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index b124b0f..9f5a03f 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -341,9 +341,6 @@ struct CustomProperty {
 
 //Prepared Kolab Objects
 
-class Journal {
-    //TODO
-};
 
 class Note {
     //TODO
diff --git a/c++/lib/kolabformat.cpp b/c++/lib/kolabformat.cpp
index c6fd6fe..51e97d0 100644
--- a/c++/lib/kolabformat.cpp
+++ b/c++/lib/kolabformat.cpp
@@ -85,18 +85,16 @@ std::string writeTodo(const Kolab::Todo &event)
 
 Journal readJournal(const std::string& s, bool isUrl)
 {
-//     Kolab::IncidenceTrait<Kolab::Journal>::IncidencePtr ptr = deserializeIncidence< IncidenceTrait<Kolab::Journal> >(s, isUrl);
-//     if (!ptr.get()) {
-//         return Kolab::Journal();
-//     }
-//     return *ptr;
-    return Journal();
+    XCAL::IncidenceTrait<Kolab::Journal>::IncidencePtr ptr = XCAL::deserializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(s, isUrl);
+    if (!ptr.get()) {
+        return Kolab::Journal();
+    }
+    return *ptr;
 }
 
 std::string writeJournal(const Kolab::Journal &j)
 {
-//     return serializeIncidence< IncidenceTrait<Kolab::Journal> >(j);
-    return std::string();
+    return XCAL::serializeIncidence<XCAL::IncidenceTrait<Kolab::Journal> >(j);
 }
 
 
diff --git a/c++/lib/kolabformat.h b/c++/lib/kolabformat.h
index d265bf0..56e0c39 100644
--- a/c++/lib/kolabformat.h
+++ b/c++/lib/kolabformat.h
@@ -22,6 +22,7 @@
 #include "kolabcontainers.h"
 #include "kolabtodo.h"
 #include "kolabevent.h"
+#include "kolabjournal.h"
 #include "kolabcontact.h"
 #include "global_definitions.h"
 
diff --git a/c++/lib/kolabjournal.cpp b/c++/lib/kolabjournal.cpp
new file mode 100644
index 0000000..9b6b0f4
--- /dev/null
+++ b/c++/lib/kolabjournal.cpp
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "kolabjournal.h"
+#include "incidence_p.h"
+
+namespace Kolab {
+
+struct Journal::Private: public PrivateIncidence
+{
+    Private()
+    : PrivateIncidence() {}
+};
+
+Journal::Journal()
+: d(new Journal::Private())
+{
+}
+
+Journal::Journal(const Journal &other)
+: d(new Journal::Private())
+{
+    *d = *other.d;
+}
+
+Journal::~Journal()
+{
+}
+
+void Journal::operator=(const Kolab::Journal &other)
+{
+    *d = *other.d;
+}
+
+bool Journal::isValid()
+{
+    return !d->uid.empty();
+}
+
+void Journal::setUid(const std::string &uid)
+{
+    d->uid = uid;
+}
+
+std::string Journal::uid() const
+{
+    return d->uid;
+}
+
+void Journal::setCreated(const Kolab::DateTime &created)
+{
+    d->created = created;
+}
+
+DateTime Journal::created() const
+{
+    return d->created;
+}
+
+void Journal::setLastModified(const Kolab::DateTime &lastMod)
+{
+    d->lastModified = lastMod;
+}
+
+DateTime Journal::lastModified() const
+{
+    return d->lastModified;
+}
+
+void Journal::setSequence(int sequence)
+{
+    d->sequence = sequence;
+}
+
+int Journal::sequence() const
+{
+    return d->sequence;
+}
+
+void Journal::setClassification(Classification class_)
+{
+    d->classification = class_;
+}
+
+Classification Journal::classification() const
+{
+    return d->classification;
+}
+
+void Journal::setCategories(const std::vector< std::string > &categories)
+{
+    d->categories = categories;
+}
+
+void Journal::addCategory(const std::string &cat)
+{
+    d->categories.push_back(cat);
+}
+
+std::vector< std::string > Journal::categories() const
+{
+    return d->categories;
+}
+
+void Journal::setStart(const Kolab::DateTime &start)
+{
+    d->start = start;
+}
+
+DateTime Journal::start() const
+{
+    return d->start;
+}
+
+void Journal::setSummary(const std::string &summary)
+{
+    d->summary = summary;
+}
+
+std::string Journal::summary() const
+{
+    return d->summary;
+}
+
+void Journal::setDescription(const std::string &description)
+{
+    d->description = description;
+}
+
+std::string Journal::description() const
+{
+    return d->description;
+}
+
+
+void Journal::setStatus(Status status)
+{
+    d->status = status;
+}
+
+Status Journal::status() const
+{
+    return d->status;
+}
+
+void Journal::setAttendees(const std::vector< Attendee > &attendees)
+{
+    d->attendees = attendees;
+}
+
+std::vector< Attendee > Journal::attendees() const
+{
+    return d->attendees;
+}
+
+void Journal::setAttachments(const std::vector< Attachment > &attach)
+{
+    d->attachments = attach;
+}
+
+std::vector< Attachment > Journal::attachments() const
+{
+    return d->attachments;
+}
+
+void Journal::setCustomProperties(const std::vector< CustomProperty > &prop)
+{
+    d->customProperties = prop;
+}
+
+std::vector< CustomProperty > Journal::customProperties() const
+{
+    return d->customProperties;
+}
+
+
+}//Namespace
\ No newline at end of file
diff --git a/c++/lib/kolabjournal.h b/c++/lib/kolabjournal.h
new file mode 100644
index 0000000..d9806f2
--- /dev/null
+++ b/c++/lib/kolabjournal.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2012  Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef KOLABJOURNAL_H
+#define KOLABJOURNAL_H
+
+#include <string>
+#include <vector>
+#include <boost/scoped_ptr.hpp>
+#include "kolabcontainers.h"
+namespace Kolab {
+
+class Journal {
+public:
+    Journal();
+    ~Journal();
+    Journal(const Journal &);
+    void operator=(const Journal &);
+    
+    bool isValid();
+    
+    void setUid(const std::string &);
+    std::string uid() const;
+    
+    void setCreated(const DateTime &);
+    DateTime created() const;
+    
+    void setLastModified(const DateTime &);
+    DateTime lastModified() const;
+    
+    void setSequence(int);
+    int sequence() const;
+    
+    void setClassification(Classification);
+    Classification classification() const;
+
+    void setCategories(const std::vector<std::string> &);
+    void addCategory(const std::string &);
+    std::vector<std::string> categories() const;
+    
+    void setStart(const DateTime &);
+    DateTime start() const;
+    
+    void setSummary(const std::string &);
+    std::string summary() const;
+    
+    void setDescription(const std::string &);
+    std::string description() const;
+    
+    void setStatus(Status);
+    Status status() const;
+    
+    //TODO Contacts
+    
+    void setAttendees(const std::vector<Attendee> &);
+    std::vector<Attendee> attendees() const;
+    
+    void setAttachments(const std::vector<Attachment> &);
+    std::vector<Attachment> attachments() const;
+    
+    void setCustomProperties(const std::vector<CustomProperty> &);
+    std::vector<CustomProperty> customProperties() const;
+private:
+    struct Private;
+    boost::scoped_ptr<Private> d;
+};
+
+
+
+}
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/xcalconversions.h b/c++/lib/xcalconversions.h
index 32be15d..e0d3412 100644
--- a/c++/lib/xcalconversions.h
+++ b/c++/lib/xcalconversions.h
@@ -37,6 +37,7 @@
 #include "kolabcontainers.h"
 #include "kolabtodo.h"
 #include "kolabevent.h"
+#include "kolabjournal.h"
 #include "utils.h"
 #include "base64.h"
 
@@ -811,8 +812,6 @@ RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule)
     
 //--- Recurrence Rule ---
 
-
-
 template <typename I, typename T>
 void setIncidenceProperties(I &inc, const T &prop)
 {    
@@ -844,35 +843,6 @@ void setIncidenceProperties(I &inc, const T &prop)
         inc.setStart(*date);
     }
 
-    if (prop.rrule()) {
-       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
-       inc.setRecurrenceRule(*rrule);
-    }
-
-    if (prop.rdate()) {
-        inc.setRecurrenceDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
-        if (!prop.rdate()->period().empty()) {
-            ERROR("the period element must not be used, ignored.");
-        }
-    }
-
-    if (prop.exdate()) {
-       inc.setExceptionDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
-    }
-    
-    if (prop.recurrence_id()) {
-        bool thisandfuture = false;
-        if (prop.recurrence_id()->parameters()) {
-            const icalendar_2_0::RecurrenceIdPropType::parameters_type &parameters = *prop.recurrence_id()->parameters();
-            for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
-                if (dynamic_cast<const icalendar_2_0::RangeParamType*> (&*it)) {
-                    thisandfuture = true;
-                }
-            }
-        }
-        inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture);
-    }
-
     if (prop.summary()) {
         inc.setSummary(toString(*prop.summary()));
     }
@@ -881,10 +851,6 @@ void setIncidenceProperties(I &inc, const T &prop)
         inc.setDescription(toString(*prop.description()));
     }
 
-    if (prop.priority()) {
-        inc.setPriority(toInt(*prop.priority()));
-    }
-
     if (prop.status()) {
         const std::string &status =  toString(*prop.status());
         if (status == NEEDSACTION) {
@@ -907,17 +873,6 @@ void setIncidenceProperties(I &inc, const T &prop)
             ERROR("Unhandled status");
         }
     }
-
-    if (prop.location()) {
-        inc.setLocation(toString(*prop.location()));
-    }
-    
-    if (prop.organizer()) {
-        std::string email;
-        std::string name;
-        setCalAddress(*prop.organizer(), email, name);
-        inc.setOrganizer(email, name);
-    }
     
     if (prop.attendee().size()) {
         std::vector<Kolab::Attendee> attendees;
@@ -977,6 +932,57 @@ void setIncidenceProperties(I &inc, const T &prop)
 
 }
 
+template <typename I, typename T>
+void setTodoEventProperties(I &inc, const T &prop)
+{
+
+    if (prop.rrule()) {
+       RecurrencePtr rrule = toRRule(prop.rrule()->recur());
+       inc.setRecurrenceRule(*rrule);
+    }
+
+    if (prop.rdate()) {
+        inc.setRecurrenceDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::rdate_type>(*prop.rdate()));
+        if (!prop.rdate()->period().empty()) {
+            ERROR("the period element must not be used, ignored.");
+        }
+    }
+
+    if (prop.exdate()) {
+       inc.setExceptionDates(toDateTimeList<icalendar_2_0::KolabEvent::properties_type::exdate_type>(*prop.exdate()));
+    }
+    
+    if (prop.recurrence_id()) {
+        bool thisandfuture = false;
+        if (prop.recurrence_id()->parameters()) {
+            const icalendar_2_0::RecurrenceIdPropType::parameters_type &parameters = *prop.recurrence_id()->parameters();
+            for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) {
+                if (dynamic_cast<const icalendar_2_0::RangeParamType*> (&*it)) {
+                    thisandfuture = true;
+                }
+            }
+        }
+        inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture);
+    }
+
+    if (prop.priority()) {
+        inc.setPriority(toInt(*prop.priority()));
+    }
+
+    if (prop.location()) {
+        inc.setLocation(toString(*prop.location()));
+    }
+    
+    if (prop.organizer()) {
+        std::string email;
+        std::string name;
+        setCalAddress(*prop.organizer(), email, name);
+        inc.setOrganizer(email, name);
+    }
+    
+}
+
+
 template <typename T, typename I>
 T fromList(const std::vector<int> &input) {
     T list;
@@ -1080,36 +1086,7 @@ void getIncidenceProperties(T &prop, const I &inc)
     if (inc.start().isValid()) {
         prop.dtstart(fromDate<typename properties::dtstart_type>(inc.start()));
     }
-    
-    if (inc.recurrenceRule().isValid()) {
-        const RecurrenceRule &r = inc.recurrenceRule();
-        prop.rrule(recurrenceProperty(r));
-        //TODO check if startdate is allDay if recurrence is allDay
-        //TODO check if startdate matches the one of the event (it MUST)
-    }
-    
-    if (!inc.recurrenceDates().empty()) {
-        prop.rdate(fromDateTimeList<typename properties::rdate_type>(inc.recurrenceDates()));
-    }
-    
-    if (!inc.exceptionDates().empty()) {
-        prop.exdate(fromDateTimeList<typename properties::exdate_type>(inc.exceptionDates()));
-    }
-    
-    if (inc.recurrenceID().isValid()) {
-        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<typename properties::recurrence_id_type>(inc.recurrenceID());
-        if (inc.thisAndFuture()) {
-            if (!recurrenceId->parameters()) {
-                recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
-            }
-            typename properties::recurrence_id_type::parameters_type &parameters = *recurrenceId->parameters(); //There is maybe already a timezone set
-            icalendar_2_0::RangeParamType range(THISANDFUTURE);
-            parameters.baseParameter().push_back(range);
-        }
-        
-        prop.recurrence_id(recurrenceId);
-    }
-    
+
     if (!inc.summary().empty()) {
         prop.summary(typename properties::summary_type(inc.summary()));
     }
@@ -1117,11 +1094,7 @@ void getIncidenceProperties(T &prop, const I &inc)
     if (!inc.description().empty()) {
         prop.description(typename properties::description_type(inc.description()));
     }
-    
-    if (inc.priority() != 0) {
-        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
-    }
-    
+
     if (inc.status() != UndefinedStatus) {
         switch (inc.status()) {
             case NeedsAction:
@@ -1153,22 +1126,7 @@ void getIncidenceProperties(T &prop, const I &inc)
         }
 
     }
-    
-    if (!inc.location().empty()) {
-        prop.location(typename properties::location_type(inc.location()));
-    }
-    
-    if (!inc.organizerEmail().empty()) { //email is required
-        typename properties::organizer_type organizer(inc.organizerEmail());
-        
-        typename properties::organizer_type::parameters_type p; //There is maybe already a timezone set
-        icalendar_2_0::CnParamType name(inc.organizerName());
-        p.baseParameter().push_back(name);
 
-        organizer.parameters(p);
-        prop.organizer(organizer);
-    }
-    
     if (!inc.attendees().empty()) {        
         
         BOOST_FOREACH(const Kolab::Attendee &a, inc.attendees()) {
@@ -1218,6 +1176,61 @@ void getIncidenceProperties(T &prop, const I &inc)
 
 }
 
+template <typename T, typename I>
+void getTodoEventProperties(T &prop, const I &inc)
+{
+    using namespace icalendar_2_0;
+    typedef T properties; 
+    
+    if (inc.recurrenceRule().isValid()) {
+        const RecurrenceRule &r = inc.recurrenceRule();
+        prop.rrule(recurrenceProperty(r));
+        //TODO check if startdate is allDay if recurrence is allDay
+        //TODO check if startdate matches the one of the event (it MUST)
+    }
+    
+    if (!inc.recurrenceDates().empty()) {
+        prop.rdate(fromDateTimeList<typename properties::rdate_type>(inc.recurrenceDates()));
+    }
+    
+    if (!inc.exceptionDates().empty()) {
+        prop.exdate(fromDateTimeList<typename properties::exdate_type>(inc.exceptionDates()));
+    }
+    
+    if (inc.recurrenceID().isValid()) {
+        std::auto_ptr<typename properties::recurrence_id_type> recurrenceId = fromDate<typename properties::recurrence_id_type>(inc.recurrenceID());
+        if (inc.thisAndFuture()) {
+            if (!recurrenceId->parameters()) {
+                recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type());
+            }
+            typename properties::recurrence_id_type::parameters_type &parameters = *recurrenceId->parameters(); //There is maybe already a timezone set
+            icalendar_2_0::RangeParamType range(THISANDFUTURE);
+            parameters.baseParameter().push_back(range);
+        }
+        
+        prop.recurrence_id(recurrenceId);
+    }
+    
+    if (inc.priority() != 0) {
+        prop.priority(typename properties::priority_type(fromInt<typename properties::priority_type::integer_type>(inc.priority())));
+    }
+    
+    if (!inc.location().empty()) {
+        prop.location(typename properties::location_type(inc.location()));
+    }
+    
+    if (!inc.organizerEmail().empty()) { //email is required
+        typename properties::organizer_type organizer(inc.organizerEmail());
+        
+        typename properties::organizer_type::parameters_type p; //There is maybe already a timezone set
+        icalendar_2_0::CnParamType name(inc.organizerName());
+        p.baseParameter().push_back(name);
+
+        organizer.parameters(p);
+        prop.organizer(organizer);
+    }
+}
+
 //=== Alarms ===
 
 template <typename KolabType, typename IncidenceType>
@@ -1401,9 +1414,17 @@ template < > struct IncidenceTrait <Kolab::Event>
 
     static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event)
     {
+        
+        typename KolabType::components_type eventComponents;
+        setAlarms<icalendar_2_0::KolabEvent, IncidenceType>(eventComponents, event);
+        if (!eventComponents.valarm().empty()) {
+            vevent.components(eventComponents);
+        }
+        
         icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
 
         getIncidenceProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
+        getTodoEventProperties<icalendar_2_0::KolabEvent::properties_type>(prop, event);
 
         if (event.end().isValid()) {
             prop.dtend(fromDate<icalendar_2_0::KolabEvent::properties_type::dtend_type>(event.end()));
@@ -1426,6 +1447,7 @@ template < > struct IncidenceTrait <Kolab::Event>
         const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties();
 
         setIncidenceProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
+        setTodoEventProperties<Kolab::Event, icalendar_2_0::KolabEvent::properties_type>(event, prop);
 
         if (prop.dtend()) {
             event.setEnd(*toDate(*prop.dtend()));
@@ -1452,12 +1474,7 @@ template < > struct IncidenceTrait <Kolab::Event>
             getAlarms<Kolab::Event, icalendar_2_0::KolabEvent>(event, *vevent.components());
         }
     }
-    
-    static void setComponents(icalendar_2_0::KolabEvent::components_type& components, const Kolab::Event &incidence)
-    {
-        setAlarms<icalendar_2_0::KolabEvent, Kolab::Event>(components, incidence);
-    }
-     
+
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
     {
         return components.vevent().begin();
@@ -1478,9 +1495,16 @@ template < > struct IncidenceTrait <Kolab::Todo>
 
     static void writeIncidence(icalendar_2_0::KolabTodo& vevent, const Kolab::Todo &todo)
     {
+        typename KolabType::components_type eventComponents;
+        setAlarms<icalendar_2_0::KolabTodo, IncidenceType>(eventComponents, todo);
+        if (!eventComponents.valarm().empty()) {
+            vevent.components(eventComponents);
+        }
+
         icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
-        
+
         getIncidenceProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
+        getTodoEventProperties<icalendar_2_0::KolabTodo::properties_type>(prop, todo);
 
         if (!todo.relatedTo().empty()) {
             icalendar_2_0::KolabTodo::properties_type::related_to_sequence list;
@@ -1507,6 +1531,7 @@ template < > struct IncidenceTrait <Kolab::Todo>
         const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties();
 
         setIncidenceProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
+        setTodoEventProperties<Kolab::Todo, icalendar_2_0::KolabTodo::properties_type>(todo, prop);
 
         if (!prop.related_to().empty()) {
             BOOST_FOREACH(icalendar_2_0::KolabTodo::properties_type::related_to_type p, prop.related_to()) {
@@ -1523,12 +1548,7 @@ template < > struct IncidenceTrait <Kolab::Todo>
             getAlarms<Kolab::Todo, icalendar_2_0::KolabTodo>(todo, *vevent.components());
         }
     }
-    
-    static void setComponents(icalendar_2_0::KolabTodo::components_type& components, const Kolab::Todo &incidence)
-    {
-        setAlarms<icalendar_2_0::KolabTodo, IncidenceType>(components, incidence);
-    }
-     
+
     static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
     {
         return components.vtodo().begin();
@@ -1541,6 +1561,41 @@ template < > struct IncidenceTrait <Kolab::Todo>
     
 };
 
+template < > struct IncidenceTrait <Kolab::Journal>
+{
+    typedef icalendar_2_0::KolabJournal KolabType;
+    typedef Kolab::Journal IncidenceType;
+    typedef boost::shared_ptr<Kolab::Journal> IncidencePtr;
+
+    static void writeIncidence(icalendar_2_0::KolabJournal& vjournal, const Kolab::Journal &journal)
+    {
+        icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
+        getIncidenceProperties<icalendar_2_0::KolabJournal::properties_type>(prop, journal);
+    }
+    
+    static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabJournal inc)
+    {
+        components.vjournal().push_back(inc);
+    }
+
+    static void readIncidence(Kolab::Journal &journal, const icalendar_2_0::KolabJournal& vjournal)
+    {
+        const icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties();
+        setIncidenceProperties<Kolab::Journal, icalendar_2_0::KolabJournal::properties_type>(journal, prop);
+    }
+
+    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vjournal().begin();
+    }
+    
+    static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components)
+    {
+        return components.vjournal().end();
+    }
+    
+};
+
 
 //////////////////////////////////=========================================
 
@@ -1556,9 +1611,6 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
 
     try {
 
-        typename KolabType::components_type eventComponents;
-        T::setComponents(eventComponents, incidence);
-
         typename KolabType::properties_type::uid_type uid(IC::uid(incidence));
         setCreatedUid(uid.text());
         typename KolabType::properties_type::dtstamp_type dtstamp;
@@ -1568,12 +1620,9 @@ std::string serializeIncidence(const typename T::IncidenceType &incidence, const
         typename KolabType::properties_type eventProps(uid, created, dtstamp);
         
         KolabType inc(eventProps);
-        if (!eventComponents.valarm().empty()) {
-            inc.components(eventComponents);
-        }
+        
         T::writeIncidence(inc, incidence);
 
-        
         VcalendarType::components_type components;
         T::addIncidence(components, inc);
         
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index d1fb65c..f7a55e4 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -18,6 +18,7 @@
 #include <fstream>
 #include "serializers.h"
 #include <lib/utils.h>
+#include <lib/kolabjournal.h>
 
 
 
@@ -228,6 +229,86 @@ void BindingsTest::todoCompletness()
     QCOMPARE(ev.percentComplete(), e.percentComplete());
 }
 
+void BindingsTest::journalCompletness()
+{
+    Kolab::Journal ev;
+    
+    
+    ev.setUid("UID");
+    ev.setCreated(Kolab::DateTime(2006,1,6,12,0,0)); //UTC
+    ev.setSequence(1);
+    ev.setClassification(Kolab::Confidential);
+    ev.addCategory("Category");
+    ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+    Kolab::Attendee attendee("email");
+    attendee.setName("name");
+    attendee.setPartStat(Kolab::PartDelegated);
+    attendee.setRole(Kolab::Chair);
+    attendee.setRSVP(true);
+    attendee.setUid("uid");
+    
+    ev.setAttendees(std::vector<Kolab::Attendee>() << attendee << attendee);
+    
+    std::vector<Kolab::Attachment> attachments;
+    
+    Kolab::Attachment attach;
+    attach.setData("data????*?*?*?*?*?", "mimetype");
+    attach.setLabel("label");
+    attachments.push_back(attach);
+    
+    Kolab::Attachment attach2;
+    attach2.setUri("../../tests/testfiles/icalEvent.xml", "mimetype");
+    attach2.setLabel("labe2l");
+    attachments.push_back(attach2);
+    
+    Kolab::Attachment attach3;
+    using namespace std;
+    ifstream file ("../../tests/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate);
+    if (file.is_open()) {
+        int size = file.tellg();
+        char *memblock = new char [size];
+        file.seekg (0, ios::beg);
+        file.read (memblock, size);
+        file.close();
+
+        attach3.setData(string(memblock, size), "mimetype");
+
+        delete[] memblock;
+    }
+    attach3.setLabel("labe3l");
+    attachments.push_back(attach3);
+    
+    ev.setAttachments(attachments);
+    std::vector<Kolab::CustomProperty> properties;
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    properties.push_back(Kolab::CustomProperty("ident", "value"));
+    ev.setCustomProperties(properties);
+    
+    
+    
+    std::string result = Kolab::writeJournal(ev);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    std::cout << result << endl;
+    Kolab::Journal re = Kolab::readJournal(result, false);
+    QVERIFY(Kolab::error() == Kolab::NoError);
+    
+    
+    QCOMPARE(ev.uid(), re.uid());
+    QCOMPARE(ev.created(), re.created());
+    QVERIFY(re.lastModified().isValid()); //TODO can we check this better?
+    QCOMPARE(ev.sequence(), re.sequence());
+    QCOMPARE(ev.classification(), re.classification());
+    QCOMPARE(ev.categories(), re.categories());
+    QCOMPARE(ev.start(), re.start());
+    QCOMPARE(ev.summary(), re.summary());
+    QCOMPARE(ev.description(), re.description());
+    QCOMPARE(ev.status(), re.status());
+    QCOMPARE(ev.attendees(), re.attendees());
+    QCOMPARE(ev.attachments(), re.attachments());
+    QCOMPARE(ev.customProperties(), re.customProperties());
+    
+}
+
 void BindingsTest::contactCompletness()
 {
     std::vector<std::string> stringlist;
@@ -303,7 +384,7 @@ void BindingsTest::contactCompletness()
     
     const std::string result = Kolab::writeContact(c);
     QVERIFY(Kolab::error() == Kolab::NoError);
-    std::cout << result << endl;
+    //std::cout << result << endl;
     Kolab::Contact e = Kolab::readContact(result, false);
     QVERIFY(Kolab::error() == Kolab::NoError);
     QCOMPARE(e.uid(), c.uid());
diff --git a/c++/tests/bindingstest.h b/c++/tests/bindingstest.h
index d5e86d3..7920b92 100644
--- a/c++/tests/bindingstest.h
+++ b/c++/tests/bindingstest.h
@@ -25,6 +25,7 @@ class BindingsTest : public QObject
     void eventCompletness();
     void eventDuration();
     void todoCompletness();
+    void journalCompletness();
     
     void contactCompletness();
     void distlistCompletness();
diff --git a/schemas/ical/kolabformat-xcal.xsd b/schemas/ical/kolabformat-xcal.xsd
index 5a5ec95..0a0e9fd 100644
--- a/schemas/ical/kolabformat-xcal.xsd
+++ b/schemas/ical/kolabformat-xcal.xsd
@@ -197,7 +197,7 @@
                     <xs:choice>
                         <xs:element name="vevent" type="KolabEvent" maxOccurs="unbounded"/>
                         <xs:element name="vtodo" type="KolabTodo" maxOccurs="unbounded"/>
-                        <xs:element name="vjournal" type="KolabJournal"/>
+                        <xs:element name="vjournal" type="KolabJournal" maxOccurs="unbounded"/>
                     </xs:choice>
                 </xs:complexType>
             </xs:element>





More information about the commits mailing list