/* * Copyright (C) 2010 Collabora Ltd. * * This library 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.1 of the License, or * (at your option) any later version. * * This library 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 library. If not, see . * * Authors: * Travis Reitter */ using GLib; using Gee; /** * A single backend to libfolks, such as Telepathy or evolution-data-server. * Each backend provides {@link Persona}s which are aggregated to form * {@link Individual}s. * * After creating a Backend instance, you must connect to the * {@link Backend.persona_store_added} and * {@link Backend.persona_store_removed} signals, //then// call * {@link Backend.prepare}, otherwise a race condition may occur between * emission of {@link Backend.persona_store_added} and your code connecting to * it. */ public abstract class Folks.Backend : Object { construct { debug ("Constructing Backend ‘%s’ (%p)", this.name, this); } ~Backend () { debug ("Destroying Backend ‘%s’ (%p)", this.name, this); } /** * Whether {@link Backend.prepare} has successfully completed for this * backend. * * @since 0.3.0 */ public abstract bool is_prepared { get; default = false; } /** * Whether the backend has reached a quiescent state. This will happen at some * point after {@link Backend.prepare} has successfully completed for the * backend. A backend is in a quiescent state when all the * {@link PersonaStore}s that it originally knows about have been loaded. * * It's guaranteed that this property's value will only ever change after * {@link Backend.is_prepared} has changed to ``true``. * * When {@link Backend.unprepare} is called, this will be reset to ``false``. * * @since 0.6.2 */ public abstract bool is_quiescent { get; default = false; } /** * A unique name for the backend. * * This will be used to identify the backend, and should also be used as the * {@link PersonaStore.type_id} of the {@link PersonaStore}s used by the * backend. * * This is guaranteed to always be available; even before * {@link Backend.prepare} is called. */ public abstract string name { get; } /** * The {@link PersonaStore}s in use by the backend. * * A backend may expose {@link Persona}s from multiple servers or accounts * (for example), so may have a {@link PersonaStore} for each. * * @since 0.5.1 */ public abstract Map persona_stores { get; } /** * Disable a {@link PersonaStore}. * * If the given persona store is in this backend {@link Backend.persona_stores}, * it will be removed, and we will disconnect from its signals. * * @param store the {@link PersonaStore} to disable. * * @since 0.9.0 */ public abstract void disable_persona_store (PersonaStore store); /** * Enable a {@link PersonaStore}. * * If the given persona store is not already in this backend * {@link Backend.persona_stores}, it will be added to the backend and * {@link Backend.persona_stores} property notification will be emitted, * along with {@link Backend.persona_store_added}. * * @param store the {@link PersonaStore} to enable. * * @since 0.9.0 */ public abstract void enable_persona_store (PersonaStore store); /** * Set the {@link PersonaStore}s to use in this backend. * * This will cause {@link Backend.persona_store_removed} signals to be emitted * for all removed stores, followed by {@link Backend.persona_store_added} * signals for all added stores. As these signals are emitted, the sets of * individuals in any associated {@link IndividualAggregator}s will be * updated, and {@link IndividualAggregator.individuals_changed} may be * emitted multiple times as appropriate. A property change notification for * {@link Backend.persona_stores} will be emitted last. * Note: pass null storeids to use all available persona stores. * * @param storeids a Set of {@link PersonaStore} IDs to use. * * @since 0.9.0 */ public abstract void set_persona_stores (Set? storeids); /** * Emitted when a {@link PersonaStore} is added to the backend. * * This will not be emitted until after {@link Backend.prepare} has been * called. * * @param store the {@link PersonaStore} */ public abstract signal void persona_store_added (PersonaStore store); /** * Emitted when a {@link PersonaStore} is removed from the backend. * * This will not be emitted until after {@link Backend.prepare} has been * called. * * @param store the {@link PersonaStore} */ public abstract signal void persona_store_removed (PersonaStore store); /** * Prepare the Backend for use. * * This connects the Backend to whichever backend-specific services it * requires, and causes it to create its {@link PersonaStore}s. This should be * called //after// connecting to the {@link Backend.persona_store_added} and * {@link Backend.persona_store_removed} signals, or a race condition could * occur, with the signals being emitted before your code has connected to * them, and {@link PersonaStore}s getting "lost" as a result. * * This is normally handled transparently by the {@link IndividualAggregator}. * * If this function throws an error, the Backend will not be functional. * * This function is guaranteed to be idempotent (since version 0.3.0). * * Concurrent calls to this function from different threads will block until * preparation has completed. However, concurrent calls to this function from * a single thread might not, i.e. the first call will block but subsequent * calls might return before the first one. (Though they will be safe in every * other respect.) * * @since 0.1.11 * @throws GLib.Error if preparing the backend-specific services failed — this * will be a backend-specific error * @throws GLib.DBusError.SERVICE_UNKNOWN if a required D-Bus service was not * installed or could not be started */ public abstract async void prepare () throws GLib.Error; /** * Revert the Backend to its pre-prepared state. * * This will disconnect this Backend and its dependencies from their * respective services and the Backend will issue * {@link Backend.persona_store_removed} for each of its * {@link PersonaStore}s. * * Most users won't need to use this function. * * If this function throws an error, the Backend will not be functional. * * Concurrent calls to this function from different threads will block until * preparation has completed. However, concurrent calls to this function from * a single thread might not, i.e. the first call will block but subsequent * calls might return before the first one. (Though they will be safe in every * other respect.) * * @since 0.3.2 * @throws GLib.Error if unpreparing the backend-specific services failed — * this will be a backend-specific error */ public abstract async void unprepare () throws GLib.Error; }