@@ -5,6 +5,8 @@ define(["underscore", "backbone", "models/metadata/eml211/EMLAnnotation"], (
5
5
Backbone ,
6
6
EMLAnnotation ,
7
7
) => {
8
+ const SCHEMA_ORG_SAME_AS = "http://www.w3.org/2002/07/owl#sameAs" ;
9
+ const PROV_WAS_DERIVED_FROM = "http://www.w3.org/ns/prov#wasDerivedFrom" ;
8
10
/**
9
11
* @class EMLAnnotations
10
12
* @classdesc A collection of EMLAnnotations.
@@ -56,6 +58,135 @@ define(["underscore", "backbone", "models/metadata/eml211/EMLAnnotation"], (
56
58
}
57
59
this . add ( annotation ) ;
58
60
} ,
61
+
62
+ /**
63
+ * Find all annotations with the given propertyURI.
64
+ * @param {string } propertyURI The propertyURI to search for.
65
+ * @returns {EMLAnnotation[] } An array of EMLAnnotations with the given
66
+ * propertyURI.
67
+ * @since 0.0.0
68
+ */
69
+ findByProperty ( propertyURI ) {
70
+ return this . where ( { propertyURI } ) ;
71
+ } ,
72
+
73
+ /**
74
+ * Adds canonical dataset annotations to this collection. A canonical
75
+ * dataset is the one that is considered the authoritative version; the
76
+ * current EML doc being essentially a duplicate version.
77
+ * @param {string } sourceId The DOI or URL of the canonical dataset.
78
+ * @returns {void }
79
+ * @since 0.0.0
80
+ */
81
+ addCanonicalDatasetAnnotation ( sourceId ) {
82
+ if ( ! sourceId ) return null ;
83
+ // TODO: Check that sourceId is a valid DOI or URL
84
+
85
+ // TODO: Check that there is not already a canonical dataset annotation
86
+ // before adding a new one, since there should only be one.
87
+ return this . add ( [
88
+ {
89
+ propertyLabel : "derivedFrom" ,
90
+ propertyURI : PROV_WAS_DERIVED_FROM ,
91
+ valueLabel : sourceId ,
92
+ valueURI : sourceId ,
93
+ } ,
94
+ {
95
+ propertyLabel : "sameAs" ,
96
+ propertyURI : SCHEMA_ORG_SAME_AS ,
97
+ valueLabel : sourceId ,
98
+ valueURI : sourceId ,
99
+ } ,
100
+ ] ) ;
101
+ } ,
102
+
103
+ /**
104
+ * Find the annotations that make up the canonical dataset annotation. A
105
+ * canonical dataset is identified by having both a "derivedFrom" and a
106
+ * "sameAs" annotation with the same DOI or URL for the valueURI.
107
+ * @returns {object } An object with the derivedFrom and sameAs
108
+ * annotations.
109
+ * @since 0.0.0
110
+ */
111
+ findCanonicalDatasetAnnotation ( ) {
112
+ // There must be at least one derivedFrom and one sameAs annotation
113
+ // for this to have a canonical dataset annotation
114
+ if ( ! this . length ) return null ;
115
+ const derivedFrom = this . findByProperty ( PROV_WAS_DERIVED_FROM ) ;
116
+ if ( ! derivedFrom ?. length ) return null ;
117
+ const sameAs = this . findByProperty ( SCHEMA_ORG_SAME_AS ) ;
118
+ if ( ! sameAs ?. length ) return null ;
119
+
120
+ // Find all pairs that have matching valueURIs
121
+ const pairs = [ ] ;
122
+ derivedFrom . forEach ( ( derived ) => {
123
+ sameAs . forEach ( ( same ) => {
124
+ if ( derived . get ( "valueURI" ) === same . get ( "valueURI" ) ) {
125
+ // TODO? Check that the URI is a valid DOI or URL
126
+ pairs . push ( { derived, same, uri : derived . get ( "valueURI" ) } ) ;
127
+ }
128
+ } ) ;
129
+ } ) ;
130
+
131
+ // If there are multiple pairs, we cannot determine which is the
132
+ // canonical dataset.
133
+ if ( pairs . length > 1 || ! pairs . length ) return null ;
134
+
135
+ // There is only one pair, so return it
136
+ return pairs [ 0 ] ;
137
+ } ,
138
+
139
+ /**
140
+ * Updates the canonical dataset annotations to have the given ID. If
141
+ * there is no canonical dataset annotation, one is added. If the ID is a
142
+ * falsy value, the canonical dataset annotation is removed.
143
+ * @param {string } newSourceId The DOI or URL of the canonical dataset.
144
+ * @returns {object } An object with the derivedFrom and sameAs annotations
145
+ * if the canonical dataset annotations were updated.
146
+ * @since 0.0.0
147
+ */
148
+ updateCanonicalDataset ( newSourceId ) {
149
+ if ( ! newSourceId ) {
150
+ this . removeCanonicalDatasetAnnotation ( ) ;
151
+ return null ;
152
+ }
153
+ const canonical = this . findCanonicalDatasetAnnotation ( ) ;
154
+ if ( ! canonical ) {
155
+ return this . addCanonicalDatasetAnnotation ( newSourceId ) ;
156
+ }
157
+
158
+ const { derived, same, uri } = canonical ;
159
+ if ( uri === newSourceId ) return null ;
160
+
161
+ derived . set ( "valueURI" , newSourceId ) ;
162
+ derived . set ( "valueLabel" , newSourceId ) ;
163
+ same . set ( "valueURI" , newSourceId ) ;
164
+ same . set ( "valueLabel" , newSourceId ) ;
165
+
166
+ return [ derived , same ] ;
167
+ } ,
168
+
169
+ /**
170
+ * Removes the canonical dataset annotations from this collection.
171
+ * @returns {EMLAnnotation[] } The canonical dataset annotations that were
172
+ * removed.
173
+ * @since 0.0.0
174
+ */
175
+ removeCanonicalDatasetAnnotation ( ) {
176
+ const canonical = this . findCanonicalDatasetAnnotation ( ) ;
177
+ if ( ! canonical ) return null ;
178
+ return this . remove ( [ canonical . derived , canonical . same ] ) ;
179
+ } ,
180
+
181
+ /**
182
+ * Returns the URI of the canonical dataset.
183
+ * @returns {string } The URI of the canonical dataset.
184
+ * @since 0.0.0
185
+ */
186
+ getCanonicalURI ( ) {
187
+ const canonical = this . findCanonicalDatasetAnnotation ( ) ;
188
+ return canonical ?. uri ;
189
+ } ,
59
190
} ,
60
191
) ;
61
192
0 commit comments