*/
public class Folks.Backends.Kf.Persona : Folks.Persona,
AliasDetails,
+ AntiLinkable,
ImDetails,
WebServiceDetails
{
- private unowned GLib.KeyFile _key_file;
private HashMultiMap<string, ImFieldDetails> _im_addresses;
private HashMultiMap<string, WebServiceFieldDetails> _web_service_addresses;
- private string _alias;
+ private string _alias = ""; /* must not be null */
private const string[] _linkable_properties =
{
"im-addresses",
{
"alias",
"im-addresses",
- "web-service-addresses"
+ "web-service-addresses",
+ "anti-links"
};
/**
*/
public override string[] linkable_properties
{
- get { return this._linkable_properties; }
+ get { return Kf.Persona._linkable_properties; }
}
/**
*/
public override string[] writeable_properties
{
- get { return this._writeable_properties; }
+ get { return Kf.Persona._writeable_properties; }
}
/**
/**
* {@inheritDoc}
*
- * @since UNRELEASED
+ * @since 0.6.2
*/
public async void change_alias (string alias) throws PropertyError
{
+ /* Deal with badly-behaved callers. */
+ if (alias == null)
+ {
+ alias = "";
+ }
+
if (this._alias == alias)
{
return;
debug ("Setting alias of Kf.Persona '%s' to '%s'.", this.uid, alias);
- this._key_file.set_string (this.display_id, "__alias", alias);
+ unowned KeyFile key_file = ((Kf.PersonaStore) this.store).get_key_file ();
+ key_file.set_string (this.display_id, "__alias", alias);
yield ((Kf.PersonaStore) this.store).save_key_file ();
this._alias = alias;
/**
* {@inheritDoc}
*
- * @since UNRELEASED
+ * @since 0.6.2
*/
public async void change_im_addresses (
MultiMap<string, ImFieldDetails> im_addresses) throws PropertyError
{
+ unowned KeyFile key_file = ((Kf.PersonaStore) this.store).get_key_file ();
+
/* Remove the current IM addresses from the key file */
foreach (var protocol1 in this._im_addresses.get_keys ())
{
try
{
- this._key_file.remove_key (this.display_id, protocol1);
+ key_file.remove_key (this.display_id, protocol1);
}
catch (KeyFileError e1)
{
* table of them to set as the new property value */
var new_im_addresses = new HashMultiMap<string, ImFieldDetails> (
null, null,
- (GLib.HashFunc) ImFieldDetails.hash,
- (GLib.EqualFunc) ImFieldDetails.equal);
+ (Gee.HashDataFunc) AbstractFieldDetails<string>.hash_static,
+ (Gee.EqualDataFunc) AbstractFieldDetails<string>.equal_static);
foreach (var protocol2 in im_addresses.get_keys ())
{
string[] addrs = (string[]) normalised_addresses.to_array ();
addrs.length = normalised_addresses.size;
- this._key_file.set_string_list (this.display_id, protocol2, addrs);
+ key_file.set_string_list (this.display_id, protocol2, addrs);
}
/* Get the PersonaStore to save the key file */
/**
* {@inheritDoc}
*/
+ [CCode (notify = false)]
public MultiMap<string, WebServiceFieldDetails> web_service_addresses
{
- get
- { return this._web_service_addresses; }
+ get { return this._web_service_addresses; }
+ set { this.change_web_service_addresses.begin (value); }
+ }
- set
+ /**
+ * {@inheritDoc}
+ *
+ * @since 0.6.2
+ */
+ public async void change_web_service_addresses (
+ MultiMap<string, WebServiceFieldDetails> web_service_addresses)
+ throws PropertyError
+ {
+ unowned KeyFile key_file = ((Kf.PersonaStore) this.store).get_key_file ();
+
+ /* Remove the current web service addresses from the key file */
+ foreach (var web_service1 in this._web_service_addresses.get_keys ())
{
- /* Remove the current web service addresses from the key file */
- foreach (var web_service in this._web_service_addresses.get_keys ())
+ try
{
- try
- {
- this._key_file.remove_key (this.display_id,
- "web-service." + web_service);
- }
- catch (KeyFileError e)
- {
- /* Ignore the error, since it's just a group or key not found
- * error. */
- }
+ key_file.remove_key (this.display_id,
+ "web-service." + web_service1);
}
+ catch (KeyFileError e)
+ {
+ /* Ignore the error, since it's just a group or key not found
+ * error. */
+ }
+ }
- /* Add the new web service addresses to the key file and build a
- * table of them to set as the new property value */
- var web_service_addresses =
- new HashMultiMap<string, WebServiceFieldDetails> (
- null, null,
- (GLib.HashFunc) WebServiceFieldDetails.hash,
- (GLib.EqualFunc) WebServiceFieldDetails.equal);
+ /* Add the new web service addresses to the key file and build a
+ * table of them to set as the new property value */
+ var new_web_service_addresses =
+ new HashMultiMap<string, WebServiceFieldDetails> (
+ null, null,
+ (Gee.HashDataFunc) AbstractFieldDetails<string>.hash_static,
+ (Gee.EqualDataFunc) AbstractFieldDetails<string>.equal_static);
- foreach (var web_service in value.get_keys ())
- {
- var ws_fds = value.get (web_service);
+ foreach (var web_service2 in web_service_addresses.get_keys ())
+ {
+ var ws_fds = web_service_addresses.get (web_service2);
- string[] addrs = new string[0];
- foreach (var ws_fd in ws_fds)
- addrs += ws_fd.value;
+ string[] addrs = new string[0];
+ foreach (var ws_fd1 in ws_fds)
+ addrs += ws_fd1.value;
- this._key_file.set_string_list (this.display_id,
- "web-service." + web_service, addrs);
+ key_file.set_string_list (this.display_id,
+ "web-service." + web_service2, addrs);
- foreach (var ws_fd in ws_fds)
- web_service_addresses.set (web_service, ws_fd);
- }
+ foreach (var ws_fd2 in ws_fds)
+ new_web_service_addresses.set (web_service2, ws_fd2);
+ }
+
+ /* Get the PersonaStore to save the key file */
+ yield ((Kf.PersonaStore) this.store).save_key_file ();
- this._web_service_addresses = web_service_addresses;
+ this._web_service_addresses = new_web_service_addresses;
+ this.notify_property ("web-service-addresses");
+ }
+
+ private HashSet<string> _anti_links;
+ private Set<string> _anti_links_ro;
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 0.7.3
+ */
+ [CCode (notify = false)]
+ public Set<string> anti_links
+ {
+ get { return this._anti_links_ro; }
+ set { this.change_anti_links.begin (value); }
+ }
- /* Get the PersonaStore to save the key file */
- ((Kf.PersonaStore) this.store).save_key_file.begin ();
+ /**
+ * {@inheritDoc}
+ *
+ * @since 0.7.3
+ */
+ public async void change_anti_links (Set<string> anti_links)
+ throws PropertyError
+ {
+ if (Folks.Internal.equal_sets<string> (anti_links, this.anti_links))
+ {
+ return;
}
+
+ unowned KeyFile key_file = ((Kf.PersonaStore) this.store).get_key_file ();
+
+ /* Skip the persona's UID; don't allow reflexive anti-links. */
+ anti_links.remove (this.uid);
+
+ key_file.set_string_list (this.display_id,
+ Kf.PersonaStore.anti_links_key_name, anti_links.to_array ());
+
+ /* Get the PersonaStore to save the key file */
+ yield ((Kf.PersonaStore) this.store).save_key_file ();
+
+ /* Update the stored anti-links. */
+ this._anti_links.clear ();
+ this._anti_links.add_all (anti_links);
+ this.notify_property ("anti-links");
}
/**
* Create a new persona.
*
- * Create a new persona for the {@link PersonaStore} `store`, representing
- * the Persona given by the group `uid` in the key file `key_file`.
+ * Create a new persona for the {@link PersonaStore} ``store``, representing
+ * the Persona given by the group ``uid`` in the key file ``key_file``.
*/
- public Persona (KeyFile key_file, string id, Folks.PersonaStore store)
+ public Persona (string id, Folks.PersonaStore store)
{
var iid = store.id + ":" + id;
- var uid = this.build_uid ("key-file", store.id, id);
+ var uid = Folks.Persona.build_uid ("key-file", store.id, id);
Object (display_id: id,
iid: iid,
uid: uid,
store: store,
is_user: false);
+ }
- debug ("Adding key-file Persona '%s' (IID '%s', group '%s')", uid, iid,
- id);
+ construct
+ {
+ debug ("Adding key-file Persona '%s' (IID '%s', group '%s')", this.uid,
+ this.iid, this.display_id);
- this._key_file = key_file;
this._im_addresses = new HashMultiMap<string, ImFieldDetails> (
- null, null, ImFieldDetails.hash, (EqualFunc) ImFieldDetails.equal);
+ null, null,
+ (Gee.HashDataFunc) AbstractFieldDetails<string>.hash_static,
+ (Gee.EqualDataFunc) AbstractFieldDetails<string>.equal_static);
this._web_service_addresses =
new HashMultiMap<string, WebServiceFieldDetails> (
- null, null,
- (GLib.HashFunc) WebServiceFieldDetails.hash,
- (GLib.EqualFunc) WebServiceFieldDetails.equal);
+ null, null,
+ (Gee.HashDataFunc) AbstractFieldDetails<string>.hash_static,
+ (Gee.EqualDataFunc) AbstractFieldDetails<string>.equal_static);
+ this._anti_links = new HashSet<string> ();
+ this._anti_links_ro = this._anti_links.read_only_view;
/* Load the IM addresses from the key file */
+ unowned KeyFile key_file = ((Kf.PersonaStore) this.store).get_key_file ();
+
try
{
- var keys = this._key_file.get_keys (this.display_id);
+ var keys = key_file.get_keys (this.display_id);
foreach (unowned string key in keys)
{
/* Alias */
if (key == "__alias")
{
- this._alias = this._key_file.get_string (this.display_id,
- key);
+ this._alias = key_file.get_string (this.display_id, key);
+
+ if (this._alias == null)
+ {
+ this._alias = "";
+ }
+
debug (" Loaded alias '%s'.", this._alias);
continue;
}
+ /* Anti-links. */
+ if (key == Kf.PersonaStore.anti_links_key_name)
+ {
+ var anti_link_array =
+ key_file.get_string_list (this.display_id, key);
+
+ if (anti_link_array != null)
+ {
+ foreach (var anti_link in anti_link_array)
+ {
+ this._anti_links.add (anti_link);
+ }
+
+ debug (" Loaded %u anti-links.",
+ anti_link_array.length);
+ continue;
+ }
+ }
+
/* Web service addresses */
var decomposed_key = key.split(".", 2);
if (decomposed_key.length == 2 &&
decomposed_key[0] == "web-service")
{
unowned string web_service = decomposed_key[1];
- var web_service_addresses = this._key_file.get_string_list (
+ var web_service_addresses = key_file.get_string_list (
this.display_id, web_service);
foreach (var web_service_address in web_service_addresses)
/* IM addresses */
unowned string protocol = key;
- var im_addresses = this._key_file.get_string_list (
+ var im_addresses = key_file.get_string_list (
this.display_id, protocol);
foreach (var im_address in im_addresses)