[folks] e-d-s: implement support for RoleDetails



commit 6d5040f72929231894e02632827ba9135552ef5b
Author: Raul Gutierrez Segales <rgs collabora co uk>
Date:   Sat Sep 3 18:28:09 2011 +0100

    e-d-s: implement support for RoleDetails
    
    Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=657969

 NEWS                                     |    1 +
 backends/eds/lib/edsf-persona-store.vala |  135 +++++++++++++++++++++++++++
 backends/eds/lib/edsf-persona.vala       |  146 ++++++++++++++++++++++++++++++
 3 files changed, 282 insertions(+), 0 deletions(-)
---
diff --git a/NEWS b/NEWS
index 9479500..5cf7dfa 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,7 @@ Bugs fixed:
 * Bug 657971 â Need BirthdayDetails support in eds backend
 * Bug 657789 â Don't claim uneditable eds fields as writable
 * Bug 657282 â Add an IndividualAggregator.individuals_changed_detailed signal
+* Bug 657969 â Support RoleDetails in eds backend
 
 API changes:
 * Add PersonaStore:always-writeable-properties property
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 6e187bd..b046b5f 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -244,6 +244,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
    * - PersonaStore.detail_key (PersonaDetail.IM_ADDRESSES)
    * - PersonaStore.detail_key (PersonaDetail.PHONE_NUMBERS)
    * - PersonaStore.detail_key (PersonaDetail.POSTAL_ADDRESSES)
+   * - PersonaStore.detail_key (PersonaDetail.ROLES)
    * - PersonaStore.detail_key (PersonaDetail.STRUCTURED_NAME)
    * - PersonaStore.detail_key (PersonaDetail.LOCAL_IDS)
    * - PersonaStore.detail_key (PersonaDetail.WEB_SERVICE_ADDRESSES)
@@ -353,6 +354,12 @@ public class Edsf.PersonaStore : Folks.PersonaStore
               var birthday = (DateTime?) v.get_boxed ();
               yield this._set_contact_birthday (contact, birthday);
             }
+          else if (k == Folks.PersonaStore.detail_key (PersonaDetail.ROLES))
+            {
+              Set<RoleFieldDetails> roles =
+                (Set<RoleFieldDetails>) v.get_object ();
+              yield this._set_contact_roles (contact, roles);
+            }
         }
 
       Edsf.Persona? persona = null;
@@ -1362,6 +1369,101 @@ public class Edsf.PersonaStore : Folks.PersonaStore
       contact.set (E.Contact.field_id ("birth_date"), contact_bday);
     }
 
+  internal async void _set_roles (Edsf.Persona persona,
+      Set<RoleFieldDetails> roles) throws PropertyError
+    {
+      if (Edsf.PersonaStore.equal_sets (roles, persona.roles))
+        return;
+
+      yield this._set_contact_roles (persona.contact, roles);
+      yield this._commit_modified_property (persona, "roles");
+    }
+
+  private async void _set_contact_roles (E.Contact contact,
+      Set<RoleFieldDetails> roles)
+    {
+      var vcard = (E.VCard) contact;
+      vcard.remove_attributes (null, "X-ROLES");
+
+      string? org = null;
+      string? org_unit = null;
+      string? office = null;
+      string? title = null;
+      string? role = null;
+      string? manager = null;
+      string? assistant = null;
+
+      /* Because e-d-s supports only fields for one Role we save the
+       * first in the Set to the fields available and the rest goes
+       * to X-ROLES */
+      int count = 0;
+      foreach (var role_fd in roles)
+        {
+          if (count == 0)
+            {
+              org = role_fd.value.organisation_name;
+              title = role_fd.value.title;
+              role = role_fd.value.role;
+
+              /* FIXME: we are swallowing the extra parameter values */
+              var org_unit_values = role_fd.get_parameter_values ("org_unit");
+              if (org_unit_values != null &&
+                  org_unit_values.size > 0)
+                org_unit = org_unit_values.to_array ()[0];
+
+              var office_values = role_fd.get_parameter_values ("office");
+              if (office_values != null &&
+                  office_values.size > 0)
+                office = office_values.to_array ()[0];
+
+              var manager_values = role_fd.get_parameter_values ("manager");
+              if (manager_values != null &&
+                  manager_values.size > 0)
+                manager = manager_values.to_array ()[0];
+
+              var assistant_values = role_fd.get_parameter_values ("assistant");
+              if (assistant_values != null &&
+                  assistant_values.size > 0)
+                assistant = assistant_values.to_array ()[0];
+            }
+          else
+            {
+              var attr = new E.VCardAttribute (null, "X-ROLES");
+              attr.add_value (role_fd.value.role);
+
+              var param1 = new E.VCardAttributeParam ("organisation_name");
+              param1.add_value (role_fd.value.organisation_name);
+              attr.add_param (param1);
+
+              var param2 = new E.VCardAttributeParam ("title");
+              param2.add_value (role_fd.value.title);
+              attr.add_param (param2);
+
+              foreach (var param_name in role_fd.parameters.get_keys ())
+                {
+                  var param3 = new E.VCardAttributeParam (param_name.up ());
+                  foreach (var param_val in role_fd.parameters.get (param_name))
+                    {
+                      param3.add_value (param_val);
+                    }
+                  attr.add_param (param3);
+                }
+
+              contact.add_attribute ((owned) attr);
+            }
+
+          count++;
+        }
+
+      contact.set (E.Contact.field_id ("org"), org);
+      contact.set (E.Contact.field_id ("org_unit"), org_unit);
+      contact.set (E.Contact.field_id ("office"), office);
+      contact.set (E.Contact.field_id ("title"), title);
+      contact.set (E.Contact.field_id ("role"), role);
+      contact.set (E.Contact.field_id ("manager"), manager);
+      contact.set (E.Contact.field_id ("assistant"), assistant);
+    }
+
   internal async void _set_structured_name (Edsf.Persona persona,
       StructuredName? sname) throws PropertyError
     {
@@ -1643,4 +1745,37 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           _("Unknown error setting property â%sâ: %s"), property_name,
           error_in.message);
     }
+
+  internal static bool equal_sets (Set<RoleFieldDetails> a,
+      Set<RoleFieldDetails> b)
+    {
+      /* For the love of Dijkstra, there should be a more
+       * succint way of comparing Sets */
+
+      if (a.size == 0 &&
+          b.size == 0)
+        return true;
+
+      if (a.size != b.size)
+        return false;
+
+      bool same = false;
+      foreach (var new_role in a)
+        {
+          same = false;
+          foreach (var cur_role in b)
+            {
+              if (cur_role.equal (new_role))
+                {
+                  same = true;
+                  break;
+                }
+            }
+
+          if (!same)
+            return false;
+        }
+
+      return true;
+    }
 }
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index 4bf796b..889f70b 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -40,6 +40,7 @@ public class Edsf.Persona : Folks.Persona,
     NameDetails,
     NoteDetails,
     PhoneDetails,
+    RoleDetails,
     UrlDetails,
     PostalAddressDetails,
     WebServiceDetails
@@ -572,6 +573,32 @@ public class Edsf.Persona : Folks.Persona,
           bday);
     }
 
+  private HashSet<RoleFieldDetails> _roles;
+  private Set<RoleFieldDetails> _roles_ro;
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  [CCode (notify = false)]
+  public Set<RoleFieldDetails> roles
+    {
+      get { return this._roles_ro; }
+      set { this.change_roles.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_roles (Set<RoleFieldDetails> roles)
+      throws PropertyError
+    {
+      yield ((Edsf.PersonaStore) this.store)._set_roles (this, roles);
+    }
+
   /**
    * Build a IID.
    *
@@ -662,6 +689,10 @@ public class Edsf.Persona : Folks.Persona,
             (GLib.EqualFunc) WebServiceFieldDetails.equal);
       this._groups = new HashSet<string> ();
       this._groups_ro = this._groups.read_only_view;
+      this._roles = new HashSet<RoleFieldDetails> (
+          (GLib.HashFunc) RoleFieldDetails.hash,
+          (GLib.EqualFunc) RoleFieldDetails.equal);
+      this._roles_ro = this._roles.read_only_view;
 
       this._update (contact);
     }
@@ -738,6 +769,7 @@ public class Edsf.Persona : Folks.Persona,
       this._update_web_services_addresses ();
       this._update_gender ();
       this._update_birthday ();
+      this._update_roles ();
     }
 
   private void _update_params (AbstractFieldDetails details,
@@ -809,6 +841,120 @@ public class Edsf.Persona : Folks.Persona,
         }
     }
 
+  private void _update_roles ()
+    {
+      var new_roles = new HashSet<RoleFieldDetails> (
+          (GLib.HashFunc) RoleFieldDetails.hash,
+          (GLib.EqualFunc) RoleFieldDetails.equal);
+
+      var default_role_fd = this._get_default_role ();
+      if (default_role_fd != null)
+        {
+          new_roles.add (default_role_fd);
+        }
+
+      var vcard = (E.VCard) this.contact;
+      foreach (unowned E.VCardAttribute attr in vcard.get_attributes ())
+        {
+          if (attr.get_name () != "X-ROLES")
+            continue;
+
+          var role = new Role ("", "");
+          role.role = attr.get_value ();
+          var role_fd = new RoleFieldDetails (role);
+
+          foreach (unowned E.VCardAttributeParam param in
+              attr.get_params ())
+            {
+              string param_name = param.get_name ().down ();
+
+              if (param_name == "organisation_name")
+                {
+                  foreach (unowned string param_value in
+                      param.get_values ())
+                    {
+                      role.organisation_name = param_value;
+                      break;
+                    }
+                }
+              else if (param_name == "title")
+                {
+                  foreach (unowned string param_value in
+                      param.get_values ())
+                    {
+                      role.title = param_value;
+                      break;
+                    }
+                }
+              else
+                {
+                  foreach (unowned string param_value in
+                      param.get_values ())
+                    {
+                      role_fd.add_parameter (param_name, param_value);
+                    }
+                }
+            }
+
+            new_roles.add (role_fd);
+        }
+
+        if (new_roles.size > 0 &&
+            !Edsf.PersonaStore.equal_sets (new_roles, this._roles))
+          {
+            this._roles = new_roles;
+            this._roles_ro = new_roles.read_only_view;
+            this.notify_property ("roles");
+          }
+        else if (new_roles.size == 0)
+          {
+            this._roles.clear ();
+            this.notify_property ("roles");
+          }
+    }
+
+  private RoleFieldDetails? _get_default_role ()
+    {
+      RoleFieldDetails? default_role = null;
+
+      var org = (string?) this._get_property ("org");
+      var org_unit = (string?) this._get_property ("org_unit");
+      var office = (string?) this._get_property ("office");
+      var title = (string?) this._get_property ("title");
+      var role = (string?) this._get_property ("role");
+      var manager = (string?) this._get_property ("manager");
+      var assistant = (string?) this._get_property ("assistant");
+
+      if (org != null ||
+          org_unit != null ||
+          office != null ||
+          title != null ||
+          role != null ||
+          manager != null ||
+          assistant != null)
+        {
+          var new_role = new Role (title, org);
+          if (role != null)
+            new_role.role = role;
+
+          default_role = new RoleFieldDetails (new_role);
+
+          if (org_unit != null)
+            default_role.set_parameter ("org_unit", org_unit);
+
+          if (office != null)
+            default_role.set_parameter ("office", office);
+
+          if (manager != null)
+            default_role.set_parameter ("manager", manager);
+
+          if (assistant != null)
+            default_role.set_parameter ("assistant", assistant);
+        }
+
+      return default_role;
+    }
+
   private void _update_web_services_addresses ()
     {
       this._web_service_addresses.clear ();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]