Skip to content

Commit

Permalink
Fixe major issue where the system metadata of each object in the pack…
Browse files Browse the repository at this point in the history
…age was retrieved when the MetadataView was loaded.

Closes #978
  • Loading branch information
laurenwalker committed Jul 12, 2019
1 parent bfb80de commit c023088
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 81 deletions.
204 changes: 162 additions & 42 deletions src/js/collections/DataPackage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
"use strict";

define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
'collections/SolrResults',
'models/filters/Filter',
'models/DataONEObject', 'models/metadata/ScienceMetadata', 'models/metadata/eml211/EML211'],
function($, _, Backbone, rdf, uuid, md5, DataONEObject, ScienceMetadata, EML211) {
function($, _, Backbone, rdf, uuid, md5, SolrResults, Filter,
DataONEObject, ScienceMetadata, EML211) {

/*
A DataPackage represents a hierarchical collection of
Expand Down Expand Up @@ -57,6 +60,19 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
// The nesting level in a data package hierarchy
nodeLevel: 0,

/**
* @type {SolrResults} - The SolrResults collection associated with this DataPackage.
* This can be used to fetch the package from Solr by passing the 'fromIndex' option
* to fetch().
*/
solrResults: new SolrResults(),

/**
* @type {Filter} - A Filter model that should filter the Solr index for only the
* objects aggregated by this package.
*/
filterModel: null,

//Define the namespaces used in the RDF XML
namespaces: {
RDF: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
Expand Down Expand Up @@ -111,6 +127,17 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
}
this.id = this.packageModel.id;

//Create a Filter for this DataPackage using the id
this.filterModel = new Filter({
fields: ["resourceMap"],
values: [this.id],
matchSubstring: false
});
//If the id is ever changed, update the id in the Filter
this.listenTo(this.packageModel, "change:id", function(){
this.filterModel.set("values", [this.packageModel.get("id")]);
});

this.on("add", this.handleAdd);
this.on("add", this.triggerComplete);
this.on("successSaving", this.updateRelationships);
Expand Down Expand Up @@ -320,14 +347,41 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
}
},

/*
/**
* Overload fetch calls for a DataPackage
*
* @param {Object} [options] - Optional options for this fetch that get sent with the XHR request
* @property {boolean} fetchModels - If false, this fetch will not fetch
* each model in the collection. It will only get the resource map object.
* @property {boolean} fromIndex - If true, the collection will be fetched from Solr rather than
* fetching the system metadata of each model. Useful when you only need to retrieve limited information about
* each package member. Set query-specific parameters on the `solrResults` SolrResults set on this collection.
*/
fetch: function(options) {

//Fetch the system metadata for this resource map
this.packageModel.fetch();

if(typeof options == "object"){

//If the fetchModels property is set to false,
if(options.fetchModels === false){
//Save the property to the Collection itself so it is accessible in other functions
this.fetchModels = false;
//Remove the property from the options Object since we don't want to send it with the XHR
delete options.fetchModels;

this.once("reset", this.triggerComplete);
}
//If the fetchFromIndex property is set to true
else if( options.fromIndex ){

this.fetchFromIndex();
return;

}
}

//Set some custom fetch options
var fetchOptions = _.extend({dataType: "text"}, options);

Expand Down Expand Up @@ -396,16 +450,20 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
//Create a DataONEObject model to represent this collection member and add to the collection
if(!_.contains(this.pluck("id"), memberPID)){

memberModel = this.add(new DataONEObject({
memberModel = new DataONEObject({
id: memberPID,
resourceMap: [this.packageModel.get("id")],
collections: [this]
}), { silent: true });
});

models.push(memberModel);

}
//If the model already exists, add this resource map ID to it's list of resource maps
else{
memberModel = this.get(memberPID);
models.push(memberModel);

var rMaps = memberModel.get("resourceMap");
if(rMaps && Array.isArray(rMaps) && !_.contains(rMaps, this.packageModel.get("id"))) rMaps.push(this.packageModel.get("id"));
else if(rMaps && !Array.isArray(rMaps)) rMaps = [rMaps, this.packageModel.get("id")];
Expand Down Expand Up @@ -444,7 +502,8 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
this.originalIsDocBy[scidataID] = _.uniq([this.originalIsDocBy[scidataID], scimetaID]);

//Find the model in this collection for this data object
var dataObj = this.get(scidataID);
//var dataObj = this.get(scidataID);
var dataObj = _.find(models, function(m){ return m.get("id") == scidataID });

if(dataObj){
//Get the isDocumentedBy field
Expand All @@ -465,54 +524,62 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
memberPIDs = _.difference(memberPIDs, sciMetaPids);
_.each(_.uniq(sciMetaPids), function(id){ memberPIDs.unshift(id); });

//Retrieve the model for each member
_.each(memberPIDs, function(pid){
//Don't fetch each member model if the fetchModels property on this Collection is set to false
if( this.fetchModels !== false ){

memberModel = this.get(pid);
//Add the models to the collection now, silently
//this.add(models, {silent: true});

var collection = this;
//Retrieve the model for each member
_.each(models, function(memberModel){

memberModel.fetch();
memberModel.once("sync",
function(oldModel){
var collection = this;

//Get the right model type based on the model values
var newModel = collection.getMember(oldModel);
memberModel.fetch();
memberModel.once("sync",
function(oldModel){

//If the model type has changed, then mark the model as unsynced, since there may be custom fetch() options for the new model
if(oldModel.type != newModel.type){
//Get the right model type based on the model values
var newModel = collection.getMember(oldModel);

// DataPackages shouldn't be fetched until we support nested packages better in the UI
if(newModel.type == "DataPackage"){
//Trigger a replace event so other parts of the app know when a model has been replaced with a different type
oldModel.trigger("replace", newModel);
}
else{
newModel.set("synced", false);
//If the model type has changed, then mark the model as unsynced, since there may be custom fetch() options for the new model
if(oldModel.type != newModel.type){

// DataPackages shouldn't be fetched until we support nested packages better in the UI
if(newModel.type == "DataPackage"){
//Trigger a replace event so other parts of the app know when a model has been replaced with a different type
oldModel.trigger("replace", newModel);
}
else{
newModel.set("synced", false);

newModel.fetch();
newModel.once("sync", function(fetchedModel){
fetchedModel.set("synced", true);
collection.add(fetchedModel, { merge: true });
newModel.fetch();
newModel.once("sync", function(fetchedModel){
fetchedModel.set("synced", true);

//Trigger a replace event so other parts of the app know when a model has been replaced with a different type
oldModel.trigger("replace", newModel);
//Remove the model from the collection and add it back
collection.remove(oldModel);
collection.add(fetchedModel);

if(newModel.type == "EML")
collection.trigger("add:EML");
});
//Trigger a replace event so other parts of the app know when a model has been replaced with a different type
oldModel.trigger("replace", newModel);

if(newModel.type == "EML")
collection.trigger("add:EML");
});
}
}
}
else{
newModel.set("synced", true);
collection.add(newModel, { replace: true });
else{
newModel.set("synced", true);
collection.add(newModel, { merge: true });

if(newModel.type == "EML")
collection.trigger("add:EML");
}
});
if(newModel.type == "EML")
collection.trigger("add:EML");
}
});

}, this);
}, this);
}

} catch (error) {
console.log(error);
Expand Down Expand Up @@ -1486,6 +1553,17 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",
},

triggerComplete: function(model){

//If the last fetch did not fetch the models of the collection, then mark as complete now.
if(this.fetchModels === false){
// Delete the fetchModels property since it is set only once per fetch.
delete this.fetchModels;

this.trigger("complete", this);

return;
}

//Check if the collection is done being retrieved
var notSynced = this.reject(function(m){
return (m.get("synced") || m.get("id") == model.get("id"));
Expand Down Expand Up @@ -2630,7 +2708,49 @@ define(['jquery', 'underscore', 'backbone', 'rdflib', "uuid", "md5",

},

/*
/**
* Fetches this DataPackage from the Solr index by using a SolrResults collection
* and merging the models in.
*/
fetchFromIndex: function(){

if( typeof this.solrResults == "undefined" || !this.solrResults ){
this.solrResults = new SolrResults();
}

//If no query is set yet, use the FilterModel associated with this DataPackage
if( !this.solrResults.currentquery.length ){
this.solrResults.currentquery = this.filterModel.getQuery();
}

this.listenToOnce(this.solrResults, "reset", function(solrResults){
solrResults.each(function(solrResult){

var modelInDataPackage = this.findWhere({ id: solrResult.get("id") });

if( modelInDataPackage ){

var fieldsToExtract = this.solrResults.fields ? this.solrResults.fields.split(",") : [];

if( fieldsToExtract.length ){
var valuesFromSolr = _.pick(solrResult.toJSON(), fieldsToExtract);

modelInDataPackage.set(valuesFromSolr);
}

}

}, this);

this.trigger("complete");
});

//Query the index for this data package
this.solrResults.query();

},

/**
* Update the relationships in this resource map when its been udpated
*/
updateRelationships: function(){
Expand Down
29 changes: 17 additions & 12 deletions src/js/collections/SolrResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,20 @@ define(['jquery', 'underscore', 'backbone', 'models/SolrHeader', 'models/SolrRes
}

//create the query url
var endpoint = MetacatUI.appModel.get('queryServiceUrl') +
"fl=" + this.fields +
"&q=" + this.currentquery +
"&sort=" + this.sort +
"&rows=" + this.rows +
"&start=" + this.start +
"&facet=true&facet.sort=index" + facetFields +
stats +
"&wt=json";
var endpoint = MetacatUI.appModel.get('queryServiceUrl') + "q=" + this.currentquery;

if(this.fields)
endpoint += "&fl=" + this.fields;
if(this.sort)
endpoint += "&sort=" + this.sort;
if( typeof this.rows == "number" || (typeof this.rows == "string" && this.rows.length))
endpoint += "&rows=" + this.rows;
if( typeof this.start == "number" || (typeof this.start == "string" && this.start.length))
endpoint += "&start=" + this.start;
if( this.facet.length > 0 )
endpoint += "&facet=true&facet.sort=index" + facetFields;

endpoint += stats + "&wt=json";

return endpoint;
},
Expand Down Expand Up @@ -151,14 +156,14 @@ define(['jquery', 'underscore', 'backbone', 'models/SolrHeader', 'models/SolrRes
},

query: function(newquery) {
if (this.currentquery != newquery) {

if(typeof newquery != "undefined" && this.currentquery != newquery){
this.currentquery = newquery;
this.start = 0;

}

var fetchOptions = this.createFetchOptions();
this.fetch(fetchOptions);
//this.fetch({data: {start: this.start}, reset: true});
},

setQuery: function(newquery) {
Expand Down
Loading

0 comments on commit c023088

Please sign in to comment.