Completed
Push — master ( f67f14...be7dea )
by Koen
01:29
created

AppUi.js ➔ ... ➔ declare._saveConceptScheme   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
/**
2
 * Main application user interface.
3
 */
4
define([
5
  'dojo/_base/declare',
6
  'dojo/_base/lang',
7
  'dojo/_base/fx',
8
  'dojo/_base/array',
9
  'dojo/dom-style',
10
  'dojo/topic',
11
  'dojo/on',
12
  'dojo/window',
13
  'dojo/router',
14
  'dojo/query',
15
  'dijit/_WidgetBase',
16
  'dijit/_TemplatedMixin',
17
  'dijit/ConfirmDialog',
18
  'dojo/text!./templates/AppUi.html',
19
  'dojo/text!./templates/Help.html',
20
  'dijit/layout/ContentPane',
21
  'dijit/layout/TabContainer',
22
  'dijit/layout/LayoutContainer',
23
  '../utils/DomUtils',
24
  './widgets/SearchPane',
25
  './widgets/ConceptDetail',
26
  './widgets/SlideMenu',
27
  './dialogs/ManageConceptDialog',
28
  './dialogs/ManageLanguagesDialog',
29
  './dialogs/ImportConceptDialog',
30
  './dialogs/MergeConceptDialog',
31
  './dialogs/ManageSchemeDialog',
32
  '../utils/ErrorUtils',
33
  'dojo/NodeList-manipulate'
34
], function (
35
  declare,
36
  lang,
37
  fx,
38
  array,
39
  domStyle,
40
  topic,
41
  on,
42
  wind,
43
  router,
44
  query,
45
  _WidgetBase,
46
  _TemplatedMixin,
47
  ConfirmDialog,
48
  template,
49
  helpTemplate,
50
  ContentPane,
51
  TabContainer,
52
  LayoutContainer,
53
  domUtils,
54
  SearchPane,
55
  ConceptDetail,
56
  SlideMenu,
57
  ManageConceptDialog,
58
  ManageLanguagesDialog,
59
  ImportConceptDialog,
60
  MergeConceptDialog,
61
  ManageSchemeDialog,
62
  errorUtils
63
) {
64
  return declare([_WidgetBase, _TemplatedMixin], {
65
66
    templateString: template,
67
    loadingContainer: null,
68
    staticAppPath: null,
69
    conceptSchemeController: null,
70
    conceptController: null,
71
    languageController: null,
72
    listController: null,
73
    _searchPane: null,
74
    _conceptContainer: null,
75
    _slideMenu: null,
76
    _manageConceptDialog: null,
77
    _manageLanguagesDialog: null,
78
    _importConceptDialog: null,
79
    _mergeConceptDialog: null,
80
    _selectedSchemeId: null,
81
82
    /**
83
     * Standard widget function.
84
     * @public
85
     */
86
    postCreate: function () {
87
      this.inherited(arguments);
88
      console.debug('AppUi::postCreate');
89
      this._registerLoadingEvents();
90
      this._registerRoutes();
91
      this._createSlideMenu(this.menuContainerNode);
92
93
      this._manageConceptDialog = new ManageConceptDialog({
94
        parent: this,
95
        languageController: this.languageController,
96
        listController: this.listController,
97
        conceptSchemeController: this.conceptSchemeController
98
      });
99
      on(this._manageConceptDialog, 'new.concept.save', lang.hitch(this, function(evt) {
100
        this._saveNewConcept(this._manageConceptDialog, evt.concept, evt.schemeId);
101
      }));
102
      on(this._manageConceptDialog, 'concept.save', lang.hitch(this, function(evt) {
103
        this._saveConcept(this._manageConceptDialog, evt.concept, evt.schemeId);
104
      }));
105
      this._manageConceptDialog.startup();
106
107
      this._manageLanguagesDialog = new ManageLanguagesDialog({
108
        parentNode: this,
109
        languageController: this.languageController
110
      });
111
      this._manageLanguagesDialog.startup();
112
113
      this._importConceptDialog = new ImportConceptDialog({
114
        externalSchemeStore: this.conceptSchemeController.getExternalSchemeStore(),
115
        conceptSchemeController: this.conceptSchemeController
116
      });
117
      this._importConceptDialog.startup();
118
      on(this._importConceptDialog, 'concept.import', lang.hitch(this, function(evt) {
119
        this._createImportConcept(evt.schemeId, evt.concept);
120
      }));
121
122
      this._mergeConceptDialog = new MergeConceptDialog({
123
        conceptSchemeController: this.conceptSchemeController
124
      });
125
      this._mergeConceptDialog.startup();
126
      on(this._mergeConceptDialog, 'concept.merge', lang.hitch(this, function(evt) {
127
        this._createMergeConcept(evt.conceptUri, evt.concept, evt.schemeId);
128
      }));
129
130
      this._manageSchemeDialog = new ManageSchemeDialog({
131
        parent: this,
132
        languageController: this.languageController,
133
        listController: this.listController,
134
        conceptSchemeController: this.conceptSchemeController
135
      });
136
      this._manageSchemeDialog.startup();
137
      on(this._manageSchemeDialog, 'scheme.save', lang.hitch(this, function(evt) {
138
        this._saveConceptScheme(this._manageSchemeDialog, evt.scheme);
139
      }));
140
141
      on(window, 'resize', lang.hitch(this, function() { this._calculateHeight() }));
142
    },
143
144
    /**
145
     * Standard widget function.
146
     * @public
147
     */
148
    startup: function () {
149
      this.inherited(arguments);
150
      console.debug('AppUi::startup');
151
152
      var ui = this._buildInterface();
153
      ui.startup();
154
      this._searchPane.startup();
155
      this._slideMenu._slideOpen();
156
      this._hideLoading();
157
158
      router.startup('#');
159
    },
160
161
    /**
162
     * Hide the 'Loading'-overlay.
163
     * @public
164
     */
165
    _hideLoading: function () {
166
      var node = this.loadingContainer;
167
      fx.fadeOut({
168
        node: node,
169
        onEnd: function (node) {
170
          domStyle.set(node, 'display', 'none');
171
        },
172
        duration: 1000
173
      }).play();
174
    },
175
176
    /**
177
     * Show the 'Loading'-overlay.
178
     * @public
179
     */
180
    _showLoading: function (message) {
181
      if (!message) message = "";
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
182
      var node = this.loadingContainer;
183
      query(".loadingMessage", node).innerHTML(message);
184
185
      domStyle.set(node, 'display', 'block');
186
      fx.fadeIn({
187
        node: node,
188
        duration: 1
189
      }).play();
190
    },
191
192
    _buildInterface: function () {
193
      console.debug('AppUi::createView');
194
195
      this._calculateHeight();
196
      //main layout container
197
      var appContainer = new LayoutContainer({
198
        design: 'headline',
199
        id: 'appContainer'
200
      }, this.conceptContainerNode);
201
202
      //body of main layout
203
      this._container = new TabContainer({
204
        tabPosition: 'bottom',
205
        splitter: true
206
      });
207
208
      appContainer.addChild(new ContentPane({
209
        content: this._container,
210
        region: 'center',
211
        baseClass: 'appBody'
212
      }));
213
      this._createHelpTab(this._container);
214
215
      appContainer.startup();
216
      return appContainer;
217
    },
218
219
    _createHelpTab: function (tabContainer) {
220
      console.debug('AppUi::_createHelpTab');
221
      tabContainer.addChild(new ContentPane({
222
        tabId: 'help',
223
        title: 'Info',
224
        content: helpTemplate,
225
        closable: false
226
      }));
227
    },
228
229
    /**
230
     * Listen to events to show/hide the loading overlay
231
     * @private
232
     */
233
    _registerLoadingEvents: function () {
234
      this.own(
235
        topic.subscribe('standby.show',lang.hitch(this, function(evt){
236
          this._showLoading(evt.message);
237
        })),
238
        topic.subscribe('standby.stop',lang.hitch(this, function(){
239
          this._hideLoading();
240
        }))
241
      );
242
    },
243
244
    _registerRoutes: function () {
245
246
      router.register('/conceptschemes/:scheme/c/:id', lang.hitch(this, function(evt){
247
        if (!evt.params.id || !evt.params.scheme) { return; }
248
        this._openConcept(evt.params.id, evt.params.scheme);
249
        this._closeMenu();
250
        router.go('#');
251
      }));
252
253
      // TODO add route for conceptscheme
254
    },
255
256
257
    _createConcept: function(evt) {
258
      evt ? evt.preventDefault() : null;
259
      console.debug('AppUi::_createConcept');
260
261
      this._manageConceptDialog.showDialog(this._selectedSchemeId, null,  'add');
262
    },
263
264
    _createAddSubordinateArrayConcept: function(concept, schemeId) {
265
      var newConcept = {
266
        superordinates: [],
267
        type: 'collection'
268
      };
269
      newConcept.superordinates.push(concept);
270
      this._manageConceptDialog.showDialog(schemeId, newConcept, 'add');
271
    },
272
273
    _createAddNarrowerConcept: function(concept, schemeId) {
274
      var newConcept = {
275
        broader: [],
276
        type: 'concept'
277
      };
278
      newConcept.broader.push(concept);
279
      this._manageConceptDialog.showDialog(schemeId, newConcept, 'add');
280
    },
281
282
    _createAddMemberConcept: function(concept, schemeId) {
283
      var newConcept = {
284
        member_of: [],
285
        type: 'concept'
286
      };
287
      newConcept.member_of.push(concept);
288
      this._manageConceptDialog.showDialog(schemeId, newConcept, 'add');
289
    },
290
291
    _createImportConcept: function(schemeId, concept) {
292
      this.conceptSchemeController.getConcept(schemeId, concept.uri).then(lang.hitch(this, function(result) {
293
        var newConcept = result;
294
        this._manageConceptDialog.showDialog(this._selectedSchemeId, newConcept, 'add');
295
      }));
296
    },
297
298
    _createMergeConcept: function(conceptUri, concept, schemeId) {
299
      this._showLoading('Merging concepts..');
300
      this.conceptSchemeController.getMergeMatch(conceptUri).then(lang.hitch(this, function (match) {
301
        var labelsToMerge = match.labels;
302
        var notesToMerge = match.notes;
303
        concept.labels = this._mergeLabels(concept.labels, labelsToMerge);
304
        concept.notes = this._mergeNotes(concept.notes, notesToMerge);
305
306
        this._manageConceptDialog.showDialog(schemeId, concept, 'edit');
307
      }), function (err) {
308
        topic.publish('dGrowl', err, {'title': "Error when looking up match", 'sticky': true, 'channel':'error'});
309
      }).always(lang.hitch(this, function() {
310
        this._hideLoading();
311
      }));
312
    },
313
314
    _importConcept  : function(evt) {
315
      evt.preventDefault();
316
      console.debug('AppUi::_importConcept');
317
      this._importConceptDialog.show();
318
    },
319
320
    _editLanguages: function (evt) {
321
      evt.preventDefault();
322
      console.debug('AppUi::_editLanguages');
323
      this._manageLanguagesDialog.show();
324
    },
325
326
    _editConceptScheme: function (evt) {
327
      evt.preventDefault();
328
      this._showLoading('Loading concept scheme..')
329
      // retrieve scheme and open dialog
330
      this.conceptSchemeController.getConceptScheme(this._selectedSchemeId).then(lang.hitch(this,
331
        function(schemeResult) {
332
          console.debug('AppUi::_editConceptScheme', schemeResult);
333
          this._manageSchemeDialog.showDialog(schemeResult, 'edit');
334
        }
335
      ), function (err) {
336
        console.log(err);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
337
        //todo dgrowl
338
      }).always(lang.hitch(this, function() {
339
        this._hideLoading();
340
      }));
341
    },
342
343
    _createSlideMenu: function(node) {
344
      this._slideMenu = new SlideMenu({
345
        overlayContainer: this.menuOverlayContainer
346
      }, node);
347
      this._slideMenu.startup();
348
      this._createSearchPane(this._slideMenu.menuNode);
349
    },
350
351
    _closeMenu: function(evt) {
352
      evt ? evt.preventDefault() : null;
353
      this._slideMenu._slideClose();
354
    },
355
356
    _toggleMenu: function(evt) {
357
      evt ? evt.preventDefault() : null;
358
      this._slideMenu._toggleMenu();
359
    },
360
361
    _openConcept: function(conceptId, scheme) {
362
      if (this._getTab(scheme + '_' + conceptId)) {
363
        this._openTab(this._getTab(scheme + '_' + conceptId));
364
        return;
365
      }
366
      this._showLoading('Loading concept..');
367
      this.conceptController.getConcept(scheme, conceptId).then(
368
        lang.hitch(this, function (data) {
369
          var conceptDetail = new ConceptDetail({
370
            concept: data,
371
            conceptId: conceptId,
372
            conceptLabel: data.label,
373
            scheme: scheme,
374
            languageController: this.languageController,
375
            listController: this.listController,
376
            conceptSchemeController: this.conceptSchemeController
377
          });
378
          on(conceptDetail, 'concept.save', lang.hitch(this, function(evt) {
379
            this._saveConcept(conceptDetail, evt.concept, evt.schemeId);
380
          }));
381
          on(conceptDetail, 'concept.delete', lang.hitch(this, function(evt) {
382
            this._deleteConcept(conceptDetail, evt.concept, evt.schemeId);
383
          }));
384
          on(conceptDetail, 'concept.edit', lang.hitch(this, function(evt) {
385
            this._editConcept(conceptDetail, evt.concept, evt.schemeId);
386
          }))
387
          on(conceptDetail, 'concept.merge', lang.hitch(this, function(evt) {
388
            this._mergeConcept(conceptDetail, evt.concept, evt.schemeId);
389
          }))
390
          conceptDetail.startup();
391
          this._addTab(conceptDetail);
392
        })).always(lang.hitch(this, function() {
393
        this._hideLoading();
394
      }));
395
    },
396
397
    _createSearchPane: function (node) {
398
      this._searchPane = new SearchPane({
399
        conceptSchemeList: this.conceptSchemeController.conceptSchemeList,
400
        appUi: this
401
      }, node);
402
403
      on(this._searchPane, 'row-select', lang.hitch(this, function (evt) {
404
        console.debug('catch select event', evt);
405
        this._openConcept(evt.data.id, evt.scheme);
406
      }));
407
408
      on(this._searchPane, 'scheme.changed', lang.hitch(this, function (evt) {
409
        this._selectedSchemeId = evt.schemeId;
410
      }));
411
412
      on(this._searchPane, 'concept.create', lang.hitch(this, function (evt) {
0 ignored issues
show
Unused Code introduced by
The parameter evt is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
413
        this._createConcept();
414
      }));
415
416
      on(this._searchPane, 'concept.edit', lang.hitch(this, function (evt) {
417
        this.conceptController.getConcept(this._selectedSchemeId, evt.conceptId).then(
418
          lang.hitch(this, function (data) {
419
            this._editConcept(null, data, this._selectedSchemeId);
420
          }));
421
      }));
422
423
      on(this._searchPane, 'concept.delete', lang.hitch(this, function (evt) {
424
        this.conceptController.getConcept(this._selectedSchemeId, evt.conceptId).then(
425
          lang.hitch(this, function (data) {
426
            this._deleteConcept(this._getTab(this._selectedSchemeId + '_' + data.id), data, this._selectedSchemeId);
427
          }));
428
      }));
429
430
      on(this._searchPane, 'concept.addnarrower', lang.hitch(this, function (evt) {
431
        this.conceptController.getConcept(this._selectedSchemeId, evt.conceptId).then(
432
          lang.hitch(this, function (data) {
433
            this._createAddNarrowerConcept(data, this._selectedSchemeId);
434
          }));
435
      }));
436
437
      on(this._searchPane, 'concept.addsubarray', lang.hitch(this, function (evt) {
438
        this.conceptController.getConcept(this._selectedSchemeId, evt.conceptId).then(
439
          lang.hitch(this, function (data) {
440
            this._createAddSubordinateArrayConcept(data, this._selectedSchemeId);
441
          }));
442
      }));
443
444
      on(this._searchPane, 'concept.addmember', lang.hitch(this, function (evt) {
445
        this.conceptController.getConcept(this._selectedSchemeId, evt.conceptId).then(
446
          lang.hitch(this, function (data) {
447
            this._createAddMemberConcept(data, this._selectedSchemeId);
448
          }));
449
      }));
450
    },
451
452
    /* Tab container functions*/
453
    /**
454
     * Opent een tab in de tabcontainer.
455
     * @param {Object} child Tab die wordt geopend
456
     */
457
    _openTab: function(child) {
458
      this._container.selectChild(child);
459
    },
460
461
    /**
462
     * Sluit een tab in de tabcontainer en verwijdert de content uit de DOM.
463
     * @param {Object} child Tab die wordt gesloten
464
     */
465
    _closeTab: function(child) {
466
      console.debug('AppUi::_closeTab ', child.tabId);
467
      this._container.removeChild(child);
468
      child.destroyRecursive();
469
    },
470
471
    /**
472
     * Zoekt een tab en geeft die terug
473
     * @param {string} tabId ID van de tab
474
     * @returns {Contentpane} de gevonden tab of null
475
     * @private
476
     */
477
    _getTab: function(tabId) {
478
      var tabs = array.filter(this._container.getChildren(), function (tab) {
479
        return tab.tabId === tabId;
480
      });
481
482
      if(tabs.length > 0) {
483
        return tabs[0];
484
      }
485
      else {
486
        return null;
487
      }
488
    },
489
490
    /**
491
     * Voegt een nieuwe tab toe in de tabcontainer.
492
     * @param {Object} content Content die wordt toegevoegd in de tab.
493
     */
494
    _addTab: function(content) {
495
      var tab = content;
496
      tab.tabId = content.scheme + '_' + content.conceptId;
497
      tab.title = content.conceptLabel;
498
      tab.closable = true;
499
      tab.onClose = lang.hitch(this, function() {
500
        this._closeTab(tab);
501
      });
502
      this._container.addChild(tab);
503
      this._container.selectChild(tab);
504
    },
505
    /*end tabcontainer*/
506
507
    _calculateHeight: function () {
508
      var win = wind.getBox();
509
      var footerheight = 30;
510
      var headerheight = 60;
511
      domStyle.set(this.appContentContainer, 'height', win.h - footerheight - headerheight + 'px');
512
      if (this._container) {
513
        this._container.resize();
514
      }
515
    },
516
517
    _editConcept: function(view, concept, schemeId) {
518
      console.debug('AppUi::_editConcept');
519
      this._manageConceptDialog.showDialog(schemeId, concept, 'edit');
520
    },
521
522
    _mergeConcept: function(view, concept, schemeId) {
523
      if (concept.matches) {
524
        this._mergeConceptDialog.show(concept, schemeId);
525
      }
526
    },
527
528
    _deleteConcept: function(view, concept, schemeId) {
529
      var content = '<p style="font-size: 15px;">Are you sure you want to remove <strong>'+ concept.label +
530
        '</strong> (ID: ' + concept.id + ') from scheme <strong>' + schemeId + '</strong>?</p>';
531
      var confirmationDialog = new ConfirmDialog({
532
        title: 'Delete concept',
533
        content: content,
534
        baseClass: 'confirm-dialog'
535
      });
536
      query('.dijitButton', confirmationDialog.domNode).addClass('button tiny');
537
      confirmationDialog.closeText.innerHTML = '<i class="fa fa-times"></i>';
538
539
      on(confirmationDialog, 'close', function() {
540
        confirmationDialog.destroy();
541
      });
542
      on(confirmationDialog, 'execute', lang.hitch(this, function () {
543
        this._showLoading('Removing concept..');
544
        this.conceptController.deleteConcept(concept, schemeId).then(
545
          lang.hitch(this, function(result) {
546
            console.debug('delete concept results', result);
547
            if (view) {
548
              this._closeTab(view);
549
            }
550
          }),
551
          lang.hitch(this, function (error) {
552
            console.error('delete concept error', error);
553
            var parsedError = errorUtils.parseError(error);
554
            topic.publish('dGrowl', parsedError.message, {
555
              'title': parsedError.title,
556
              'sticky': true,
557
              'channel': 'error'
558
            });
559
          })
560
        ).always(lang.hitch(this, function() {
561
          this._hideLoading();
562
        }));
563
      }));
564
565
      confirmationDialog.show();
566
    },
567
568
    _saveConcept: function(view, concept, schemeId) {
569
      console.debug('ConceptContainer::_saveConcept', concept);
570
571
      this._showLoading('Saving concept..');
572
      this.conceptController.saveConcept(concept, schemeId, 'PUT').then(lang.hitch(this, function(res) {
573
        // save successful
574
        view._close();
575
        var tab = this._getTab(schemeId + '_' + concept.id);
576
        this._closeTab(tab);
577
        this._openConcept(res.id, schemeId);
578
        topic.publish('dGrowl', 'The concept was successfully saved.', {
579
          'title': 'Save successful',
580
          'sticky': false,
581
          'channel': 'info'
582
        });
583
      }), function(err) {
584
        var parsedError = errorUtils.parseError(err);
585
        topic.publish('dGrowl', parsedError.message, {
586
          'title': parsedError.title,
587
          'sticky': true,
588
          'channel': 'error'
589
        });
590
      }).always(lang.hitch(this, function() {
591
        this._hideLoading();
592
      }));
593
    },
594
595
    _saveNewConcept: function(view, concept, schemeId) {
596
      this._showLoading('Saving concept..');
597
      this.conceptController.saveConcept(concept, schemeId, 'POST').then(lang.hitch(this, function(res) {
598
        // save successful
599
        view._close();
600
        this._openConcept(res.id, schemeId);
601
        topic.publish('dGrowl', 'The concept was successfully saved.', {
602
          'title': 'Save successful',
603
          'sticky': false,
604
          'channel': 'info'
605
        });
606
      }), function(err) {
607
        var parsedError = errorUtils.parseError(err);
608
        topic.publish('dGrowl', parsedError.message, {
609
          'title': parsedError.title,
610
          'sticky': true,
611
          'channel': 'error'
612
        });
613
      }).always(lang.hitch(this, function() {
614
        this._hideLoading();
615
      }));
616
    },
617
618
    _saveConceptScheme: function(view, scheme) {
619
      this._showLoading('Saving concept scheme..');
620
      this.conceptSchemeController.editConceptScheme(scheme).then(lang.hitch(this, function(res) {
0 ignored issues
show
Unused Code introduced by
The parameter res is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
621
        view._close();
622
        topic.publish('dGrowl', 'The concept scheme was successfully saved.', {
623
          'title': 'Save successful',
624
          'sticky': false,
625
          'channel': 'info'
626
        });
627
      }), function(err) {
628
        var parsedError = errorUtils.parseError(err);
629
        topic.publish('dGrowl', parsedError.message, {
630
          'title': parsedError.title,
631
          'sticky': true,
632
          'channel': 'error'
633
        });
634
      }).always(lang.hitch(this, function() {
635
        this._hideLoading();
636
      }));
637
    },
638
639
    _closeEditDialog: function() {
640
      if (this._editDialog) {
641
        this._editDialog._close();
642
        this._editDialog.destroyRecursive();
643
      }
644
    },
645
646
    _mergeLabels: function (currentLabels, labelsToMerge) {
647
      var mergedLabels = currentLabels;
648
      array.forEach(labelsToMerge, function(labelToMerge) {
649
        if (!this._containsLabel(currentLabels, labelToMerge)) {
650
          mergedLabels.push(this._verifyPrefLabel(mergedLabels, labelToMerge));
651
        }
652
      }, this);
653
      return mergedLabels;
654
    },
655
656
    _containsLabel: function (labels, labelToSearch) {
657
      return array.some(labels, function(label) {
658
        return label.label === labelToSearch.label
659
          && label.language === labelToSearch.language
660
          && label.type === labelToSearch.type;
661
      })
662
    },
663
664
    _verifyPrefLabel: function (labels, labelToMerge) {
665
      if (labelToMerge.type === 'prefLabel' && this._containsPrefLabelOfSameLanguage(labels, labelToMerge)) {
666
        labelToMerge.type = 'altLabel';
667
      }
668
      return labelToMerge;
669
    },
670
671
    _containsPrefLabelOfSameLanguage: function (labels, labelToSearch) {
672
      return array.some(labels, function(label) {
673
        return label.type === 'prefLabel'
674
          && label.language === labelToSearch.language;
675
      })
676
    },
677
678
    _mergeNotes: function (currentNotes, notesToMerge) {
679
      var mergedNotes = currentNotes;
680
      array.forEach(notesToMerge, function(noteToMerge) {
681
        if (!this._containsNote(currentNotes, noteToMerge)) {
682
          mergedNotes.push(noteToMerge);
683
        }
684
      }, this);
685
      return mergedNotes;
686
    },
687
688
    _containsNote: function (notes, noteToSearch) {
689
      return array.some(notes, function(note) {
690
        return note.note === noteToSearch.note
691
          && note.language === noteToSearch.language
692
          && note.type === noteToSearch.type;
693
      })
694
    }
695
  });
696
});
697