[rygel] tracker: Extact base-class for metadata container



commit fb400ac19b42bcaa1e06445f452a98bf4d73dfac
Author: Jens Georg <mail jensge org>
Date:   Sat Jul 14 21:46:23 2012 +0200

    tracker: Extact base-class for metadata container
    
    Reduce redundancy introduced by previous commit.

 src/plugins/tracker/Makefile.am                    |    1 +
 .../tracker/rygel-tracker-metadata-container.vala  |  148 ++++++++++++++++++
 .../rygel-tracker-metadata-multivalues.vala        |  161 ++++---------------
 .../tracker/rygel-tracker-metadata-values.vala     |  148 ++++---------------
 4 files changed, 211 insertions(+), 247 deletions(-)
---
diff --git a/src/plugins/tracker/Makefile.am b/src/plugins/tracker/Makefile.am
index 446f7de..1f53720 100644
--- a/src/plugins/tracker/Makefile.am
+++ b/src/plugins/tracker/Makefile.am
@@ -13,6 +13,7 @@ librygel_tracker_la_SOURCES = \
 	rygel-tracker-videos.vala \
 	rygel-tracker-pictures.vala \
 	rygel-tracker-metadata-values.vala \
+	rygel-tracker-metadata-container.vala \
 	rygel-tracker-metadata-multivalues.vala \
 	rygel-tracker-tags.vala \
 	rygel-tracker-years.vala \
diff --git a/src/plugins/tracker/rygel-tracker-metadata-container.vala b/src/plugins/tracker/rygel-tracker-metadata-container.vala
new file mode 100644
index 0000000..f7df86e
--- /dev/null
+++ b/src/plugins/tracker/rygel-tracker-metadata-container.vala
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2008 Zeeshan Ali <zeenix gmail com>.
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali <zeenix gmail com>
+ *
+ * This file is part of Rygel.
+ *
+ * Rygel 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel 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, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+using GUPnP;
+using Gee;
+using Tracker;
+
+/**
+ * Base class for containers listing possible values of a particular Tracker
+ * metadata key.
+ */
+public abstract class Rygel.Tracker.MetadataContainer : Rygel.SimpleContainer {
+    /* class-wide constants */
+    private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
+    private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
+
+    protected ItemFactory item_factory;
+    private bool update_in_progress = false;
+
+    private string child_class;
+
+    private Sparql.Connection resources;
+    protected QueryTriplets triplets;
+
+    public MetadataContainer (string         id,
+                              MediaContainer parent,
+                              string         title,
+                              ItemFactory    item_factory,
+                              string?        child_class = null) {
+        base (id, parent, title);
+
+        this.item_factory = item_factory;
+        this.child_class = child_class;
+
+        try {
+            this.resources = Sparql.Connection.get ();
+        } catch (Error error) {
+            critical (_("Failed to create Tracker connection: %s"),
+                      error.message);
+
+            return;
+        }
+    }
+
+    internal async void fetch_metadata_values () {
+        if (this.update_in_progress) {
+            return;
+        }
+
+        this.update_in_progress = true;
+        // First thing, clear the existing hierarchy, if any
+        this.clear ();
+
+        var query = this.create_query ();
+
+        try {
+            yield query.execute (this.resources);
+
+            /* Iterate through all the values */
+            while (query.result.next ()) {
+                string value = query.result.get_string (0);
+
+                if (value == "") {
+                    continue;
+                }
+
+                var title = this.create_title_for_value (value);
+                if (title == null) {
+                    continue;
+                }
+
+                var id = this.create_id_for_title (title);
+                if (id == null || !this.is_child_id_unique (id)) {
+                    continue;
+                }
+
+                var container = this.create_container (id, title, value);
+
+                if (this.child_class != null) {
+                    container.upnp_class = child_class;
+                }
+
+                this.add_child_container (container);
+            }
+        } catch (Error error) {
+            critical (_("Error getting all values for '%s': %s"),
+                      this.id,
+                      error.message);
+            this.update_in_progress = false;
+
+            return;
+        }
+
+        this.updated ();
+        this.update_in_progress = false;
+    }
+
+    protected abstract SelectionQuery create_query ();
+    protected abstract SearchContainer create_container (string id,
+                                                         string title,
+                                                         string value);
+
+    public override async MediaObject? find_object (string       id,
+                                                    Cancellable? cancellable)
+                                                    throws GLib.Error {
+        if (this.is_our_child (id)) {
+            return yield base.find_object (id, cancellable);
+        } else {
+            return null;
+        }
+    }
+
+    protected virtual string? create_id_for_title (string title) {
+        return this.id + ":" + Uri.escape_string (title, "", true);
+    }
+
+    protected virtual string? create_title_for_value (string value) {
+        return value;
+    }
+
+    protected virtual string create_filter (string variable, string value) {
+        return variable + " = \"" + Query.escape_string (value) + "\"";
+    }
+
+    private bool is_our_child (string id) {
+        return id.has_prefix (this.id + ":");
+    }
+}
diff --git a/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala b/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala
index 0cd1ad3..1c8d2c0 100644
--- a/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala
+++ b/src/plugins/tracker/rygel-tracker-metadata-multivalues.vala
@@ -4,6 +4,7 @@
  *
  * Author: Zeeshan Ali <zeenix gmail com>
  *         Jens Georg <jensg openismus com>
+ *         Jens Georg <mail jensge org>
  *
  * This file is part of Rygel.
  *
@@ -24,71 +25,39 @@
 
 using GUPnP;
 using Gee;
-using Tracker;
 
 /**
  * Container listing possible values of a particuler Tracker metadata key.
+ * This class is used for multivalue properties such as nao:Tag (via
+ * nao:hasTag)
  */
-public abstract class Rygel.Tracker.MetadataMultiValues : Rygel.SimpleContainer {
-    /* class-wide constants */
-    private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
-    private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
-
-    private ItemFactory item_factory;
-    private bool update_in_progress = false;
-
-    // In tracker 0.7, we might don't get values of keys in place so you need a
-    // chain of keys to reach to final destination. For instances:
-    // nmm:Performer -> nmm:artistName
+public abstract class Rygel.Tracker.MetadataMultiValues : MetadataContainer {
     public string[] key_chain;
 
-    private string child_class;
-
-    private Sparql.Connection resources;
-
     public MetadataMultiValues (string         id,
                                 MediaContainer parent,
                                 string         title,
                                 ItemFactory    item_factory,
                                 string[]       key_chain,
                                 string?        child_class = null) {
-        base (id, parent, title);
+        base (id, parent, title, item_factory, child_class);
 
-        this.item_factory = item_factory;
         this.key_chain = key_chain;
-        this.child_class = child_class;
-
-        try {
-            this.resources = Sparql.Connection.get ();
-        } catch (Error error) {
-            critical (_("Failed to create Tracker connection: %s"), error.message);
-
-            return;
-        }
 
         this.fetch_metadata_values.begin ();
     }
 
-    internal async void fetch_metadata_values () {
-        if (this.update_in_progress) {
-            return;
-        }
-
-        this.update_in_progress = true;
-        // First thing, clear the existing hierarchy, if any
-        this.clear ();
+    protected override SelectionQuery create_query () {
+        this.triplets = new QueryTriplets ();
 
-        int i;
-        var triplets = new QueryTriplets ();
-
-        triplets.add (new QueryTriplet (SelectionQuery.ITEM_VARIABLE,
-                                        "a",
-                                        this.item_factory.category));
+        this.triplets.add (new QueryTriplet (SelectionQuery.ITEM_VARIABLE,
+                                             "a",
+                                             this.item_factory.category));
 
         // All variables used in the query
         var num_keys = this.key_chain.length - 1;
         var variables = new string[num_keys];
-        for (i = 0; i < num_keys; i++) {
+        for (int i = 0; i < num_keys; i++) {
             variables[i] = "?" + key_chain[i].replace (":", "_");
 
             string subject;
@@ -98,9 +67,9 @@ public abstract class Rygel.Tracker.MetadataMultiValues : Rygel.SimpleContainer
                 subject = variables[i - 1];
             }
 
-            triplets.add (new QueryTriplet (subject,
-                                            this.key_chain[i],
-                                            variables[i]));
+            this.triplets.add (new QueryTriplet (subject,
+                                                 this.key_chain[i],
+                                                 variables[i]));
         }
 
         // Variables to select from query
@@ -109,89 +78,27 @@ public abstract class Rygel.Tracker.MetadataMultiValues : Rygel.SimpleContainer
         var last_variable = variables[num_keys - 1];
         selected.add ("DISTINCT " + last_variable);
 
-        var query = new SelectionQuery (selected,
-                                        triplets,
-                                        null,
-                                        last_variable);
-
-        try {
-            yield query.execute (this.resources);
-
-            while (query.result.next ()) {
-                string value = query.result.get_string (0);
-
-                if (value == "") {
-                    continue;
-                }
-
-                var title = this.create_title_for_value (value);
-                if (title == null) {
-                    continue;
-                }
-
-                var id = this.create_id_for_title (title);
-                if (id == null || !this.is_child_id_unique (id)) {
-                    continue;
-                }
-
-                // The child container can use the same triplets we used in our
-                // query.
-                var child_triplets = new QueryTriplets.clone (triplets);
-
-                // However we constrain the object of our last triplet.
-                var filters = new ArrayList<string> ();
-                var filter = this.create_filter (child_triplets.last ().obj, value);
-                filters.add (filter);
-
-                var container = new SearchContainer (id,
-                                                     this,
-                                                     title,
-                                                     this.item_factory,
-                                                     child_triplets,
-                                                     filters);
-                if (this.child_class != null) {
-                    container.upnp_class = child_class;
-                }
-
-                this.add_child_container (container);
-            }
-        } catch (Error error) {
-            critical (_("Error getting all values for '%s': %s"),
-                      string.joinv (" -> ", this.key_chain),
-                      error.message);
-            this.update_in_progress = false;
-
-            return;
-        }
-
-
-        this.updated ();
-        this.update_in_progress = false;
-    }
-
-    public override async MediaObject? find_object (string       id,
-                                                    Cancellable? cancellable)
-                                                    throws GLib.Error {
-        if (this.is_our_child (id)) {
-            return yield base.find_object (id, cancellable);
-        } else {
-            return null;
-        }
-    }
-
-    protected virtual string? create_id_for_title (string title) {
-        return this.id + ":" + Uri.escape_string (title, "", true);
-    }
-
-    protected virtual string? create_title_for_value (string value) {
-        return value;
-    }
-
-    protected virtual string create_filter (string variable, string value) {
-        return variable + " = \"" + Query.escape_string (value) + "\"";
+        return new SelectionQuery (selected, triplets, null, last_variable);
     }
 
-    private bool is_our_child (string id) {
-        return id.has_prefix (this.id + ":");
+    protected override SearchContainer create_container (string id,
+                                                         string title,
+                                                         string value) {
+
+        // The child container can use the same triplets we used in our
+        // query.
+        var child_triplets = new QueryTriplets.clone (triplets);
+
+        // However we constrain the object of our last triplet.
+        var filters = new ArrayList<string> ();
+        var filter = this.create_filter (child_triplets.last ().obj, value);
+        filters.add (filter);
+
+        return new SearchContainer (id,
+                                    this,
+                                    title,
+                                    this.item_factory,
+                                    child_triplets,
+                                    filters);
     }
 }
diff --git a/src/plugins/tracker/rygel-tracker-metadata-values.vala b/src/plugins/tracker/rygel-tracker-metadata-values.vala
index b333be7..341fce6 100644
--- a/src/plugins/tracker/rygel-tracker-metadata-values.vala
+++ b/src/plugins/tracker/rygel-tracker-metadata-values.vala
@@ -28,151 +28,59 @@ using Tracker;
 
 /**
  * Container listing possible values of a particuler Tracker metadata key.
+ * The key needs to be single-valued.
  */
-public abstract class Rygel.Tracker.MetadataValues : Rygel.SimpleContainer {
-    /* class-wide constants */
-    private const string TRACKER_SERVICE = "org.freedesktop.Tracker1";
-    private const string RESOURCES_PATH = "/org/freedesktop/Tracker1/Resources";
-
-    private ItemFactory item_factory;
-    private bool update_in_progress = false;
-
+public abstract class Rygel.Tracker.MetadataValues : MetadataContainer {
     private string property;
 
-    private string child_class;
-
-    private Sparql.Connection resources;
-
     public MetadataValues (string         id,
                            MediaContainer parent,
                            string         title,
                            ItemFactory    item_factory,
                            string         property,
                            string?        child_class = null) {
-        base (id, parent, title);
+        base (id, parent, title, item_factory, child_class);
 
-        this.item_factory = item_factory;
         this.property = property;
-        this.child_class = child_class;
 
-        try {
-            this.resources = Sparql.Connection.get ();
-        } catch (Error error) {
-            critical (_("Failed to create Tracker connection: %s"), error.message);
-
-            return;
-        }
+        this.triplets = new QueryTriplets ();
 
+        this.triplets.add (new QueryTriplet (SelectionQuery.ITEM_VARIABLE,
+                                             "a",
+                                             this.item_factory.category));
         this.fetch_metadata_values.begin ();
     }
 
-    internal async void fetch_metadata_values () {
-        if (this.update_in_progress) {
-            return;
-        }
-
-        this.update_in_progress = true;
-        // First thing, clear the existing hierarchy, if any
-        this.clear ();
-
-        int i;
-        var triplets = new QueryTriplets ();
-
-        triplets.add (new QueryTriplet (SelectionQuery.ITEM_VARIABLE,
-                                        "a",
-                                        this.item_factory.category));
-
+    protected override SelectionQuery create_query () {
         var key_chain_map = KeyChainMap.get_key_chain_map ();
         var selected = new ArrayList<string> ();
         selected.add ("DISTINCT " +
                       key_chain_map.map_property (this.property) +
                       " AS x");
 
-        var query = new SelectionQuery (selected,
-                                        triplets,
-                                        null,
-                                        "?x");
-
-        try {
-            yield query.execute (this.resources);
-
-            while (query.result.next ()) {
-                string value = query.result.get_string (0);
-
-                if (value == "") {
-                    continue;
-                }
-
-                var title = this.create_title_for_value (value);
-                if (title == null) {
-                    continue;
-                }
-
-                var id = this.create_id_for_title (title);
-                if (id == null || !this.is_child_id_unique (id)) {
-                    continue;
-                }
-
-                // The child container can use the same triplets we used in our
-                // query.
-                var child_triplets = new QueryTriplets.clone (triplets);
-
-                // However we constrain the object of our last triplet.
-                var filters = new ArrayList<string> ();
-                var property = key_chain_map.map_property (this.property);
-                var filter = this.create_filter (property, value);
-                filters.add (filter);
-
-                var container = new SearchContainer (id,
-                                                     this,
-                                                     title,
-                                                     this.item_factory,
-                                                     child_triplets,
-                                                     filters);
-                if (this.child_class != null) {
-                    container.upnp_class = child_class;
-                }
-
-                this.add_child_container (container);
-            }
-        } catch (Error error) {
-            critical (_("Error getting all values for '%s': %s"),
-                      this.id,
-                      error.message);
-            this.update_in_progress = false;
-
-            return;
-        }
-
-
-        this.updated ();
-        this.update_in_progress = false;
-    }
-
-    public override async MediaObject? find_object (string       id,
-                                                    Cancellable? cancellable)
-                                                    throws GLib.Error {
-        if (this.is_our_child (id)) {
-            return yield base.find_object (id, cancellable);
-        } else {
-            return null;
-        }
-    }
-
-    protected virtual string? create_id_for_title (string title) {
-        return this.id + ":" + Uri.escape_string (title, "", true);
+        return new SelectionQuery (selected, triplets, null, "?x");
     }
 
-    protected virtual string? create_title_for_value (string value) {
-        return value;
-    }
+    protected override SearchContainer create_container (string id,
+                                                         string title,
+                                                         string value) {
+        // The child container can use the same triplets we used in our
+        // query.
+        var child_triplets = new QueryTriplets.clone (this.triplets);
 
-    protected virtual string create_filter (string variable, string value) {
-        return variable + " = \"" + Query.escape_string (value) + "\"";
-    }
-
-    private bool is_our_child (string id) {
-        return id.has_prefix (this.id + ":");
+        // However we constrain the object of our last triplet.
+        var filters = new ArrayList<string> ();
+        var key_chain_map = KeyChainMap.get_key_chain_map ();
+        var property = key_chain_map.map_property (this.property);
+        var filter = this.create_filter (property, value);
+        filters.add (filter);
+
+        return new SearchContainer (id,
+                                    this,
+                                    title,
+                                    this.item_factory,
+                                    child_triplets,
+                                    filters);
     }
 }
 



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