Commit 846c3e1c authored by Sam Thursfield's avatar Sam Thursfield

Merge branch 'sam/fix-domainontology-gtype-conflict' into 'master'

Replace TrackerDomainOntology class with a simpler function

Closes tracker#116

See merge request GNOME/tracker-miners!89
parents 323aa7e3 ef6261a0
......@@ -21,48 +21,9 @@
#include "config-miners.h"
#include <string.h>
#include <gio/gio.h>
#include "tracker-domain-ontology.h"
typedef struct {
/* DomainOntologies section */
GFile *cache_location;
GFile *journal_location;
GFile *ontology_location;
gchar *name;
gchar *domain;
gchar *ontology_name;
gchar **miners;
} TrackerDomainOntologyPrivate;
enum {
PROP_0,
PROP_NAME
};
struct {
const gchar *var;
const gchar *(*func) (void);
} lookup_dirs[] = {
{ "HOME", g_get_home_dir },
{ "XDG_CACHE_HOME", g_get_user_cache_dir },
{ "XDG_DATA_HOME", g_get_user_data_dir },
{ "XDG_RUNTIME_DIR", g_get_user_runtime_dir },
};
struct {
const gchar *var;
GUserDirectory user_directory;
} lookup_special_dirs[] = {
{ "XDG_DESKTOP_DIR", G_USER_DIRECTORY_DESKTOP },
{ "XDG_DOCUMENTS_DIR", G_USER_DIRECTORY_DOCUMENTS },
{ "XDG_DOWNLOAD_DIR", G_USER_DIRECTORY_DOWNLOAD },
{ "XDG_MUSIC_DIR", G_USER_DIRECTORY_MUSIC },
{ "XDG_PICTURES_DIR", G_USER_DIRECTORY_PICTURES },
{ "XDG_PUBLICSHARE_DIR", G_USER_DIRECTORY_PUBLIC_SHARE },
{ "XDG_VIDEOS_DIR", G_USER_DIRECTORY_VIDEOS },
};
#define DOMAIN_ONTOLOGY_SECTION "DomainOntology"
#define CACHE_KEY "CacheLocation"
......@@ -74,194 +35,6 @@ struct {
#define DEFAULT_RULE "default.rule"
static void tracker_domain_ontology_initable_iface_init (GInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (TrackerDomainOntology, tracker_domain_ontology, G_TYPE_OBJECT,
G_ADD_PRIVATE (TrackerDomainOntology)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_domain_ontology_initable_iface_init))
static void
tracker_domain_ontology_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
switch (prop_id) {
case PROP_NAME:
priv->name = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
tracker_domain_ontology_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, priv->name);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
tracker_domain_ontology_finalize (GObject *object)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
g_clear_object (&priv->cache_location);
g_clear_object (&priv->journal_location);
g_clear_object (&priv->ontology_location);
g_free (priv->ontology_name);
g_free (priv->name);
g_free (priv->domain);
g_strfreev (priv->miners);
G_OBJECT_CLASS (tracker_domain_ontology_parent_class)->finalize (object);
}
static void
tracker_domain_ontology_class_init (TrackerDomainOntologyClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = tracker_domain_ontology_set_property;
object_class->get_property = tracker_domain_ontology_get_property;
object_class->finalize = tracker_domain_ontology_finalize;
g_object_class_install_property (object_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"Name",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
tracker_domain_ontology_init (TrackerDomainOntology *domain_ontology)
{
}
static const gchar *
lookup_dir (const gchar *variable,
gsize variable_len)
{
gint i;
for (i = 0; i < G_N_ELEMENTS (lookup_dirs); i++) {
if (strncmp (lookup_dirs[i].var, variable, variable_len) == 0) {
return lookup_dirs[i].func ();
}
}
for (i = 0; i < G_N_ELEMENTS (lookup_special_dirs); i++) {
if (strncmp (lookup_special_dirs[i].var, variable, variable_len) == 0) {
return g_get_user_special_dir (lookup_special_dirs[i].user_directory);
}
}
return NULL;
}
static GFile *
key_file_get_location (GKeyFile *key_file,
const gchar *section,
const gchar *key,
gboolean essential,
gboolean must_exist,
GError **error)
{
GError *inner_error = NULL;
gchar *value;
GFile *file;
value = g_key_file_get_string (key_file, section, key, &inner_error);
if (inner_error) {
if (essential)
g_propagate_error (error, inner_error);
else
g_error_free (inner_error);
return NULL;
}
if (value[0] == '$') {
const gchar *var_end, *prefix;
gchar *path;
/* This is a path relative from a xdg dir */
var_end = strchr (value, '/');
if (!var_end) {
/* We must take $VAR/subdir values */
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Path in key '%s' can not consist solely of a variable",
key);
g_free (value);
return NULL;
}
prefix = lookup_dir (&value[1], (var_end - &value[1]));
if (!prefix) {
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Unrecognized variable in '%s'", key);
g_free (value);
return NULL;
}
path = g_strconcat (prefix, var_end, NULL);
file = g_file_new_for_path (path);
g_free (path);
} else {
file = g_file_new_for_uri (value);
}
g_free (value);
if (must_exist && file &&
g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL) != G_FILE_TYPE_DIRECTORY) {
gchar *uri = g_file_get_uri (file);
g_set_error (error,
G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"Uri '%s' is not a directory or does not exist", uri);
g_free (uri);
return NULL;
}
return file;
}
static gchar *
find_rule_in_data_dirs (const gchar *name)
{
......@@ -289,38 +62,33 @@ find_rule_in_data_dirs (const gchar *name)
return NULL;
}
static gboolean
tracker_domain_ontology_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
gboolean
tracker_load_domain_config (const gchar *name,
gchar **dbus_domain_name,
GError **error)
{
TrackerDomainOntology *domain_ontology;
TrackerDomainOntologyPrivate *priv;
GError *inner_error = NULL;
GKeyFile *key_file = NULL;
GKeyFile *key_file;
gchar *path, *path_for_tests;
GError *inner_error = NULL;
domain_ontology = TRACKER_DOMAIN_ONTOLOGY (initable);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (priv->name && priv->name[0] == '/') {
if (!g_file_test (priv->name, G_FILE_TEST_IS_REGULAR)) {
if (name && name[0] == '/') {
if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_NOT_FOUND,
"Could not find rule at '%s'",
priv->name);
name);
goto end;
}
path = g_strdup (priv->name);
} else if (priv->name) {
path = find_rule_in_data_dirs (priv->name);
path = g_strdup (name);
} else if (name) {
path = find_rule_in_data_dirs (name);
if (!path) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_NOT_FOUND,
"Could not find rule '%s' in data dirs",
priv->name);
name);
goto end;
}
} else {
......@@ -351,60 +119,11 @@ tracker_domain_ontology_initable_init (GInitable *initable,
if (inner_error)
goto end;
priv->domain = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
DOMAIN_KEY, &inner_error);
if (inner_error)
goto end;
priv->cache_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
CACHE_KEY, TRUE, FALSE, &inner_error);
if (inner_error)
goto end;
priv->journal_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
JOURNAL_KEY, FALSE, FALSE, &inner_error);
if (inner_error)
goto end;
priv->ontology_location =
key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
ONTOLOGY_KEY, FALSE, TRUE, &inner_error);
*dbus_domain_name = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
DOMAIN_KEY, &inner_error);
if (inner_error)
goto end;
priv->ontology_name = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
ONTOLOGY_NAME_KEY, NULL);
priv->miners = g_key_file_get_string_list (key_file, DOMAIN_ONTOLOGY_SECTION,
MINERS_KEY, NULL, NULL);
/* Consistency check, we need one of OntologyLocation and OntologyName,
* no more, no less.
*/
if ((priv->ontology_name && priv->ontology_location) ||
(!priv->ontology_name && !priv->ontology_location)) {
inner_error = g_error_new (G_KEY_FILE_ERROR,
G_KEY_FILE_ERROR_INVALID_VALUE,
"One of OntologyLocation and OntologyName must be provided");
}
/* Build ontology location from name if necessary */
if (!priv->ontology_location) {
gchar *ontology_path;
ontology_path = g_build_filename (SHAREDIR, "tracker", "ontologies",
priv->ontology_name, NULL);
if (!g_file_test (ontology_path, G_FILE_TEST_IS_DIR)) {
g_free (ontology_path);
ontology_path = g_strdup (g_getenv ("TRACKER_DB_ONTOLOGIES_DIR"));
}
priv->ontology_location = g_file_new_for_path (ontology_path);
g_free (ontology_path);
}
end:
if (key_file)
g_key_file_free (key_file);
......@@ -416,83 +135,3 @@ end:
return TRUE;
}
static void
tracker_domain_ontology_initable_iface_init (GInitableIface *iface)
{
iface->init = tracker_domain_ontology_initable_init;
}
TrackerDomainOntology *
tracker_domain_ontology_new (const gchar *domain_name,
GCancellable *cancellable,
GError **error)
{
return g_initable_new (TRACKER_TYPE_DOMAIN_ONTOLOGY,
cancellable, error,
"name", domain_name,
NULL);
}
GFile *
tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->cache_location;
}
GFile *
tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->journal_location;
}
GFile *
tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
return priv->ontology_location;
}
gchar *
tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
const gchar *suffix)
{
TrackerDomainOntologyPrivate *priv;
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (suffix)
return g_strconcat (priv->domain, ".", suffix, NULL);
else
return g_strconcat (priv->domain, NULL);
}
gboolean
tracker_domain_ontology_uses_miner (TrackerDomainOntology *domain_ontology,
const gchar *suffix)
{
TrackerDomainOntologyPrivate *priv;
guint i;
g_return_val_if_fail (suffix != NULL, FALSE);
priv = tracker_domain_ontology_get_instance_private (domain_ontology);
if (!priv->miners)
return FALSE;
for (i = 0; priv->miners[i] != NULL; i++) {
if (strcmp (priv->miners[i], suffix) == 0) {
return TRUE;
}
}
return FALSE;
}
......@@ -27,43 +27,7 @@
#endif
#include <glib-object.h>
#include <gio/gio.h>
#define TRACKER_TYPE_DOMAIN_ONTOLOGY (tracker_domain_ontology_get_type())
#define TRACKER_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntology))
#define TRACKER_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
#define TRACKER_IS_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY))
#define TRACKER_IS_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY))
#define TRACKER_DOMAIN_ONTOLOGY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
gboolean tracker_load_domain_config (const gchar *name, gchar **dbus_domain_name, GError **error);
typedef struct _TrackerDomainOntology TrackerDomainOntology;
typedef struct _TrackerDomainOntologyClass TrackerDomainOntologyClass;
struct _TrackerDomainOntology {
GObject parent_instance;
};
struct _TrackerDomainOntologyClass {
GObjectClass parent_class;
/*<private>*/
gpointer padding[10];
};
GType tracker_domain_ontology_get_type (void) G_GNUC_CONST;
TrackerDomainOntology * tracker_domain_ontology_new (const gchar *name,
GCancellable *cancellable,
GError **error);
GFile * tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology);
GFile * tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology);
GFile * tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology);
gchar * tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
const gchar *suffix);
gboolean tracker_domain_ontology_uses_miner (TrackerDomainOntology *domain_ontology,
const gchar *suffix);
#endif /* __TRACKER_MINER_PROXY_H__ */
#endif /* __TRACKER_DOMAIN_ONTOLOGY_H__ */
......@@ -773,8 +773,7 @@ main (gint argc, gchar *argv[])
gboolean store_available;
TrackerMinerProxy *proxy;
GDBusConnection *connection;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
gchar *dbus_domain_name, *dbus_name;
main_loop = NULL;
......@@ -814,8 +813,9 @@ main (gint argc, gchar *argv[])
tracker_sparql_connection_set_domain (domain_ontology_name);
domain_ontology = tracker_domain_ontology_new (domain_ontology_name, NULL, &error);
if (error) {
tracker_load_domain_config (domain_ontology_name, &dbus_domain_name, &error);
if (error != NULL) {
g_critical ("Could not load domain ontology '%s': %s",
domain_ontology_name, error->message);
g_error_free (error);
......@@ -856,18 +856,16 @@ main (gint argc, gchar *argv[])
main_loop = g_main_loop_new (NULL, FALSE);
if (domain_ontology && domain_ontology_name) {
if (domain_ontology_name) {
/* If we are running for a specific domain, we tie the lifetime of this
* process to the domain. For example, if the domain name is
* org.example.MyApp then this tracker-miner-fs process will exit as
* soon as org.example.MyApp exits.
*/
domain_name = tracker_domain_ontology_get_domain (domain_ontology, NULL);
g_bus_watch_name_on_connection (connection, domain_name,
g_bus_watch_name_on_connection (connection, dbus_domain_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL, on_domain_vanished,
main_loop, NULL);
g_free (domain_name);
}
g_message ("Checking if we're running as a daemon:");
......@@ -922,7 +920,7 @@ main (gint argc, gchar *argv[])
}
/* Request DBus name */
dbus_name = tracker_domain_ontology_get_domain (domain_ontology, DBUS_NAME_SUFFIX);
dbus_name = g_strconcat (dbus_domain_name, ".", DBUS_NAME_SUFFIX, NULL);
if (!tracker_dbus_request_name (connection, dbus_name, &error)) {
g_critical ("Could not request DBus name '%s': %s",
......@@ -996,7 +994,8 @@ main (gint argc, gchar *argv[])
g_object_unref (proxy);
g_object_unref (connection);
g_object_unref (domain_ontology);
g_free (dbus_domain_name);
tracker_writeback_shutdown ();
tracker_log_shutdown ();
......
......@@ -78,8 +78,7 @@ main (int argc, char **argv)
GError *error = NULL;
GDBusConnection *connection;
TrackerMinerProxy *proxy;
TrackerDomainOntology *domain_ontology;
gchar *domain_name, *dbus_name;
gchar *dbus_domain_name, *dbus_name;
setlocale (LC_ALL, "");
......@@ -172,7 +171,8 @@ main (int argc, char **argv)
g_free (log_filename);
}
domain_ontology = tracker_domain_ontology_new (domain_ontology_name, NULL, &error);
tracker_load_domain_config (domain_ontology_name, &dbus_domain_name, &error);
if (error) {
g_critical ("Could not load domain ontology '%s': %s",
domain_ontology_name, error->message);
......@@ -203,7 +203,7 @@ main (int argc, char **argv)
return EXIT_FAILURE;
}
dbus_name = tracker_domain_ontology_get_domain (domain_ontology, DBUS_NAME_SUFFIX);
dbus_name = g_strconcat (dbus_domain_name, ".", DBUS_NAME_SUFFIX, NULL);
if (!tracker_dbus_request_name (connection, dbus_name, &error)) {
g_critical ("Could not request DBus name '%s': %s",
......@@ -217,18 +217,16 @@ main (int argc, char **argv)
loop = g_main_loop_new (NULL, FALSE);
if (domain_ontology && domain_ontology_name) {
if (domain_ontology_name) {
/* If we are running for a specific domain, we tie the lifetime of this
* process to the domain. For example, if the domain name is
* org.example.MyApp then this tracker-miner-rss process will exit as
* soon as org.example.MyApp exits.
*/
domain_name = tracker_domain_ontology_get_domain (domain_ontology, NULL);
g_bus_watch_name_on_connection (connection, domain_name,
g_bus_watch_name_on_connection (connection, dbus_domain_name,
G_BUS_NAME_WATCHER_FLAGS_NONE,
NULL, on_domain_vanished,
loop, NULL);
g_free (domain_name);
}
g_main_loop_run (loop);
......@@ -238,7 +236,7 @@ main (int argc, char **argv)
g_object_unref (miner);
g_object_unref (connection);
g_object_unref (proxy);
g_object_unref (domain_ontology);
g_free (dbus_domain_name);
return EXIT_SUCCESS;
}
......@@ -246,8 +246,7 @@ tracker_miner_rss_init (TrackerMinerRSS *object)
{
GError *error = NULL;
TrackerMinerRSSPrivate *priv;
TrackerDomainOntology *domain_ontology;
gchar *dbus_name;
gchar *dbus_domain_name;
g_message ("Initializing...");
......@@ -278,13 +277,11 @@ tracker_miner_rss_init (TrackerMinerRSS *object)
g_message ("Listening for GraphUpdated changes on D-Bus interface...");
g_message (" arg0:'%s'", TRACKER_PREFIX_MFO "FeedChannel");
domain_ontology = tracker_domain_ontology_new (tracker_sparql_connection_get_domain (),
NULL, NULL);
dbus_name = tracker_domain_ontology_get_domain (domain_ontology, NULL);
tracker_load_domain_config (tracker_sparql_connection_get_domain (), &dbus_domain_name, &error);
priv->graph_updated_id =
g_dbus_connection_signal_subscribe (priv->connection,
dbus_name,
dbus_domain_name,
"org.freedesktop.Tracker1.Resources",
"GraphUpdated",
"/org/freedesktop/Tracker1/Resources",
......@@ -293,8 +290,8 @@ tracker_miner_rss_init (TrackerMinerRSS *object)
graph_updated_cb,
object,
NULL);
g_free (dbus_name);
g_object_unref (domain_ontology);
g_free (dbus_domain_name);
}
static void
......
......@@ -198,32 +198,6 @@ initialize_signal_handler (void)
#endif /* G_OS_WIN32 */
}
static void
log_handler (const gchar *domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
switch (log_level) {
case G_LOG_LEVEL_WARNING:
case G_LOG_LEVEL_CRITICAL:
case G_LOG_LEVEL_ERROR:
case G_LOG_FLAG_RECURSION:
case G_LOG_FLAG_FATAL:
g_fprintf (stderr, "%s\n", message);
fflush (stderr);
break;
case G_LOG_LEVEL_MESSAGE:
case G_LOG_LEVEL_INFO:
case G_LOG_LEVEL_DEBUG:
case G_LOG_LEVEL_MASK:
default:
g_fprintf (stdout, "%s\n", message);
fflush (stdout);
break;
}
}