7
7
"models/metadata/eml211/EMLEntity" ,
8
8
"models/metadata/eml211/EMLDataTable" ,
9
9
"models/metadata/eml211/EMLOtherEntity" ,
10
- ] , ( Backbone , EMLEntity , EMLDataTable , EMLOtherEntity ) => {
10
+ "models/DataONEObject" ,
11
+ ] , ( Backbone , EMLEntity , EMLDataTable , EMLOtherEntity , DataONEObject ) => {
11
12
// The names of the nodes that are considered entities in EML
12
13
const ENTITY_NODE_NAMES = [
13
14
"otherEntity" ,
@@ -378,8 +379,14 @@ define([
378
379
* thrown if any attributes from the source entity are invalid. If set to
379
380
* false, only valid attributes will be copied over, and invalid
380
381
* attributes will be ignored.
382
+ * @param {boolean } [byRef] - If true, the attributes will be copied as a
383
+ * reference to the source attributes. Meaning that changes to the source
384
+ * attributes will affect the target attributes. If false (default), the
385
+ * attributes will have the same values as the source attributes, but will
386
+ * be a deep copy. This means that changes to the source attributes will
387
+ * not affect the target attributes.
381
388
*/
382
- copyAttributeList ( source , targets , errorIfInvalid = true ) {
389
+ copyAttributeList ( source , targets , errorIfInvalid = true , byRef = false ) {
383
390
if ( ! source || ! targets ) return ;
384
391
385
392
const sourceAttrs = source . get ( "attributeList" ) ;
@@ -397,26 +404,64 @@ define([
397
404
errors . join ? errors . join ( "\n" ) : "Invalid attribute list" ,
398
405
) ;
399
406
}
400
- const attrsStr = source . get ( "attributeList" ) . serialize ( ) ;
407
+
401
408
targets . forEach ( ( target ) => {
402
- const attrList = target . get ( "attributeList" ) ;
403
- const emlAttrs = attrList . get ( "emlAttributes" ) ;
404
- // Use remove rather than reset to trigger events
405
- emlAttrs . remove ( emlAttrs . models ) ;
406
- const attrDOM = new DOMParser ( ) . parseFromString ( attrsStr , "text/xml" ) ;
407
- emlAttrs . add ( attrDOM , { parse : true } ) ;
408
- // remove xmlID from the target attributes
409
- emlAttrs . each ( ( attr ) => attr . unset ( "xmlID" ) ) ;
410
- // Reference to entity model required for attr & sub-models
411
- emlAttrs . each ( ( attr ) => attr . set ( "parentModel" , target ) ) ;
412
-
413
- // Invalid to have both attributes and references
414
- if ( attrList . hasReferences ( ) ) {
415
- attrList . removeReferences ( ) ;
409
+ if ( ! target ) return ;
410
+ if ( byRef ) {
411
+ this . copyAttributeListByRef ( source , target ) ;
412
+ } else {
413
+ this . deepCopyAttributeList ( source , target ) ;
416
414
}
417
415
} ) ;
418
416
} ,
419
417
418
+ /**
419
+ * Copy the attribute list from a source entity to a target entity by
420
+ * reference. This means that changes to the source will be reflected in
421
+ * the target.
422
+ * @param {EMLEntity } source - The entity to copy attributes from
423
+ * @param {EMLEntity } target - The entity to copy attributes to
424
+ */
425
+ copyAttributeListByRef ( source , target ) {
426
+ const sourceAttrList = source . get ( "attributeList" ) ;
427
+ let sourceId = sourceAttrList . get ( "xmlID" ) ;
428
+
429
+ if ( ! sourceId ) {
430
+ sourceId = DataONEObject . generateId ( ) ;
431
+ sourceAttrList . set ( "xmlID" , sourceId ) ;
432
+ }
433
+
434
+ // empty the target attribute list
435
+ const targetAttrList = target . get ( "attributeList" ) ;
436
+ targetAttrList . setReferences ( sourceId ) ;
437
+ } ,
438
+
439
+ /**
440
+ * Deep copy the attribute list from a source entity to a target entity.
441
+ * This means that changes to the source will not be reflected in the
442
+ * target.
443
+ * @param {EMLEntity } source - The entity to copy attributes from
444
+ * @param {EMLEntity } target - The entity to copy attributes to
445
+ */
446
+ deepCopyAttributeList ( source , target ) {
447
+ const attrsStr = source . get ( "attributeList" ) . serialize ( ) ;
448
+ const attrList = target . get ( "attributeList" ) ;
449
+ const emlAttrs = attrList . get ( "emlAttributes" ) ;
450
+ // Use remove rather than reset to trigger events
451
+ emlAttrs . remove ( emlAttrs . models ) ;
452
+ const attrDOM = new DOMParser ( ) . parseFromString ( attrsStr , "text/xml" ) ;
453
+ emlAttrs . add ( attrDOM , { parse : true } ) ;
454
+ // remove xmlID from the target attributes
455
+ emlAttrs . each ( ( attr ) => attr . unset ( "xmlID" ) ) ;
456
+ // Reference to entity model required for attr & sub-models
457
+ emlAttrs . each ( ( attr ) => attr . set ( "parentModel" , target ) ) ;
458
+
459
+ // Invalid to have both attributes and references
460
+ if ( attrList . hasReferences ( ) ) {
461
+ attrList . removeReferences ( ) ;
462
+ }
463
+ } ,
464
+
420
465
/**
421
466
* Get the attribute lists of all entities in the collection.
422
467
* @returns {EMLAttributeList[] } The attribute lists of all entities in the
0 commit comments