~codygarver/+junk/gnome-builder

« back to all changes in this revision

Viewing changes to libide/doap/ide-doap.c

  • Committer: Cody Garver
  • Date: 2015-11-21 00:50:38 UTC
  • Revision ID: cody@elementary.io-20151121005038-8wygis63zt0ljqlz
Import https://github.com/chergert/gnome-builder 06e3158922a02a27f4abca250d70aa7b2970e06a

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ide-doap.c
 
2
 *
 
3
 * Copyright (C) 2015 Christian Hergert <christian@hergert.me>
 
4
 *
 
5
 * This program is free software: you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation, either version 3 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
17
 */
 
18
 
 
19
#define G_LOG_DOMAIN "ide-doap"
 
20
 
 
21
#include <glib/gi18n.h>
 
22
 
 
23
#include "ide-doap.h"
 
24
#include "ide-macros.h"
 
25
 
 
26
#include "xml-reader.h"
 
27
 
 
28
/*
 
29
 * TODO: We don't do any XMLNS checking or anything here.
 
30
 */
 
31
 
 
32
struct _IdeDoap
 
33
{
 
34
  GObject parent_instance;
 
35
 
 
36
  gchar     *bug_database;
 
37
  gchar     *category;
 
38
  gchar     *description;
 
39
  gchar     *download_page;
 
40
  gchar     *homepage;;
 
41
  gchar     *name;
 
42
  gchar     *shortdesc;
 
43
 
 
44
  GPtrArray *languages;
 
45
  GList     *maintainers;
 
46
};
 
47
 
 
48
G_DEFINE_QUARK (ide_doap_error, ide_doap_error)
 
49
G_DEFINE_TYPE (IdeDoap, ide_doap, G_TYPE_OBJECT)
 
50
 
 
51
enum {
 
52
  PROP_0,
 
53
  PROP_BUG_DATABASE,
 
54
  PROP_CATEGORY,
 
55
  PROP_DESCRIPTION,
 
56
  PROP_DOWNLOAD_PAGE,
 
57
  PROP_HOMEPAGE,
 
58
  PROP_LANGUAGES,
 
59
  PROP_NAME,
 
60
  PROP_SHORTDESC,
 
61
  LAST_PROP
 
62
};
 
63
 
 
64
static GParamSpec *gParamSpecs [LAST_PROP];
 
65
 
 
66
IdeDoap *
 
67
ide_doap_new (void)
 
68
{
 
69
  return g_object_new (IDE_TYPE_DOAP, NULL);
 
70
}
 
71
 
 
72
const gchar *
 
73
ide_doap_get_name (IdeDoap *self)
 
74
{
 
75
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
76
 
 
77
  return self->name;
 
78
}
 
79
 
 
80
const gchar *
 
81
ide_doap_get_shortdesc (IdeDoap *self)
 
82
{
 
83
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
84
 
 
85
  return self->shortdesc;
 
86
}
 
87
 
 
88
const gchar *
 
89
ide_doap_get_description (IdeDoap *self)
 
90
{
 
91
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
92
 
 
93
  return self->description;
 
94
}
 
95
 
 
96
const gchar *
 
97
ide_doap_get_bug_database (IdeDoap *self)
 
98
{
 
99
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
100
 
 
101
  return self->bug_database;
 
102
}
 
103
 
 
104
const gchar *
 
105
ide_doap_get_download_page (IdeDoap *self)
 
106
{
 
107
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
108
 
 
109
  return self->download_page;
 
110
}
 
111
 
 
112
const gchar *
 
113
ide_doap_get_homepage (IdeDoap *self)
 
114
{
 
115
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
116
 
 
117
  return self->homepage;
 
118
}
 
119
 
 
120
const gchar *
 
121
ide_doap_get_category (IdeDoap *self)
 
122
{
 
123
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
124
 
 
125
  return self->category;
 
126
}
 
127
 
 
128
/**
 
129
 * ide_doap_get_languages:
 
130
 *
 
131
 * Returns: (transfer none): A #GStrv.
 
132
 */
 
133
gchar **
 
134
ide_doap_get_languages (IdeDoap *self)
 
135
{
 
136
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
137
 
 
138
  if (self->languages != NULL)
 
139
    return (gchar **)self->languages->pdata;
 
140
 
 
141
  return NULL;
 
142
}
 
143
 
 
144
static void
 
145
ide_doap_set_bug_database (IdeDoap     *self,
 
146
                           const gchar *bug_database)
 
147
{
 
148
  g_return_if_fail (IDE_IS_DOAP (self));
 
149
 
 
150
  if (!ide_str_equal0 (self->bug_database, bug_database))
 
151
    {
 
152
      g_free (self->bug_database);
 
153
      self->bug_database = g_strdup (bug_database);
 
154
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_BUG_DATABASE]);
 
155
    }
 
156
}
 
157
 
 
158
static void
 
159
ide_doap_set_category (IdeDoap     *self,
 
160
                       const gchar *category)
 
161
{
 
162
  g_return_if_fail (IDE_IS_DOAP (self));
 
163
 
 
164
  if (!ide_str_equal0 (self->category, category))
 
165
    {
 
166
      g_free (self->category);
 
167
      self->category = g_strdup (category);
 
168
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_CATEGORY]);
 
169
    }
 
170
}
 
171
 
 
172
static void
 
173
ide_doap_set_description (IdeDoap     *self,
 
174
                          const gchar *description)
 
175
{
 
176
  g_return_if_fail (IDE_IS_DOAP (self));
 
177
 
 
178
  if (!ide_str_equal0 (self->description, description))
 
179
    {
 
180
      g_free (self->description);
 
181
      self->description = g_strdup (description);
 
182
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DESCRIPTION]);
 
183
    }
 
184
}
 
185
 
 
186
static void
 
187
ide_doap_set_download_page (IdeDoap     *self,
 
188
                            const gchar *download_page)
 
189
{
 
190
  g_return_if_fail (IDE_IS_DOAP (self));
 
191
 
 
192
  if (!ide_str_equal0 (self->download_page, download_page))
 
193
    {
 
194
      g_free (self->download_page);
 
195
      self->download_page = g_strdup (download_page);
 
196
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOWNLOAD_PAGE]);
 
197
    }
 
198
}
 
199
 
 
200
static void
 
201
ide_doap_set_homepage (IdeDoap     *self,
 
202
                       const gchar *homepage)
 
203
{
 
204
  g_return_if_fail (IDE_IS_DOAP (self));
 
205
 
 
206
  if (!ide_str_equal0 (self->homepage, homepage))
 
207
    {
 
208
      g_free (self->homepage);
 
209
      self->homepage = g_strdup (homepage);
 
210
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_HOMEPAGE]);
 
211
    }
 
212
}
 
213
 
 
214
static void
 
215
ide_doap_set_name (IdeDoap     *self,
 
216
                   const gchar *name)
 
217
{
 
218
  g_return_if_fail (IDE_IS_DOAP (self));
 
219
 
 
220
  if (!ide_str_equal0 (self->name, name))
 
221
    {
 
222
      g_free (self->name);
 
223
      self->name = g_strdup (name);
 
224
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_NAME]);
 
225
    }
 
226
}
 
227
 
 
228
static void
 
229
ide_doap_set_shortdesc (IdeDoap     *self,
 
230
                        const gchar *shortdesc)
 
231
{
 
232
  g_return_if_fail (IDE_IS_DOAP (self));
 
233
 
 
234
  if (!ide_str_equal0 (self->shortdesc, shortdesc))
 
235
    {
 
236
      g_free (self->shortdesc);
 
237
      self->shortdesc = g_strdelimit (g_strdup (shortdesc), "\n", ' ');
 
238
      g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_SHORTDESC]);
 
239
    }
 
240
}
 
241
 
 
242
/**
 
243
 * ide_doap_get_maintainers:
 
244
 *
 
245
 *
 
246
 *
 
247
 * Returns: (transfer none) (element-type IdeDoapPerson*): A #GList of #IdeDoapPerson.
 
248
 */
 
249
GList *
 
250
ide_doap_get_maintainers (IdeDoap *self)
 
251
{
 
252
  g_return_val_if_fail (IDE_IS_DOAP (self), NULL);
 
253
 
 
254
  return self->maintainers;
 
255
}
 
256
 
 
257
static void
 
258
ide_doap_add_language (IdeDoap     *self,
 
259
                       const gchar *language)
 
260
{
 
261
  g_return_if_fail (IDE_IS_DOAP (self));
 
262
  g_return_if_fail (language != NULL);
 
263
 
 
264
  if (self->languages == NULL)
 
265
    {
 
266
      self->languages = g_ptr_array_new_with_free_func (g_free);
 
267
      g_ptr_array_add (self->languages, NULL);
 
268
    }
 
269
 
 
270
  g_assert (self->languages->len > 0);
 
271
 
 
272
  g_ptr_array_index (self->languages, self->languages->len - 1) = g_strdup (language);
 
273
  g_ptr_array_add (self->languages, NULL);
 
274
 
 
275
  g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_LANGUAGES]);
 
276
}
 
277
 
 
278
static void
 
279
ide_doap_set_languages (IdeDoap  *self,
 
280
                        gchar   **languages)
 
281
{
 
282
  gsize i;
 
283
 
 
284
  g_return_if_fail (IDE_IS_DOAP (self));
 
285
 
 
286
  if ((self->languages != NULL) && (self->languages->len > 0))
 
287
    g_ptr_array_remove_range (self->languages, 0, self->languages->len);
 
288
 
 
289
  g_object_freeze_notify (G_OBJECT (self));
 
290
  for (i = 0; languages [i]; i++)
 
291
    ide_doap_add_language (self, languages [i]);
 
292
  g_object_thaw_notify (G_OBJECT (self));
 
293
}
 
294
 
 
295
static void
 
296
ide_doap_finalize (GObject *object)
 
297
{
 
298
  IdeDoap *self = (IdeDoap *)object;
 
299
 
 
300
  g_clear_pointer (&self->bug_database, g_free);
 
301
  g_clear_pointer (&self->category, g_free);
 
302
  g_clear_pointer (&self->description, g_free);
 
303
  g_clear_pointer (&self->download_page, g_free);
 
304
  g_clear_pointer (&self->homepage, g_free);
 
305
  g_clear_pointer (&self->languages, g_ptr_array_unref);
 
306
  g_clear_pointer (&self->name, g_free);
 
307
  g_clear_pointer (&self->shortdesc, g_free);
 
308
 
 
309
  g_list_free_full (self->maintainers, g_object_unref);
 
310
  self->maintainers = NULL;
 
311
 
 
312
  G_OBJECT_CLASS (ide_doap_parent_class)->finalize (object);
 
313
}
 
314
 
 
315
static void
 
316
ide_doap_get_property (GObject    *object,
 
317
                       guint       prop_id,
 
318
                       GValue     *value,
 
319
                       GParamSpec *pspec)
 
320
{
 
321
  IdeDoap *self = IDE_DOAP (object);
 
322
 
 
323
  switch (prop_id)
 
324
    {
 
325
    case PROP_BUG_DATABASE:
 
326
      g_value_set_string (value, ide_doap_get_bug_database (self));
 
327
      break;
 
328
 
 
329
    case PROP_CATEGORY:
 
330
      g_value_set_string (value, ide_doap_get_category (self));
 
331
      break;
 
332
 
 
333
    case PROP_DESCRIPTION:
 
334
      g_value_set_string (value, ide_doap_get_description (self));
 
335
      break;
 
336
 
 
337
    case PROP_DOWNLOAD_PAGE:
 
338
      g_value_set_string (value, ide_doap_get_download_page (self));
 
339
      break;
 
340
 
 
341
    case PROP_HOMEPAGE:
 
342
      g_value_set_string (value, ide_doap_get_homepage (self));
 
343
      break;
 
344
 
 
345
    case PROP_LANGUAGES:
 
346
      g_value_set_boxed (value, ide_doap_get_languages (self));
 
347
      break;
 
348
 
 
349
    case PROP_NAME:
 
350
      g_value_set_string (value, ide_doap_get_name (self));
 
351
      break;
 
352
 
 
353
    case PROP_SHORTDESC:
 
354
      g_value_set_string (value, ide_doap_get_shortdesc (self));
 
355
      break;
 
356
 
 
357
    default:
 
358
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
359
    }
 
360
}
 
361
 
 
362
static void
 
363
ide_doap_set_property (GObject      *object,
 
364
                       guint         prop_id,
 
365
                       const GValue *value,
 
366
                       GParamSpec   *pspec)
 
367
{
 
368
  IdeDoap *self = IDE_DOAP (object);
 
369
 
 
370
  switch (prop_id)
 
371
    {
 
372
    case PROP_BUG_DATABASE:
 
373
      ide_doap_set_bug_database (self, g_value_get_string (value));
 
374
      break;
 
375
 
 
376
    case PROP_CATEGORY:
 
377
      ide_doap_set_category (self, g_value_get_string (value));
 
378
      break;
 
379
 
 
380
    case PROP_DESCRIPTION:
 
381
      ide_doap_set_description (self, g_value_get_string (value));
 
382
      break;
 
383
 
 
384
    case PROP_DOWNLOAD_PAGE:
 
385
      ide_doap_set_download_page (self, g_value_get_string (value));
 
386
      break;
 
387
 
 
388
    case PROP_HOMEPAGE:
 
389
      ide_doap_set_homepage (self, g_value_get_string (value));
 
390
      break;
 
391
 
 
392
    case PROP_LANGUAGES:
 
393
      ide_doap_set_languages (self, g_value_get_boxed (value));
 
394
      break;
 
395
 
 
396
    case PROP_NAME:
 
397
      ide_doap_set_name (self, g_value_get_string (value));
 
398
      break;
 
399
 
 
400
    case PROP_SHORTDESC:
 
401
      ide_doap_set_shortdesc (self, g_value_get_string (value));
 
402
      break;
 
403
 
 
404
    default:
 
405
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 
406
    }
 
407
}
 
408
 
 
409
static void
 
410
ide_doap_class_init (IdeDoapClass *klass)
 
411
{
 
412
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
413
 
 
414
  object_class->finalize = ide_doap_finalize;
 
415
  object_class->get_property = ide_doap_get_property;
 
416
  object_class->set_property = ide_doap_set_property;
 
417
 
 
418
  gParamSpecs [PROP_BUG_DATABASE] =
 
419
    g_param_spec_string ("bug-database",
 
420
                         "Bug Database",
 
421
                         "Bug Database",
 
422
                         NULL,
 
423
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
424
 
 
425
  gParamSpecs [PROP_CATEGORY] =
 
426
    g_param_spec_string ("category",
 
427
                         "Category",
 
428
                         "Category",
 
429
                         NULL,
 
430
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
431
 
 
432
  gParamSpecs [PROP_DESCRIPTION] =
 
433
    g_param_spec_string ("description",
 
434
                         "Description",
 
435
                         "Description",
 
436
                         NULL,
 
437
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
438
 
 
439
  gParamSpecs [PROP_DOWNLOAD_PAGE] =
 
440
    g_param_spec_string ("download-page",
 
441
                         "Download Page",
 
442
                         "Download Page",
 
443
                         NULL,
 
444
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
445
 
 
446
  gParamSpecs [PROP_HOMEPAGE] =
 
447
    g_param_spec_string ("homepage",
 
448
                         "Homepage",
 
449
                         "Homepage",
 
450
                         NULL,
 
451
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
452
 
 
453
  gParamSpecs [PROP_LANGUAGES] =
 
454
    g_param_spec_string ("languages",
 
455
                         "Languages",
 
456
                         "Languages",
 
457
                         NULL,
 
458
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
459
 
 
460
  gParamSpecs [PROP_NAME] =
 
461
    g_param_spec_string ("name",
 
462
                         "Name",
 
463
                         "Name",
 
464
                         NULL,
 
465
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
466
 
 
467
  gParamSpecs [PROP_SHORTDESC] =
 
468
    g_param_spec_string ("shortdesc",
 
469
                         "Shortdesc",
 
470
                         "Shortdesc",
 
471
                         NULL,
 
472
                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
473
 
 
474
  g_object_class_install_properties (object_class, LAST_PROP, gParamSpecs);
 
475
}
 
476
 
 
477
static void
 
478
ide_doap_init (IdeDoap *self)
 
479
{
 
480
}
 
481
 
 
482
static gboolean
 
483
ide_doap_parse_maintainer (IdeDoap   *self,
 
484
                           XmlReader *reader)
 
485
{
 
486
  g_assert (IDE_IS_DOAP (self));
 
487
  g_assert (XML_IS_READER (reader));
 
488
 
 
489
  if (!xml_reader_read (reader))
 
490
    return FALSE;
 
491
 
 
492
  do
 
493
    {
 
494
      if (xml_reader_is_a_local (reader, "Person") && xml_reader_read (reader))
 
495
        {
 
496
          g_autoptr(IdeDoapPerson) person = ide_doap_person_new ();
 
497
 
 
498
          do
 
499
            {
 
500
              if (xml_reader_is_a_local (reader, "name"))
 
501
                {
 
502
                  ide_doap_person_set_name (person, xml_reader_read_string (reader));
 
503
                }
 
504
              else if (xml_reader_is_a_local (reader, "mbox"))
 
505
                {
 
506
                  gchar *str;
 
507
 
 
508
                  str = xml_reader_get_attribute (reader, "rdf:resource");
 
509
                  if (!ide_str_empty0 (str) && g_str_has_prefix (str, "mailto:"))
 
510
                    ide_doap_person_set_email (person, str + strlen ("mailto:"));
 
511
                  g_free (str);
 
512
                }
 
513
            }
 
514
          while (xml_reader_read_to_next (reader));
 
515
 
 
516
          if (ide_doap_person_get_name (person) || ide_doap_person_get_email (person))
 
517
            self->maintainers = g_list_append (self->maintainers, g_object_ref (person));
 
518
        }
 
519
    }
 
520
  while (xml_reader_read_to_next (reader));
 
521
 
 
522
  return TRUE;
 
523
}
 
524
 
 
525
gboolean
 
526
ide_doap_load_from_file (IdeDoap       *self,
 
527
                         GFile         *file,
 
528
                         GCancellable  *cancellable,
 
529
                         GError       **error)
 
530
{
 
531
  g_autoptr(XmlReader) reader = NULL;
 
532
 
 
533
  g_return_val_if_fail (IDE_IS_DOAP (self), FALSE);
 
534
  g_return_val_if_fail (G_IS_FILE (file), FALSE);
 
535
  g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
 
536
 
 
537
  reader = xml_reader_new ();
 
538
 
 
539
  if (!xml_reader_load_from_file (reader, file, cancellable, error))
 
540
    return FALSE;
 
541
 
 
542
  if (!xml_reader_read_start_element (reader, "Project"))
 
543
    {
 
544
      g_set_error (error,
 
545
                   IDE_DOAP_ERROR,
 
546
                   IDE_DOAP_ERROR_INVALID_FORMAT,
 
547
                   "Project element is missing from doap.");
 
548
      return FALSE;
 
549
    }
 
550
 
 
551
  g_object_freeze_notify (G_OBJECT (self));
 
552
 
 
553
  xml_reader_read (reader);
 
554
 
 
555
  do
 
556
    {
 
557
      const gchar *element_name;
 
558
 
 
559
      element_name = xml_reader_get_local_name (reader);
 
560
 
 
561
      if (ide_str_equal0 (element_name, "name") ||
 
562
          ide_str_equal0 (element_name, "shortdesc") ||
 
563
          ide_str_equal0 (element_name, "description"))
 
564
        {
 
565
          gchar *str;
 
566
 
 
567
          str = xml_reader_read_string (reader);
 
568
          if (str != NULL)
 
569
            g_object_set (self, element_name, g_strstrip (str), NULL);
 
570
          g_free (str);
 
571
        }
 
572
      else if (ide_str_equal0 (element_name, "category") ||
 
573
               ide_str_equal0 (element_name, "homepage") ||
 
574
               ide_str_equal0 (element_name, "download-page") ||
 
575
               ide_str_equal0 (element_name, "bug-database"))
 
576
        {
 
577
          gchar *str;
 
578
 
 
579
          str = xml_reader_get_attribute (reader, "rdf:resource");
 
580
          if (str != NULL)
 
581
            g_object_set (self, element_name, g_strstrip (str), NULL);
 
582
          g_free (str);
 
583
        }
 
584
      else if (ide_str_equal0 (element_name, "programming-language"))
 
585
        {
 
586
          gchar *str;
 
587
 
 
588
          str = xml_reader_read_string (reader);
 
589
          if (!ide_str_empty0 (str))
 
590
            ide_doap_add_language (self, g_strstrip (str));
 
591
          g_free (str);
 
592
        }
 
593
      else if (ide_str_equal0 (element_name, "maintainer"))
 
594
        {
 
595
          if (!ide_doap_parse_maintainer (self, reader))
 
596
            break;
 
597
        }
 
598
    }
 
599
  while (xml_reader_read_to_next (reader));
 
600
 
 
601
  g_object_thaw_notify (G_OBJECT (self));
 
602
 
 
603
  return TRUE;
 
604
}