[rygel] Only modify the description file from DescriptionFile



commit c03cef824e7ae0163bf5a73833b52c8693ea8a4b
Author: Jussi Kukkonen <jussi kukkonen intel com>
Date:   Wed Jun 26 18:34:40 2013 +0300

    Only modify the description file from DescriptionFile
    
    RootDeviceFactory used to modify the description xml directly. This is
    not optimal as DescriptionFile now keeps the elements in the correct
    order.
    
    Move the icon element and service element creation code to
    DescriptionFile, start using DescriptionFile public methods to modify
    the description from RootDeviceFactory. Swap the order of ControlURL
    and EventSubURL elements to match the specification.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=702451

 src/librygel-core/rygel-description-file.vala    |  113 ++++++++++++-
 src/librygel-core/rygel-root-device-factory.vala |  194 +++++-----------------
 2 files changed, 147 insertions(+), 160 deletions(-)
---
diff --git a/src/librygel-core/rygel-description-file.vala b/src/librygel-core/rygel-description-file.vala
index a24411c..37978de 100644
--- a/src/librygel-core/rygel-description-file.vala
+++ b/src/librygel-core/rygel-description-file.vala
@@ -90,6 +90,17 @@ public class Rygel.DescriptionFile : Object {
     }
 
     /**
+     * Modify the model description.
+     *
+     * A longer user friendly description of the device.
+     *
+     * @param model_description is the new model description.
+     */
+    public void set_model_description (string model_description) {
+        this.set_device_element ("modelDescription", model_description);
+    }
+
+    /**
      * Modify the model name.
      *
      * Usually the name of the software implementing this device.
@@ -139,6 +150,34 @@ public class Rygel.DescriptionFile : Object {
     }
 
     /**
+     * Set the Unique Device Name of the device.
+     *
+     * Unique Device Name is the UUID of this particular device instance.
+     *
+     * @param udn is the Unique Device Name of the device.
+     */
+    public void set_udn (string udn) {
+        this.set_device_element ("UDN", udn);
+    }
+
+    /**
+     * Get the current UDN of the device.
+     *
+     * @return The currenly set UDN.
+     */
+    public string? get_udn () {
+        var element = Rygel.XMLUtils.get_element ((Xml.Node *) this.doc.doc,
+                                                  "root",
+                                                  "device",
+                                                  "UDN");
+        if (element == null) {
+            return null;
+        }
+
+        return element->get_content ();
+    }
+
+    /**
      * Set the DLNA caps of this root device and while taking the
      * capabilities of the plugin into account.
      *
@@ -202,6 +241,64 @@ public class Rygel.DescriptionFile : Object {
         }
     }
 
+    public void clear_service_list () {
+        this.remove_device_element ("serviceList");
+    }
+
+    public void add_service (string device_name, ResourceInfo resource_info) {
+        var list = Rygel.XMLUtils.get_element
+                                        ((Xml.Node *) this.doc.doc,
+                                         "root",
+                                         "device",
+                                         "serviceList");
+        if (list == null) {
+            list = this.set_device_element ("serviceList", null);
+        }
+
+        Xml.Node *service_node = list->new_child (null, "service");
+
+        service_node->new_child (null, "serviceType", resource_info.upnp_type);
+        service_node->new_child (null, "serviceId", resource_info.upnp_id);
+
+        /* Now the relative (to base URL) URLs*/
+        string url = "/" + resource_info.description_path;
+        service_node->new_child (null, "SCPDURL", url);
+
+        url = "/Control/" + device_name + "/" + resource_info.type.name ();
+        service_node->new_child (null, "controlURL", url);
+
+        url = "/Event/" + device_name + "/" + resource_info.type.name ();
+        service_node->new_child (null, "eventSubURL", url);
+    }
+
+    public void clear_icon_list () {
+        this.remove_device_element ("iconList");
+    }
+
+    public void add_icon (string   device_name,
+                          IconInfo icon_info,
+                          string   url) {
+        var list = Rygel.XMLUtils.get_element
+                                        ((Xml.Node *) this.doc.doc,
+                                         "root",
+                                         "device",
+                                         "iconList");
+        if (list == null) {
+            list = this.set_device_element ("iconList", null);
+        }
+
+        Xml.Node *icon_node = list->new_child (null, "icon");
+
+        string width = icon_info.width.to_string ();
+        string height = icon_info.height.to_string ();
+        string depth = icon_info.depth.to_string ();
+
+        icon_node->new_child (null, "mimetype", icon_info.mime_type);
+        icon_node->new_child (null, "width", width);
+        icon_node->new_child (null, "height", height);
+        icon_node->new_child (null, "depth", depth);
+        icon_node->new_child (null, "url", url);
+    }
 
     /**
      * Change the type of a service.
@@ -273,10 +370,12 @@ public class Rygel.DescriptionFile : Object {
      *
      * @param element below /root/device to be set.
      * @param new_value is the new content of that element.
+     *
+     * @returns the element that was modified (or created) or null
      */
-    private void set_device_element (string element,
-                                     string new_value,
-                                     string? ns = null) {
+    private Xml.Node* set_device_element (string element,
+                                          string? new_value,
+                                          string? ns = null) {
         var xml_element = Rygel.XMLUtils.get_element
                                         ((Xml.Node *) this.doc.doc,
                                          "root",
@@ -284,7 +383,7 @@ public class Rygel.DescriptionFile : Object {
                                          element);
         if (xml_element != null) {
             xml_element->set_content (new_value);
-            return;
+            return xml_element;
         }
 
         // Element not found: create it
@@ -312,7 +411,7 @@ public class Rygel.DescriptionFile : Object {
                                          "device",
                                          device_elements[index]);
                 if (sibling != null) {
-                    sibling->add_next_sibling (xml_element);
+                    xml_element = sibling->add_next_sibling (xml_element);
 
                     break;
                 }
@@ -322,10 +421,12 @@ public class Rygel.DescriptionFile : Object {
                 // Set as first child
                 sibling = device_element->first_element_child ();
                 if (sibling != null) {
-                    sibling->add_prev_sibling (xml_element);
+                    xml_element = sibling->add_prev_sibling (xml_element);
                 }
             }
         }
+
+        return xml_element;
     }
 
     /**
diff --git a/src/librygel-core/rygel-root-device-factory.vala 
b/src/librygel-core/rygel-root-device-factory.vala
index 99aa36d..fa9808f 100644
--- a/src/librygel-core/rygel-root-device-factory.vala
+++ b/src/librygel-core/rygel-root-device-factory.vala
@@ -93,149 +93,55 @@ public class Rygel.RootDeviceFactory : Object,
         var doc = this.get_latest_doc (desc_path, template_path);
 
         /* Modify description to include Plugin-specific stuff */
-        this.prepare_desc_for_plugin (doc, plugin);
 
         var file = new DescriptionFile.from_xml_document (doc);
-        file.set_dlna_caps (plugin.capabilities);
-        file.save (desc_path);
-
-        return doc;
-    }
-
-    private void prepare_desc_for_plugin (XMLDoc doc, Plugin plugin) {
-        Xml.Node *device_element;
 
-        device_element = XMLUtils.get_element ((Xml.Node *) doc.doc,
-                                               "root",
-                                               "device",
-                                               null);
-        if (device_element == null) {
-            warning (_("XML node '%s' not found."), "/root/device");
-
-            return;
-        }
-
-        /* First, set the Friendly name and UDN */
-        this.set_friendly_name_and_udn (device_element,
-                                        plugin.name,
-                                        plugin.title);
+        this.add_services_to_desc (file, plugin);
+        this.add_icons_to_desc (file, plugin);
 
+        file.set_friendly_name (this.get_friendly_name (plugin));
+        file.set_dlna_caps (plugin.capabilities);
         if (plugin.description != null) {
-            this.set_description (device_element, plugin.description);
+            file.set_model_description (plugin.description);
+        }
+        var udn = file.get_udn ();
+        if (udn == null || udn == "") {
+            file.set_udn (this.generate_random_udn ());
         }
 
-        /* Then list each icon */
-        this.add_icons_to_desc (device_element, plugin);
+        file.save (desc_path);
 
-        /* Then list each service */
-        this.add_services_to_desc (device_element, plugin);
+        return doc;
     }
 
-    /**
-     * Fills the description doc @doc with a friendly name, and UDN from gconf.
-     * If these keys are not present in gconf, they are set with default values.
-     */
-    private void set_friendly_name_and_udn (Xml.Node *device_element,
-                                            string    plugin_name,
-                                            string    plugin_title) {
-        /* friendlyName */
-        Xml.Node *element = XMLUtils.get_element (device_element,
-                                                  "friendlyName",
-                                                  null);
-        if (element == null) {
-            warning (_("XML node '%s' not found."),
-                       "/root/device/friendlyName");
-
-            return;
-        }
-
+    private string get_friendly_name (Plugin plugin) {
         string title;
         try {
-            title = this.config.get_title (plugin_name);
+            title = this.config.get_title (plugin.name);
         } catch (GLib.Error err) {
-            title = plugin_title;
+            title = plugin.title;
         }
 
         title = title.replace ("@REALNAME@", Environment.get_real_name ());
         title = title.replace ("@USERNAME@", Environment.get_user_name ());
         title = title.replace ("@HOSTNAME@", Environment.get_host_name ());
 
-        element->set_content (title);
-
-        /* UDN */
-        element = XMLUtils.get_element (device_element, "UDN");
-        if (element == null) {
-            warning (_("XML node '%s' not found."), "/root/device/UDN");
-
-            return;
-        }
-
-        var udn = element->get_content ();
-        if (udn == null || udn == "") {
-            udn = this.generate_random_udn ();
-
-            element->set_content (udn);
-        }
-    }
-
-    private void set_description (Xml.Node *device_element,
-                                  string    description) {
-        Xml.Node *element = XMLUtils.get_element (device_element,
-                                                  "modelDescription",
-                                                  null);
-        if (element == null) {
-            device_element->new_child (null, "modelDescription", description);
-        }
-
-        element->set_content (description);
+        return title;
     }
 
-    private void add_services_to_desc (Xml.Node *device_element,
-                                       Plugin    plugin) {
-        Xml.Node *service_list_node = XMLUtils.get_element (device_element,
-                                                            "serviceList",
-                                                            null);
-        if (service_list_node == null) {
-            warning (_("XML node '%s' not found."), "/root/device/serviceList");
-
-            return;
-        }
-
-        // Clear the existing service list first
-        service_list_node->set_content ("");
-
+    private void add_services_to_desc (DescriptionFile file,
+                                       Plugin plugin) {
+        file.clear_service_list ();
         foreach (ResourceInfo resource_info in plugin.resource_infos) {
             // FIXME: We only support plugable services for now
             if (resource_info.type.is_a (typeof (Service))) {
-                    this.add_service_to_desc (service_list_node,
-                                              plugin.name,
-                                              resource_info);
+                file.add_service (plugin.name, resource_info);
             }
         }
     }
 
-    private void add_service_to_desc (Xml.Node    *service_list_node,
-                                      string       plugin_name,
-                                      ResourceInfo resource_info) {
-        // Now create the service node
-        Xml.Node *service_node = service_list_node->new_child (null, "service");
-
-        service_node->new_child (null, "serviceType", resource_info.upnp_type);
-        service_node->new_child (null, "serviceId", resource_info.upnp_id);
-
-        /* Now the relative (to base URL) URLs*/
-        string url = "/" + resource_info.description_path;
-        service_node->new_child (null, "SCPDURL", url);
-
-        url = "/Event/" + plugin_name + "/" + resource_info.type.name ();
-        service_node->new_child (null, "eventSubURL", url);
-
-        url = "/Control/" + plugin_name + "/" + resource_info.type.name ();
-        service_node->new_child (null, "controlURL", url);
-    }
-
-    private void add_icons_to_desc (Xml.Node *device_element,
-                                    Plugin    plugin) {
+    private void add_icons_to_desc (DescriptionFile file,
+                                    Plugin plugin) {
         var icons = plugin.icon_infos;
 
         if (icons == null || icons.size == 0) {
@@ -245,51 +151,31 @@ public class Rygel.RootDeviceFactory : Object,
             icons = plugin.default_icons;
         }
 
-        Xml.Node *icon_list_node = XMLUtils.get_element (device_element,
-                                                         "iconList",
-                                                         null);
-        if (icon_list_node == null) {
-            icon_list_node = device_element->new_child (null, "iconList", null);
-        } else {
-            // Clear the existing icon list first
-            icon_list_node->set_content ("");
-        }
-
+        file.clear_icon_list ();
         foreach (var icon in icons) {
-            add_icon_to_desc (icon_list_node, icon, plugin);
+            var remote_path = this.get_icon_remote_path (icon, plugin);
+            if (icon.uri.has_prefix ("file://")) {
+                var local_path = icon.uri.substring (7);
+                this.context.host_path (local_path, remote_path);
+            }
+
+            file.add_icon (plugin.name, icon, remote_path);
         }
     }
 
-    private void add_icon_to_desc (Xml.Node *icon_list_node,
-                                   IconInfo  icon_info,
-                                   Plugin    plugin) {
-        // Create the service node
-        Xml.Node *icon_node = icon_list_node->new_child (null, "icon");
-
-        string width = icon_info.width.to_string ();
-        string height = icon_info.height.to_string ();
-        string depth = icon_info.depth.to_string ();
-
-        icon_node->new_child (null, "mimetype", icon_info.mime_type);
-        icon_node->new_child (null, "width", width);
-        icon_node->new_child (null, "height", height);
-        icon_node->new_child (null, "depth", depth);
-
-        var uri = icon_info.uri;
-
-        if (uri.has_prefix ("file://")) {
+    private string get_icon_remote_path (IconInfo icon_info,
+                                         Plugin plugin) {
+        if (icon_info.uri.has_prefix ("file://")) {
             // /PLUGIN_NAME-WIDTHxHEIGHTxDEPTH.png
-            var remote_path = "/" + plugin.name + "-" +
-                              width + "x" +
-                              height + "x" +
-                              depth + "." + icon_info.file_extension;
-            var local_path = uri.substring (7);
-
-            this.context.host_path (local_path, remote_path);
-            icon_node->new_child (null, "url", remote_path);
+            return "/" + plugin.name + "-" +
+                   icon_info.width.to_string () + "x" +
+                   icon_info.height.to_string () + "x" +
+                   icon_info.depth.to_string () + "." +
+                   icon_info.file_extension;
         } else {
-            uri = uri.replace ("@ADDRESS@", this.context.host_ip);
-            icon_node->new_child (null, "url", uri);
+            var uri = icon_info.uri;
+            uri.replace ("@ADDRESS@", this.context.host_ip);
+            return uri;
         }
     }
 


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