Skip to content

Commit

Permalink
Merge branch '5.8.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
hplahar committed Jan 21, 2021
2 parents cb2a7a7 + 64205c3 commit feaa85a
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 33 deletions.
88 changes: 73 additions & 15 deletions src/main/java/org/jbei/ice/lib/entry/sequence/PartSequence.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.jbei.ice.storage.DAOFactory;
import org.jbei.ice.storage.hibernate.dao.FeatureDAO;
import org.jbei.ice.storage.hibernate.dao.SequenceDAO;
import org.jbei.ice.storage.hibernate.dao.SequenceFeatureAttributeDAO;
import org.jbei.ice.storage.hibernate.dao.SequenceFeatureDAO;
import org.jbei.ice.storage.model.*;

Expand Down Expand Up @@ -366,26 +367,83 @@ private void checkForUpdatedFeatures(Sequence existing, Sequence updated) {
if (existing == null || existing.getSequenceFeatures() == null || updated.getSequenceFeatures() == null)
return;

for (SequenceFeature existingFeature : existing.getSequenceFeatures()) {
// for each existing feature, check with updated for difference in name and type
for (SequenceFeature updatedSequenceFeature : updated.getSequenceFeatures()) {
Feature sequenceFeature = updatedSequenceFeature.getFeature();
Feature existingFeatureFeature = existingFeature.getFeature();

if (!sequenceFeature.getHash().equals(existingFeatureFeature.getHash()))
continue;

if (!sequenceFeature.getName().equals(existingFeatureFeature.getName()) ||
!sequenceFeature.getGenbankType().equals(existingFeatureFeature.getGenbankType())) {
// update
existingFeatureFeature.setName(sequenceFeature.getName());
existingFeatureFeature.setGenbankType(sequenceFeature.getGenbankType());
featureDAO.update(existingFeatureFeature);
final SequenceFeatureAttributeDAO attributeDAO = DAOFactory.getSequenceFeatureAttributeDAO();

// for each existing feature, check with updated for difference in name and type and notes
for (SequenceFeature existingSequenceFeature : existing.getSequenceFeatures()) {

SequenceFeature updatedSequenceFeature = getUpdatedEquivalent(existingSequenceFeature, updated);
if (updatedSequenceFeature == null)
continue;

Feature updatedFeature = updatedSequenceFeature.getFeature();
Feature existingFeature = existingSequenceFeature.getFeature();

// check if existing feature name/type needs to be updated
if (!updatedFeature.getName().equals(existingFeature.getName()) ||
!updatedFeature.getGenbankType().equals(existingFeature.getGenbankType())) {
existingFeature.setName(updatedFeature.getName());
existingFeature.setGenbankType(updatedFeature.getGenbankType());
featureDAO.update(existingFeature);
}

// check notes for existing feature TODO : if key same but value is different, update instead
// first build cache of updated
Map<String, List<String>> updatedCache = new HashMap<>();
for (SequenceFeatureAttribute updatedAttribute : updatedSequenceFeature.getSequenceFeatureAttributes()) {
String key = updatedAttribute.getKey();
String value = updatedAttribute.getValue();

List<String> values = updatedCache.computeIfAbsent(key, k -> new ArrayList<>());
values.add(value);
}

Iterator<SequenceFeatureAttribute> iterator = existingSequenceFeature.getSequenceFeatureAttributes().iterator();

// remove notes that are not in updated list
while (iterator.hasNext()) {
SequenceFeatureAttribute attribute = iterator.next();
List<String> values = updatedCache.get(attribute.getKey());
if (values == null || !values.contains(attribute.getValue())) {
attributeDAO.delete(attribute);
iterator.remove();
}
}

// add notes from updated list not present in existing
for (SequenceFeatureAttribute updatedAttribute : updatedSequenceFeature.getSequenceFeatureAttributes()) {
// check if attribute is available on existing
boolean isAvailable = false;
for (SequenceFeatureAttribute existingAttribute : existingSequenceFeature.getSequenceFeatureAttributes()) {
isAvailable = updatedAttribute.getKey().equals(existingAttribute.getKey()) &&
updatedAttribute.getValue().equals(existingAttribute.getValue());
if (isAvailable)
break;
}

// if not available add to list
if (!isAvailable) {
updatedAttribute.setSequenceFeature(existingSequenceFeature);
updatedAttribute = attributeDAO.create(updatedAttribute);
existingSequenceFeature.getSequenceFeatureAttributes().add(updatedAttribute);
}
}
}
}

// todo : can cache using hash as key (hash -> sequence) for performance improvements
private SequenceFeature getUpdatedEquivalent(SequenceFeature existing, Sequence updatedSequence) {
if (updatedSequence.getSequenceFeatures() == null)
return null;

for (SequenceFeature updated : updatedSequence.getSequenceFeatures()) {
if (existing.getFeature().getHash().equals(updated.getFeature().getHash()))
return updated;
}
// no match found
return null;
}

private void deleteSequenceFeature(SequenceFeature sequenceFeature) {
sequenceFeature.setSequence(null);
sequenceFeature.setFeature(null);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/jbei/ice/storage/DAOFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class DAOFactory {
private static CustomEntryFieldDAO customEntryFieldDAO;
private static CustomEntryFieldValueDAO customEntryFieldValueDAO;
private static SampleCreateModelDAO sampleCreateModelDAO;
private static SequenceFeatureAttributeDAO sequenceFeatureAttributeDAO;

public static AccountDAO getAccountDAO() {
if (accountDAO == null)
Expand Down Expand Up @@ -245,4 +246,10 @@ public static SampleCreateModelDAO getSampleCreateModelDAO() {
sampleCreateModelDAO = new SampleCreateModelDAO();
return sampleCreateModelDAO;
}

public static SequenceFeatureAttributeDAO getSequenceFeatureAttributeDAO() {
if (sequenceFeatureAttributeDAO == null)
sequenceFeatureAttributeDAO = new SequenceFeatureAttributeDAO();
return sequenceFeatureAttributeDAO;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.jbei.ice.storage.hibernate.dao;

import org.jbei.ice.storage.hibernate.HibernateRepository;
import org.jbei.ice.storage.model.SequenceFeatureAttribute;

public class SequenceFeatureAttributeDAO extends HibernateRepository<SequenceFeatureAttribute> {

@Override
public SequenceFeatureAttribute get(long id) {
return super.get(SequenceFeatureAttribute.class, id);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.jbei.ice.storage.model;

import org.jbei.ice.lib.dto.DNAFeatureNote;
import org.jbei.ice.storage.DataModel;
import org.jbei.ice.storage.IDataTransferModel;

import javax.persistence.*;

Expand Down Expand Up @@ -77,7 +77,12 @@ public void setSequenceFeature(SequenceFeature sequenceFeature) {
}

@Override
public IDataTransferModel toDataTransferObject() {
return null; //To change body of implemented methods use File | Settings | File Templates.
public String toString() {
return "(" + this.key + ", " + this.value + ")";
}

@Override
public DNAFeatureNote toDataTransferObject() {
return new DNAFeatureNote(this.key, this.value);
}
}
39 changes: 29 additions & 10 deletions src/main/webapp/scripts/entry/entryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,13 @@ angular.module('ice.entry.controller', [])
forward: feature.strand === 1,
type: feature.type,
name: feature.name,
notes: notes,
notes: [],
annotationType: feature.type
};

// convert notes
console.log("notes", notes);

features.push(featureObject);
}
}
Expand All @@ -569,7 +572,9 @@ angular.module('ice.entry.controller', [])
isFullscreen: true,
shouldAutosave: true,
disableSetReadOnly: true,
handleFullscreenClose: function () { // this will make the editor fullscreen by default, and will allow you to handle the close request
showMenuBar: true,
handleFullscreenClose: function () {
// this will make the editor fullscreen by default, and will allow you to handle the close request
$scope.vEeditor.close(); // handle vector editor root removal and clean up
},

Expand All @@ -578,6 +583,16 @@ angular.module('ice.entry.controller', [])
// teselagenSequenceData
},

beforeAnnotationCreate: ({
annotationTypePlural, //one of "features"/"parts"/"primers"
annotation, //annotation info
props //general props to the dialog
}) => {
console.log("features", annotationTypePlural);
console.log("info", annotation);
console.log("general props", props);
},

// getVersionList: function () {
// Util.get('rest/sequences/' + openVEData.registryData.identifier + '/history', function (result) {
// return [
Expand Down Expand Up @@ -660,7 +675,10 @@ angular.module('ice.entry.controller', [])
if (!feature.notes.hasOwnProperty(prop))
continue;

featureMap[feature.id].notes.push({name: "note", value: prop})
const values = feature.notes[prop];
for (let i = 0; i < values.length; i += 1) {
featureMap[feature.id].notes.push({name: prop, value: values[i]});
}
}
}
}
Expand All @@ -673,11 +691,8 @@ angular.module('ice.entry.controller', [])
sequence.features.push(featureMap[property]);
}

console.log(sequence.features);

Util.update("rest/parts/" + entry.id + "/sequence", sequence, {},
function (result) {
console.log("save completed for", entry.id);
$rootScope.$emit("ReloadVectorViewData", result);
const sequenceModel = {
sequenceData: {
Expand All @@ -691,7 +706,8 @@ angular.module('ice.entry.controller', [])
$scope.updatedSequence = result;
onSuccessCallback();
})
},
}
,

onCopy: function (event, copiedSequenceData, editorState) {
let clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
Expand All @@ -700,7 +716,8 @@ angular.module('ice.entry.controller', [])
openVEData.openVECopied = copiedSequenceData;
clipboardData.setData('application/json', JSON.stringify(openVEData));
event.preventDefault();
},
}
,

onPaste: function (event, editorState) {
let clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
Expand All @@ -710,7 +727,8 @@ angular.module('ice.entry.controller', [])
jsonData = jsonData.openVECopied;
}
return jsonData || {sequence: clipboardData.getData("text/plain")}
},
}
,

PropertiesProps: {
propertiesList: [
Expand All @@ -719,7 +737,8 @@ angular.module('ice.entry.controller', [])
"cutsites",
"orfs"
]
},
}
,
ToolBarProps: {
//name the tools you want to see in the toolbar in the order you want to see them
toolList: [
Expand Down
24 changes: 19 additions & 5 deletions src/main/webapp/scripts/entry/entryDirectives.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ angular.module('ice.entry.directives', [])
if (!data)
return;

console.log("refreshing vector editor");
$scope.loadVectorEditor(convertToVEModel(data));
});

Expand Down Expand Up @@ -178,6 +177,18 @@ angular.module('ice.entry.directives', [])
return l1.genbankStart - l2.genbankStart;
}

let convertNotes = function (feature, featureObject) {
if (feature.notes.length) {
for (let k = 0; k < feature.notes.length; k += 1) {
const note = feature.notes[k];
if (!featureObject.notes[note.name])
featureObject.notes[note.name] = [];
featureObject.notes[note.name].push(note.value);
}
}
return featureObject;
}

// converts the features array (which is what is returned by ICE) to a class (which is what
// openVE uses)
const convertFeaturesToVEModel = function (features, openVE = null) {
Expand All @@ -202,8 +213,6 @@ angular.module('ice.entry.directives', [])
feature.locations.sort(compareLocations); // todo: there is a bug here if spanning origin

// deal with locations
let notes = feature.notes.length ? feature.notes[0].value : "";

for (let j = 0; j < feature.locations.length; j += 1) {
let location = feature.locations[j];
let featureObject = openVE[feature.id];
Expand All @@ -217,6 +226,9 @@ angular.module('ice.entry.directives', [])
locations.push({start: location.genbankStart - 1, end: location.end - 1});
featureObject.end = location.end - 1;
featureObject.locations = locations;

// deal with feature notes
featureObject = convertNotes(feature, featureObject);
} else {
featureObject = {
start: location.genbankStart - 1,
Expand All @@ -225,9 +237,12 @@ angular.module('ice.entry.directives', [])
forward: feature.strand === 1,
type: feature.type,
name: feature.name,
notes: notes,
notes: {},
annotationType: feature.type
};

// deal with feature notes
featureObject = convertNotes(feature, featureObject);
}

openVE[featureObject.fid] = featureObject;
Expand Down Expand Up @@ -285,7 +300,6 @@ angular.module('ice.entry.directives', [])
} else {
$scope.fetchingAnnotations = false;
$scope.loaded(seqData);
console.log("annotations loaded", seqData);
$rootScope.$emit("VectorEditorSequenceModel", {sequenceData: seqData});
}
}, {start: start, limit: 10}, function (error) {
Expand Down

0 comments on commit feaa85a

Please sign in to comment.