~ubuntu-branches/ubuntu/saucy/evolution-data-server/saucy

« back to all changes in this revision

Viewing changes to libebackend/e-collection-backend.c

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-10-08 12:58:16 UTC
  • mfrom: (181.1.7 quantal)
  • Revision ID: package-import@ubuntu.com-20121008125816-i3n76e8c0m64e7xp
Tags: 3.6.0-0ubuntu2
* Fix LP: #1038047 part 1 - Don't abort in e_source_registry_new* when a
  problem occurs connecting to the Dbus service
  - add debian/patches/dont-abort-in-e_source_registry_new.patch
  - update debian/patches/series
* Fix LP: #1038047 part 2 - libedataserver depends on
  evolution-data-server-common to ensure that the GSettings schemas are
  present
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
 
42
42
#include "e-collection-backend.h"
43
43
 
 
44
#include <config.h>
 
45
#include <glib/gi18n-lib.h>
 
46
 
44
47
#include <libedataserver/libedataserver.h>
45
48
 
46
49
#include <libebackend/e-server-side-source.h>
52
55
 
53
56
struct _ECollectionBackendPrivate {
54
57
        GWeakRef server;
55
 
        GQueue children;
 
58
 
 
59
        /* Set of ESources */
 
60
        GHashTable *children;
 
61
        GMutex *children_lock;
56
62
 
57
63
        gchar *cache_dir;
58
64
 
82
88
        e_collection_backend,
83
89
        E_TYPE_BACKEND)
84
90
 
 
91
static void
 
92
collection_backend_children_insert (ECollectionBackend *backend,
 
93
                                    ESource *source)
 
94
{
 
95
        g_mutex_lock (backend->priv->children_lock);
 
96
 
 
97
        g_hash_table_add (backend->priv->children, g_object_ref (source));
 
98
 
 
99
        g_mutex_unlock (backend->priv->children_lock);
 
100
}
 
101
 
 
102
static gboolean
 
103
collection_backend_children_remove (ECollectionBackend *backend,
 
104
                                    ESource *source)
 
105
{
 
106
        gboolean removed;
 
107
 
 
108
        g_mutex_lock (backend->priv->children_lock);
 
109
 
 
110
        removed = g_hash_table_remove (backend->priv->children, source);
 
111
 
 
112
        g_mutex_unlock (backend->priv->children_lock);
 
113
 
 
114
        return removed;
 
115
}
 
116
 
 
117
static GList *
 
118
collection_backend_children_list (ECollectionBackend *backend)
 
119
{
 
120
        GList *list, *link;
 
121
 
 
122
        g_mutex_lock (backend->priv->children_lock);
 
123
 
 
124
        list = g_hash_table_get_keys (backend->priv->children);
 
125
 
 
126
        for (link = list; link != NULL; link = g_list_next (link))
 
127
                g_object_ref (link->data);
 
128
 
 
129
        g_mutex_unlock (backend->priv->children_lock);
 
130
 
 
131
        return list;
 
132
}
 
133
 
85
134
static GFile *
86
135
collection_backend_new_user_file (ECollectionBackend *backend)
87
136
{
118
167
        ESourceRegistryServer *server;
119
168
        ESource *child_source;
120
169
        ESource *collection_source;
 
170
        EServerSideSource *server_side_source;
121
171
        const gchar *cache_dir;
122
172
        const gchar *collection_uid;
123
173
 
128
178
        if (child_source == NULL)
129
179
                return NULL;
130
180
 
 
181
        server_side_source = E_SERVER_SIDE_SOURCE (child_source);
 
182
 
131
183
        /* Clients may change the source but may not remove it. */
132
 
        e_server_side_source_set_writable (
133
 
                E_SERVER_SIDE_SOURCE (child_source), TRUE);
134
 
        e_server_side_source_set_removable (
135
 
                E_SERVER_SIDE_SOURCE (child_source), FALSE);
 
184
        e_server_side_source_set_writable (server_side_source, TRUE);
 
185
        e_server_side_source_set_removable (server_side_source, FALSE);
136
186
 
137
187
        /* Changes should be written back to the cache directory. */
138
188
        cache_dir = e_collection_backend_get_cache_dir (backend);
139
189
        e_server_side_source_set_write_directory (
140
 
                E_SERVER_SIDE_SOURCE (child_source), cache_dir);
 
190
                server_side_source, cache_dir);
141
191
 
142
192
        /* Configure the child source as a collection member. */
143
193
        collection_source = e_backend_get_source (E_BACKEND (backend));
470
520
                g_object_unref (server);
471
521
        }
472
522
 
473
 
        while (!g_queue_is_empty (&priv->children))
474
 
                g_object_unref (g_queue_pop_head (&priv->children));
 
523
        g_mutex_lock (priv->children_lock);
 
524
        g_hash_table_remove_all (priv->children);
 
525
        g_mutex_unlock (priv->children_lock);
475
526
 
476
527
        g_mutex_lock (priv->unclaimed_resources_lock);
477
528
        g_hash_table_remove_all (priv->unclaimed_resources);
488
539
 
489
540
        priv = E_COLLECTION_BACKEND_GET_PRIVATE (object);
490
541
 
 
542
        g_hash_table_destroy (priv->children);
 
543
        g_mutex_free (priv->children_lock);
 
544
 
491
545
        g_hash_table_destroy (priv->unclaimed_resources);
492
546
        g_mutex_free (priv->unclaimed_resources_lock);
493
547
 
566
620
                (GDestroyNotify) g_object_unref);
567
621
}
568
622
 
 
623
static gboolean
 
624
collection_backend_authenticate_sync (EBackend *backend,
 
625
                                      ESourceAuthenticator *auth,
 
626
                                      GCancellable *cancellable,
 
627
                                      GError **error)
 
628
{
 
629
        ECollectionBackend *collection_backend;
 
630
        ESourceRegistryServer *server;
 
631
        EAuthenticationSession *session;
 
632
        ESource *source;
 
633
        const gchar *uid;
 
634
        gboolean success;
 
635
 
 
636
        source = e_backend_get_source (backend);
 
637
        uid = e_source_get_uid (source);
 
638
 
 
639
        collection_backend = E_COLLECTION_BACKEND (backend);
 
640
        server = e_collection_backend_ref_server (collection_backend);
 
641
        session = e_authentication_session_new (server, auth, uid);
 
642
 
 
643
        success = e_source_registry_server_authenticate_sync (
 
644
                server, session, cancellable, error);
 
645
 
 
646
        g_object_unref (session);
 
647
        g_object_unref (server);
 
648
 
 
649
        return success;
 
650
}
 
651
 
569
652
static void
570
653
collection_backend_populate (ECollectionBackend *backend)
571
654
{
572
655
        /* Placeholder so subclasses can safely chain up. */
573
656
}
574
657
 
 
658
static gchar *
 
659
collection_backend_dup_resource_id (ECollectionBackend *backend,
 
660
                                    ESource *source)
 
661
{
 
662
        const gchar *extension_name;
 
663
        gchar *resource_id = NULL;
 
664
 
 
665
        extension_name = E_SOURCE_EXTENSION_RESOURCE;
 
666
 
 
667
        if (e_source_has_extension (source, extension_name)) {
 
668
                ESourceResource *extension;
 
669
 
 
670
                extension = e_source_get_extension (source, extension_name);
 
671
                resource_id = e_source_resource_dup_identity (extension);
 
672
        }
 
673
 
 
674
        return resource_id;
 
675
}
 
676
 
575
677
static void
576
678
collection_backend_child_added (ECollectionBackend *backend,
577
679
                                ESource *child_source)
578
680
{
 
681
        collection_backend_children_insert (backend, child_source);
579
682
        collection_backend_bind_child_enabled (backend, child_source);
580
683
 
581
 
        g_queue_push_tail (
582
 
                &backend->priv->children,
583
 
                g_object_ref (child_source));
584
 
 
585
684
        /* Collection children are not removable. */
586
685
        e_server_side_source_set_removable (
587
686
                E_SERVER_SIDE_SOURCE (child_source), FALSE);
591
690
collection_backend_child_removed (ECollectionBackend *backend,
592
691
                                  ESource *child_source)
593
692
{
594
 
        if (g_queue_remove (&backend->priv->children, child_source))
595
 
                g_object_unref (child_source);
 
693
        collection_backend_children_remove (backend, child_source);
 
694
}
 
695
 
 
696
static gboolean
 
697
collection_backend_create_resource_sync (ECollectionBackend *backend,
 
698
                                         ESource *source,
 
699
                                         GCancellable *cancellable,
 
700
                                         GError **error)
 
701
{
 
702
        EAsyncClosure *closure;
 
703
        GAsyncResult *result;
 
704
        gboolean success;
 
705
 
 
706
        closure = e_async_closure_new ();
 
707
 
 
708
        e_collection_backend_create_resource (
 
709
                backend, source, cancellable,
 
710
                e_async_closure_callback, closure);
 
711
 
 
712
        result = e_async_closure_wait (closure);
 
713
 
 
714
        success = e_collection_backend_create_resource_finish (
 
715
                backend, result, error);
 
716
 
 
717
        e_async_closure_free (closure);
 
718
 
 
719
        return success;
 
720
}
 
721
 
 
722
static void
 
723
collection_backend_create_resource (ECollectionBackend *backend,
 
724
                                    ESource *source,
 
725
                                    GCancellable *cancellable,
 
726
                                    GAsyncReadyCallback callback,
 
727
                                    gpointer user_data)
 
728
{
 
729
        GSimpleAsyncResult *simple;
 
730
 
 
731
        simple = g_simple_async_result_new_error (
 
732
                G_OBJECT (backend), callback, user_data,
 
733
                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 
734
                _("%s does not support creating remote resources"),
 
735
                G_OBJECT_TYPE_NAME (backend));
 
736
 
 
737
        g_simple_async_result_complete_in_idle (simple);
 
738
 
 
739
        g_object_unref (simple);
 
740
}
 
741
 
 
742
static gboolean
 
743
collection_backend_create_resource_finish (ECollectionBackend *backend,
 
744
                                           GAsyncResult *result,
 
745
                                           GError **error)
 
746
{
 
747
        GSimpleAsyncResult *simple;
 
748
 
 
749
        simple = G_SIMPLE_ASYNC_RESULT (result);
 
750
 
 
751
        /* Assume success unless a GError is set. */
 
752
        return !g_simple_async_result_propagate_error (simple, error);
 
753
}
 
754
 
 
755
static gboolean
 
756
collection_backend_delete_resource_sync (ECollectionBackend *backend,
 
757
                                         ESource *source,
 
758
                                         GCancellable *cancellable,
 
759
                                         GError **error)
 
760
{
 
761
        EAsyncClosure *closure;
 
762
        GAsyncResult *result;
 
763
        gboolean success;
 
764
 
 
765
        closure = e_async_closure_new ();
 
766
 
 
767
        e_collection_backend_delete_resource (
 
768
                backend, source, cancellable,
 
769
                e_async_closure_callback, closure);
 
770
 
 
771
        result = e_async_closure_wait (closure);
 
772
 
 
773
        success = e_collection_backend_delete_resource_finish (
 
774
                backend, result, error);
 
775
 
 
776
        e_async_closure_free (closure);
 
777
 
 
778
        return success;
 
779
}
 
780
 
 
781
static void
 
782
collection_backend_delete_resource (ECollectionBackend *backend,
 
783
                                    ESource *source,
 
784
                                    GCancellable *cancellable,
 
785
                                    GAsyncReadyCallback callback,
 
786
                                    gpointer user_data)
 
787
{
 
788
        GSimpleAsyncResult *simple;
 
789
 
 
790
        simple = g_simple_async_result_new_error (
 
791
                G_OBJECT (backend), callback, user_data,
 
792
                G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 
793
                _("%s does not support deleting remote resources"),
 
794
                G_OBJECT_TYPE_NAME (backend));
 
795
 
 
796
        g_simple_async_result_complete_in_idle (simple);
 
797
 
 
798
        g_object_unref (simple);
 
799
}
 
800
 
 
801
static gboolean
 
802
collection_backend_delete_resource_finish (ECollectionBackend *backend,
 
803
                                           GAsyncResult *result,
 
804
                                           GError **error)
 
805
{
 
806
        GSimpleAsyncResult *simple;
 
807
 
 
808
        simple = G_SIMPLE_ASYNC_RESULT (result);
 
809
 
 
810
        /* Assume success unless a GError is set. */
 
811
        return !g_simple_async_result_propagate_error (simple, error);
596
812
}
597
813
 
598
814
static void
599
815
e_collection_backend_class_init (ECollectionBackendClass *class)
600
816
{
601
817
        GObjectClass *object_class;
 
818
        EBackendClass *backend_class;
602
819
 
603
820
        g_type_class_add_private (class, sizeof (ECollectionBackendPrivate));
604
821
 
609
826
        object_class->finalize = collection_backend_finalize;
610
827
        object_class->constructed = collection_backend_constructed;
611
828
 
 
829
        backend_class = E_BACKEND_CLASS (class);
 
830
        backend_class->authenticate_sync = collection_backend_authenticate_sync;
 
831
 
612
832
        class->populate = collection_backend_populate;
 
833
        class->dup_resource_id = collection_backend_dup_resource_id;
613
834
        class->child_added = collection_backend_child_added;
614
835
        class->child_removed = collection_backend_child_removed;
 
836
        class->create_resource_sync = collection_backend_create_resource_sync;
 
837
        class->create_resource = collection_backend_create_resource;
 
838
        class->create_resource_finish = collection_backend_create_resource_finish;
 
839
        class->delete_resource_sync = collection_backend_delete_resource_sync;
 
840
        class->delete_resource = collection_backend_delete_resource;
 
841
        class->delete_resource_finish = collection_backend_delete_resource_finish;
615
842
 
616
843
        g_object_class_install_property (
617
844
                object_class,
675
902
static void
676
903
e_collection_backend_init (ECollectionBackend *backend)
677
904
{
 
905
        GHashTable *children;
678
906
        GHashTable *unclaimed_resources;
679
907
 
 
908
        children = g_hash_table_new_full (
 
909
                (GHashFunc) e_source_hash,
 
910
                (GEqualFunc) e_source_equal,
 
911
                (GDestroyNotify) g_object_unref,
 
912
                (GDestroyNotify) NULL);
 
913
 
680
914
        unclaimed_resources = g_hash_table_new_full (
681
915
                (GHashFunc) g_str_hash,
682
916
                (GEqualFunc) g_str_equal,
684
918
                (GDestroyNotify) g_object_unref);
685
919
 
686
920
        backend->priv = E_COLLECTION_BACKEND_GET_PRIVATE (backend);
 
921
        backend->priv->children = children;
 
922
        backend->priv->children_lock = g_mutex_new ();
687
923
        backend->priv->unclaimed_resources = unclaimed_resources;
688
924
        backend->priv->unclaimed_resources_lock = g_mutex_new ();
689
925
}
731
967
 
732
968
        collection_source = e_backend_get_source (E_BACKEND (backend));
733
969
 
734
 
        g_print ("%s: Pairing %s with resource %s\n",
 
970
        g_print (
 
971
                "%s: Pairing %s with resource %s\n",
735
972
                e_source_get_display_name (collection_source),
736
973
                e_source_get_uid (child_source), resource_id);
737
974
 
783
1020
}
784
1021
 
785
1022
/**
 
1023
 * e_collection_backend_dup_resource_id:
 
1024
 * @backend: an #ECollectionBackend
 
1025
 * @child_source: an #ESource managed by @backend
 
1026
 *
 
1027
 * Extracts the resource ID for @child_source, which is supposed to be a
 
1028
 * stable and unique server-assigned identifier for the remote resource
 
1029
 * described by @child_source.  If @child_source is not actually a child
 
1030
 * of the collection #EBackend:source owned by @backend, the function
 
1031
 * returns %NULL.
 
1032
 *
 
1033
 * The returned string should be freed with g_free() when no longer needed.
 
1034
 *
 
1035
 * Returns: a newly-allocated resource ID for @child_source, or %NULL
 
1036
 *
 
1037
 * Since: 3.6
 
1038
 **/
 
1039
gchar *
 
1040
e_collection_backend_dup_resource_id (ECollectionBackend *backend,
 
1041
                                      ESource *child_source)
 
1042
{
 
1043
        ECollectionBackend *backend_for_child_source;
 
1044
        ECollectionBackendClass *class;
 
1045
        ESourceRegistryServer *server;
 
1046
        gboolean child_is_ours = FALSE;
 
1047
 
 
1048
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), NULL);
 
1049
        g_return_val_if_fail (E_IS_SOURCE (child_source), NULL);
 
1050
 
 
1051
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1052
        g_return_val_if_fail (class->dup_resource_id != NULL, NULL);
 
1053
 
 
1054
        /* Make sure the ESource belongs to the ECollectionBackend to
 
1055
         * avoid accidentally creating a new extension while trying to
 
1056
         * extract a resource ID that isn't there.  Better to test this
 
1057
         * up front than rely on ECollectionBackend subclasses to do it. */
 
1058
        server = e_collection_backend_ref_server (backend);
 
1059
        backend_for_child_source =
 
1060
                e_source_registry_server_ref_backend (server, child_source);
 
1061
        g_object_unref (server);
 
1062
 
 
1063
        if (backend_for_child_source != NULL) {
 
1064
                child_is_ours = (backend_for_child_source == backend);
 
1065
                g_object_unref (backend_for_child_source);
 
1066
        }
 
1067
 
 
1068
        if (!child_is_ours)
 
1069
                return NULL;
 
1070
 
 
1071
        return class->dup_resource_id (backend, child_source);
 
1072
}
 
1073
 
 
1074
/**
 
1075
 * e_collection_backend_claim_all_resources:
 
1076
 * @backend: an #ECollectionBackend
 
1077
 *
 
1078
 * Claims all previously used sources that have not yet been claimed by
 
1079
 * e_collection_backend_new_child() and returns them in a #GList.  Note
 
1080
 * that previously used sources can only be claimed once, so subsequent
 
1081
 * calls to this function for @backend will return %NULL.
 
1082
 *
 
1083
 * The @backend is then expected to compare the returned list with a
 
1084
 * current list of resources from a remote server, create new #ESource
 
1085
 * instances as needed with e_collection_backend_new_child(), discard
 
1086
 * unneeded #ESource instances with e_source_remove(), and export the
 
1087
 * remaining instances with e_source_registry_server_add_source().
 
1088
 *
 
1089
 * The sources returned in the list are referenced for thread-safety.
 
1090
 * They must each be unreferenced with g_object_unref() when finished
 
1091
 * with them.  Free the returned #GList itself with g_list_free().
 
1092
 *
 
1093
 * An easy way to free the list properly in one step is as follows:
 
1094
 *
 
1095
 * |[
 
1096
 *   g_list_free_full (list, g_object_unref);
 
1097
 * ]|
 
1098
 *
 
1099
 * Returns: a list of previously used sources
 
1100
 *
 
1101
 * Since: 3.6
 
1102
 **/
 
1103
GList *
 
1104
e_collection_backend_claim_all_resources (ECollectionBackend *backend)
 
1105
{
 
1106
        GHashTable *unclaimed_resources;
 
1107
        GList *resources;
 
1108
 
 
1109
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), NULL);
 
1110
 
 
1111
        g_mutex_lock (backend->priv->unclaimed_resources_lock);
 
1112
 
 
1113
        unclaimed_resources = backend->priv->unclaimed_resources;
 
1114
        resources = g_hash_table_get_values (unclaimed_resources);
 
1115
        g_list_foreach (resources, (GFunc) g_object_ref, NULL);
 
1116
        g_hash_table_remove_all (unclaimed_resources);
 
1117
 
 
1118
        g_mutex_unlock (backend->priv->unclaimed_resources_lock);
 
1119
 
 
1120
        return resources;
 
1121
}
 
1122
 
 
1123
/**
786
1124
 * e_collection_backend_list_calendar_sources:
787
1125
 * @backend: an #ECollectionBackend
788
1126
 *
811
1149
 
812
1150
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), NULL);
813
1151
 
814
 
        list = g_queue_peek_head_link (&backend->priv->children);
 
1152
        list = collection_backend_children_list (backend);
815
1153
 
816
1154
        for (link = list; link != NULL; link = g_list_next (link)) {
817
1155
                ESource *child_source = E_SOURCE (link->data);
820
1158
                                result_list, g_object_ref (child_source));
821
1159
        }
822
1160
 
 
1161
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
1162
 
823
1163
        return g_list_reverse (result_list);
824
1164
}
825
1165
 
852
1192
 
853
1193
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), NULL);
854
1194
 
855
 
        list = g_queue_peek_head_link (&backend->priv->children);
 
1195
        list = collection_backend_children_list (backend);
856
1196
 
857
1197
        for (link = list; link != NULL; link = g_list_next (link)) {
858
1198
                ESource *child_source = E_SOURCE (link->data);
861
1201
                                result_list, g_object_ref (child_source));
862
1202
        }
863
1203
 
 
1204
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
1205
 
864
1206
        return g_list_reverse (result_list);
865
1207
}
866
1208
 
893
1235
 
894
1236
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), NULL);
895
1237
 
896
 
        list = g_queue_peek_head_link (&backend->priv->children);
 
1238
        list = collection_backend_children_list (backend);
897
1239
 
898
1240
        for (link = list; link != NULL; link = g_list_next (link)) {
899
1241
                ESource *child_source = E_SOURCE (link->data);
902
1244
                                result_list, g_object_ref (child_source));
903
1245
        }
904
1246
 
 
1247
        g_list_free_full (list, (GDestroyNotify) g_object_unref);
 
1248
 
905
1249
        return g_list_reverse (result_list);
906
1250
}
907
1251
 
 
1252
/**
 
1253
 * e_collection_backend_create_resource_sync
 
1254
 * @backend: an #ECollectionBackend
 
1255
 * @source: an #ESource
 
1256
 * @cancellable: optional #GCancellable object, or %NULL
 
1257
 * @error: return location for a #GError, or %NULL
 
1258
 *
 
1259
 * Creates a server-side resource described by @source.  For example, if
 
1260
 * @source describes a new calendar, an equivalent calendar is created on
 
1261
 * the server.
 
1262
 *
 
1263
 * It is the implementor's responsibility to examine @source and determine
 
1264
 * what the equivalent server-side resource would be.  If this cannot be
 
1265
 * determined without ambiguity, the function must return an error.
 
1266
 *
 
1267
 * After the server-side resource is successfully created, the implementor
 
1268
 * must also add an #ESource to @backend's #ECollectionBackend:server.  This
 
1269
 * can either be done immediately or in response to some "resource created"
 
1270
 * notification from the server.  The added #ESource can be @source itself
 
1271
 * or a different #ESource instance that describes the new resource.
 
1272
 *
 
1273
 * If an error occurs, the function will set @error and return %FALSE.
 
1274
 *
 
1275
 * Returns: %TRUE on success, %FALSE on failure
 
1276
 *
 
1277
 * Since: 3.6
 
1278
 **/
 
1279
gboolean
 
1280
e_collection_backend_create_resource_sync (ECollectionBackend *backend,
 
1281
                                           ESource *source,
 
1282
                                           GCancellable *cancellable,
 
1283
                                           GError **error)
 
1284
{
 
1285
        ECollectionBackendClass *class;
 
1286
 
 
1287
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), FALSE);
 
1288
        g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
 
1289
 
 
1290
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1291
        g_return_val_if_fail (class->create_resource_sync != NULL, FALSE);
 
1292
 
 
1293
        return class->create_resource_sync (
 
1294
                backend, source, cancellable, error);
 
1295
}
 
1296
 
 
1297
/**
 
1298
 * e_collection_backend_create_resource:
 
1299
 * @backend: an #ECollectionBackend
 
1300
 * @source: an #ESource
 
1301
 * @cancellable: optional #GCancellable object, or %NULL
 
1302
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
 
1303
 * @user_data: data to pass to the callback function
 
1304
 *
 
1305
 * Asynchronously creates a server-side resource described by @source.
 
1306
 * For example, if @source describes a new calendar, an equivalent calendar
 
1307
 * is created on the server.
 
1308
 *
 
1309
 * It is the implementor's responsibility to examine @source and determine
 
1310
 * what the equivalent server-side resource would be.  If this cannot be
 
1311
 * determined without ambiguity, the function must return an error.
 
1312
 *
 
1313
 * After the server-side resource is successfully created, the implementor
 
1314
 * must also add an #ESource to @backend's #ECollectionBackend:server.  This
 
1315
 * can either be done immediately or in response to some "resource created"
 
1316
 * notification from the server.  The added #ESource can be @source itself
 
1317
 * or a different #ESource instance that describes the new resource.
 
1318
 *
 
1319
 * When the operation is finished, @callback will be called.  You can then
 
1320
 * call e_collection_backend_create_resource_finish() to get the result of
 
1321
 * the operation.
 
1322
 *
 
1323
 * Since: 3.6
 
1324
 **/
 
1325
void
 
1326
e_collection_backend_create_resource (ECollectionBackend *backend,
 
1327
                                      ESource *source,
 
1328
                                      GCancellable *cancellable,
 
1329
                                      GAsyncReadyCallback callback,
 
1330
                                      gpointer user_data)
 
1331
{
 
1332
        ECollectionBackendClass *class;
 
1333
 
 
1334
        g_return_if_fail (E_IS_COLLECTION_BACKEND (backend));
 
1335
        g_return_if_fail (E_IS_SOURCE (source));
 
1336
 
 
1337
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1338
        g_return_if_fail (class->create_resource != NULL);
 
1339
 
 
1340
        class->create_resource (
 
1341
                backend, source, cancellable, callback, user_data);
 
1342
}
 
1343
 
 
1344
/**
 
1345
 * e_collection_backend_create_resource_finish:
 
1346
 * @backend: an #ECollectionBackend
 
1347
 * @result: a #GAsyncResult
 
1348
 * @error: return location for a #GError, or %NULL
 
1349
 *
 
1350
 * Finishes the operation started with e_collection_backend_create_resource().
 
1351
 *
 
1352
 * If an error occurred, the function will set @error and return %FALSE.
 
1353
 *
 
1354
 * Returns: %TRUE on success, %FALSE on failure
 
1355
 *
 
1356
 * Since: 3.6
 
1357
 **/
 
1358
gboolean
 
1359
e_collection_backend_create_resource_finish (ECollectionBackend *backend,
 
1360
                                             GAsyncResult *result,
 
1361
                                             GError **error)
 
1362
{
 
1363
        ECollectionBackendClass *class;
 
1364
 
 
1365
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), FALSE);
 
1366
        g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
 
1367
 
 
1368
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1369
        g_return_val_if_fail (class->create_resource_finish != NULL, FALSE);
 
1370
 
 
1371
        return class->create_resource_finish (backend, result, error);
 
1372
}
 
1373
 
 
1374
/**
 
1375
 * e_collection_backend_delete_resource_sync:
 
1376
 * @backend: an #ECollectionBackend
 
1377
 * @source: an #ESource
 
1378
 * @cancellable: optional #GCancellable object, or %NULL
 
1379
 * @error: return location for a #GError, or %NULL
 
1380
 *
 
1381
 * Deletes a server-side resource described by @source.  The @source must
 
1382
 * be a child of @backend's collection #EBackend:source.
 
1383
 *
 
1384
 * After the server-side resource is successfully deleted, the implementor
 
1385
 * must also remove @source from the @backend's #ECollectionBackend:server.
 
1386
 * This can either be done immediately or in response to some "resource
 
1387
 * deleted" notification from the server.
 
1388
 *
 
1389
 * If an error occurs, the function will set @error and return %FALSE.
 
1390
 *
 
1391
 * Returns: %TRUE on success, %FALSE on failure
 
1392
 *
 
1393
 * Since: 3.6
 
1394
 **/
 
1395
gboolean
 
1396
e_collection_backend_delete_resource_sync (ECollectionBackend *backend,
 
1397
                                           ESource *source,
 
1398
                                           GCancellable *cancellable,
 
1399
                                           GError **error)
 
1400
{
 
1401
        ECollectionBackendClass *class;
 
1402
 
 
1403
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), FALSE);
 
1404
        g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
 
1405
 
 
1406
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1407
        g_return_val_if_fail (class->delete_resource_sync != NULL, FALSE);
 
1408
 
 
1409
        return class->delete_resource_sync (
 
1410
                backend, source, cancellable, error);
 
1411
}
 
1412
 
 
1413
/**
 
1414
 * e_collection_backend_delete_resource:
 
1415
 * @backend: an #ECollectionBackend
 
1416
 * @source: an #ESource
 
1417
 * @cancellable: optional #GCancellable object, or %NULL
 
1418
 * @callback: a #GAsyncReadyCallback to call when the request is satisfied
 
1419
 * @user_data: data to pass to the callback function
 
1420
 *
 
1421
 * Asynchronously deletes a server-side resource described by @source.
 
1422
 * The @source must be a child of @backend's collection #EBackend:source.
 
1423
 *
 
1424
 * After the server-side resource is successfully deleted, the implementor
 
1425
 * must also remove @source from the @backend's #ECollectionBackend:server.
 
1426
 * This can either be done immediately or in response to some "resource
 
1427
 * deleted" notification from the server.
 
1428
 *
 
1429
 * When the operation is finished, @callback will be called.  You can then
 
1430
 * call e_collection_backend_delete_resource_finish() to get the result of
 
1431
 * the operation.
 
1432
 *
 
1433
 * Since: 3.6
 
1434
 **/
 
1435
void
 
1436
e_collection_backend_delete_resource (ECollectionBackend *backend,
 
1437
                                      ESource *source,
 
1438
                                      GCancellable *cancellable,
 
1439
                                      GAsyncReadyCallback callback,
 
1440
                                      gpointer user_data)
 
1441
{
 
1442
        ECollectionBackendClass *class;
 
1443
 
 
1444
        g_return_if_fail (E_IS_COLLECTION_BACKEND (backend));
 
1445
        g_return_if_fail (E_IS_SOURCE (source));
 
1446
 
 
1447
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1448
        g_return_if_fail (class->delete_resource != NULL);
 
1449
 
 
1450
        return class->delete_resource (
 
1451
                backend, source, cancellable, callback, user_data);
 
1452
}
 
1453
 
 
1454
/**
 
1455
 * e_collection_backend_delete_resource_finish:
 
1456
 * @backend: an #ECollectionBackend
 
1457
 * @result: a #GAsyncResult
 
1458
 * @error: return location for a #GError, or %NULL
 
1459
 *
 
1460
 * Finishes the operation started with e_collection_backend_delete_resource().
 
1461
 *
 
1462
 * If an error occurred, the function will set @error and return %FALSE.
 
1463
 *
 
1464
 * Returns: %TRUE on success, %FALSE on failure
 
1465
 *
 
1466
 * Since: 3.6
 
1467
 **/
 
1468
gboolean
 
1469
e_collection_backend_delete_resource_finish (ECollectionBackend *backend,
 
1470
                                             GAsyncResult *result,
 
1471
                                             GError **error)
 
1472
{
 
1473
        ECollectionBackendClass *class;
 
1474
 
 
1475
        g_return_val_if_fail (E_IS_COLLECTION_BACKEND (backend), FALSE);
 
1476
        g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
 
1477
 
 
1478
        class = E_COLLECTION_BACKEND_GET_CLASS (backend);
 
1479
        g_return_val_if_fail (class->delete_resource_finish != NULL, FALSE);
 
1480
 
 
1481
        return class->delete_resource_finish (backend, result, error);
 
1482
}
 
1483