Skip to content

Commit

Permalink
Move/consolidate DOI methods to AppModel
Browse files Browse the repository at this point in the history
- CitationModel, DataONEObject, SolrResult, and MetadataView previously all used very similar DOI methods
- These methods have been moved to the appModel, the other views/models call those
- Also added getCanonicalDOIIRI to DataONEObject

Relates to #1380
  • Loading branch information
robyngit committed Jul 31, 2023
1 parent 44d2aab commit f8ab572
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 101 deletions.
70 changes: 70 additions & 0 deletions src/js/models/AppModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,76 @@ define(['jquery', 'underscore', 'backbone'],
this.set("description", this.defaults.description);
},

/**
* Remove all DOI prefixes from a DOI string, including https, http, doi.org,
* dx.doi.org, and doi:.
* @param {string} str - The DOI string to remove prefixes from.
* @returns {string} - The DOI string without any prefixes.
* @since x.x.x
*/
removeAllDOIPrefixes: function (str) {
if (!str) return "";
// Remove https and http prefixes
str = str.replace(/^(https?:\/\/)?/, "");
// Remove domain prefixes, like doi.org and dx.doi.org
str = str.replace(/^(doi\.org\/|dx\.doi\.org\/)/, "");
// Remove doi: prefix
str = str.replace(/^doi:/, "");
return str;
},

/**
* Check if a string is a valid DOI.
* @param {string} doi - The string to check.
* @returns {boolean} - True if the string is a valid DOI, false otherwise.
* @since x.x.x
*/
isDOI: function (str) {
try {
if (!str) return false;
str = this.removeAllDOIPrefixes(str);
const doiRegex = /^10\.[0-9]{4,}(?:[.][0-9]+)*\/[^\s"<>]+$/;
return doiRegex.test(str);
} catch (e) {
console.error("Error checking if string is a DOI", e);
return false;
}
},

/**
* Get the URL for the online location of the object being cited when it
* has a DOI. If the DOI is not passed to the function, or if the string
* is not a DOI, then an empty string is returned.
* @param {string} str - The DOI string, handles both DOI and DOI URL,
* with or without prefixes
* @returns {string} - The DOI URL
* @since 2.23.0
*/
DOItoURL: function (str) {
if (!str) return "";
str = this.removeAllDOIPrefixes(str);
if (!this.isDOI(str)) return "";
return "https://doi.org/" + str;
},

/**
* Get the DOI from a DOI URL. The URL can be http or https, can include the
* "doi:" prefix or not, and can use "dx.doi.org" or "doi.org" as the
* domain. If a string is not passed to the function, or if the string is
* not for a DOI URL, then an empty string is returned.
* @param {string} url - The DOI URL
* @returns {string} - The DOI string, including the "doi:" prefix
* @since x.x.x
*/
URLtoDOI: function (url) {
if (!url) return "";
const doiURLRegex =
/https?:\/\/(dx\.)?doi\.org\/(doi:)?(10\.[0-9]{4,}(?:[.][0-9]+)*\/[^\s"<>]+)/;
const doiURLMatch = url.match(doiURLRegex);
if (doiURLMatch) return "doi:" + doiURLMatch[3];
return "";
},

});
return AppModel;
});
22 changes: 3 additions & 19 deletions src/js/models/CitationModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -977,15 +977,7 @@ define(["jquery", "underscore", "backbone", "collections/Citations"], function (
* @since 2.23.0
*/
isDOI: function (str) {
try {
if (!str) return false;
str = this.removeAllDOIPrefixes(str);
const doiRegex = /^10\.[0-9]{4,}(?:[.][0-9]+)*\/[^\s"<>]+$/;
return doiRegex.test(str);
} catch (e) {
console.error("Error checking if string is a DOI", e);
return false;
}
return MetacatUI.appModel.isDOI(str);
},

/**
Expand All @@ -999,10 +991,7 @@ define(["jquery", "underscore", "backbone", "collections/Citations"], function (
* @since 2.23.0
*/
DOItoURL: function (str) {
if (!str) return "";
str = this.removeAllDOIPrefixes(str);
if (!this.isDOI(str)) return "";
return "https://doi.org/" + str;
return MetacatUI.appModel.DOItoURL(str);
},

/**
Expand All @@ -1015,12 +1004,7 @@ define(["jquery", "underscore", "backbone", "collections/Citations"], function (
* @since 2.23.0
*/
URLtoDOI: function (url) {
if (!url) return "";
const doiURLRegex =
/https?:\/\/(dx\.)?doi\.org\/(doi:)?(10\.[0-9]{4,}(?:[.][0-9]+)*\/[^\s"<>]+)/;
const doiURLMatch = url.match(doiURLRegex);
if (doiURLMatch) return "doi:" + doiURLMatch[3];
return "";
return MetacatUI.appModel.URLtoDOI(url);
},

/**
Expand Down
57 changes: 20 additions & 37 deletions src/js/models/DataONEObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -1814,6 +1814,22 @@ define(['jquery', 'underscore', 'backbone', 'uuid', 'he', 'collections/AccessPol
createViewURL: function(){
return MetacatUI.root + "/view/" + encodeURIComponent((this.get("seriesId") || this.get("id")));
},

/**
* Check if the seriesID or PID matches a DOI regex, and if so, return
* a canonical IRI for the DOI.
* @return {string|null} - The canonical IRI for the DOI, or null if
* neither the seriesId nor the PID match a DOI regex.
* @since x.x.x
*/
getCanonicalDOIIRI: function () {
const id = this.get("id");
const seriesId = this.get("seriesId");
let DOI = null;
if (this.isDOI(seriesId)) DOI = seriesId;
else if (this.isDOI(id)) DOI = id;
return MetacatUI.appModel.DOItoURL(DOI);
},

/**
* Converts the identifier string to a string safe to use in an XML id attribute
Expand Down Expand Up @@ -2132,43 +2148,10 @@ define(['jquery', 'underscore', 'backbone', 'uuid', 'he', 'collections/AccessPol
* @returns {boolean} True if it is a DOI
*/
isDOI: function(customString) {
var DOI_PREFIXES = ["doi:10.", "http://dx.doi.org/10.", "http://doi.org/10.", "http://doi.org/doi:10.",
"https://dx.doi.org/10.", "https://doi.org/10.", "https://doi.org/doi:10."],
DOI_REGEX = new RegExp(/^10.\d{4,9}\/[-._;()/:A-Z0-9]+$/i);;

//If a custom string is given, then check that instead of the seriesId and id from the model
if( typeof customString == "string" ){
for (var i=0; i < DOI_PREFIXES.length; i++) {
if (customString.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
}

//If there is no DOI prefix, check for a DOI without the prefix using a regular expression
if( DOI_REGEX.test(customString) ){
return true;
}

}
else{
var seriesId = this.get("seriesId"),
pid = this.get("id");

for (var i=0; i < DOI_PREFIXES.length; i++) {
if (seriesId && seriesId.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
else if (pid && pid.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
}

//If there is no DOI prefix, check for a DOI without the prefix using a regular expression
if( DOI_REGEX.test(seriesId) || DOI_REGEX.test(pid) ){
return true;
}

}

return false;
},
return isDOI(customString) ||
isDOI(this.get("id")) ||
isDOI(this.get("seriesId"));
},

/**
* Creates an array of objects that represent Member Nodes that could possibly be this
Expand Down
41 changes: 4 additions & 37 deletions src/js/models/SolrResult.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,43 +208,10 @@ define(['jquery', 'underscore', 'backbone'],
* @param {string} customString - Optional. An identifier string to check instead of the id and seriesId attributes on the model
* @returns {boolean} True if it is a DOI
*/
isDOI: function(customString) {
var DOI_PREFIXES = ["doi:10.", "http://dx.doi.org/10.", "http://doi.org/10.", "http://doi.org/doi:10.",
"https://dx.doi.org/10.", "https://doi.org/10.", "https://doi.org/doi:10."],
DOI_REGEX = new RegExp(/^10.\d{4,9}\/[-._;()/:A-Z0-9]+$/i);;

//If a custom string is given, then check that instead of the seriesId and id from the model
if( typeof customString == "string" ){
for (var i=0; i < DOI_PREFIXES.length; i++) {
if (customString.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
}

//If there is no DOI prefix, check for a DOI without the prefix using a regular expression
if( DOI_REGEX.test(customString) ){
return true;
}

}
else{
var seriesId = this.get("seriesId"),
pid = this.get("id");

for (var i=0; i < DOI_PREFIXES.length; i++) {
if (seriesId && seriesId.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
else if (pid && pid.toLowerCase().indexOf(DOI_PREFIXES[i].toLowerCase()) == 0 )
return true;
}

//If there is no DOI prefix, check for a DOI without the prefix using a regular expression
if( DOI_REGEX.test(seriesId) || DOI_REGEX.test(pid) ){
return true;
}

}

return false;
isDOI: function (customString) {
return MetacatUI.appModel.isDOI(customString) ||
MetacatUI.appModel.isDOI(this.get("id")) ||
MetacatUI.appModel.isDOI(this.get("seriesId"));
},

/*
Expand Down
10 changes: 2 additions & 8 deletions src/js/views/MetadataView.js
Original file line number Diff line number Diff line change
Expand Up @@ -2905,15 +2905,9 @@ define(['jquery',
* Note: Really could be generalized to more identifier schemes.
*/
getCanonicalDOIIRI: function (identifier) {
var pattern = /(10\.\d{4,9}\/[-\._;()\/:A-Z0-9]+)$/,
match = identifier.match(pattern);

if (match === null || match.length !== 2 || match[1].length <= 0) {
return null;
}

return "https://doi.org/" + match[1];
return MetacatUI.appModel.DOItoURL(identifier) || null;
},

/**
* Insert citation information as meta tags into the head of the page
*
Expand Down

0 comments on commit f8ab572

Please sign in to comment.