2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.io.vamsas;
23 import java.util.Enumeration;
24 import java.util.Vector;
26 import uk.ac.vamsas.objects.core.DataSetAnnotations;
27 import uk.ac.vamsas.objects.core.Link;
28 import uk.ac.vamsas.objects.core.Property;
29 import uk.ac.vamsas.objects.core.Provenance;
30 import uk.ac.vamsas.objects.core.RangeAnnotation;
31 import uk.ac.vamsas.objects.core.Score;
32 import uk.ac.vamsas.objects.core.Seg;
33 import uk.ac.vamsas.objects.utils.Properties;
34 import jalview.bin.Cache;
35 import jalview.datamodel.SequenceFeature;
36 import jalview.datamodel.SequenceI;
37 import jalview.io.VamsasAppDatastore;
38 import jalview.util.UrlLink;
44 public class Sequencefeature extends Rangetype
47 uk.ac.vamsas.objects.core.DataSet dataset;
49 uk.ac.vamsas.objects.core.Sequence sequence;
51 private SequenceI dsSeq;
53 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
54 SequenceFeature sequenceFeature,
55 uk.ac.vamsas.objects.core.DataSet dataset,
56 uk.ac.vamsas.objects.core.Sequence sequence)
58 super(vamsasAppDatastore, sequenceFeature, DataSetAnnotations.class);
59 this.dataset = dataset;
60 this.sequence = sequence;
64 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
65 DataSetAnnotations dseta, SequenceI dsSeq)
67 super(vamsasAppDatastore, dseta,
68 jalview.datamodel.SequenceFeature.class);
73 public void addToDocument()
75 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
76 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
77 dsa = (DataSetAnnotations) getDSAnnotationFromJalview(
78 new DataSetAnnotations(), feature);
79 if (dsa.getProvenance() == null)
81 dsa.setProvenance(new Provenance());
83 addProvenance(dsa.getProvenance(), "created"); // JBPNote - need
85 dsa.addSeqRef(sequence); // we have just created this annotation
86 // - so safe to use this
87 bindjvvobj(feature, dsa);
88 dataset.addDataSetAnnotations(dsa);
91 public void addFromDocument()
93 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
94 if (dsa.getSeqRefCount() != 1)
99 + " to Sequence Feature - has multiple dataset sequence references.");
102 jalview.datamodel.SequenceFeature sf = (jalview.datamodel.SequenceFeature) jvobj;
103 dsSeq.addSequenceFeature(sf = getJalviewSeqFeature(dsa));
108 public void conflict()
110 log.warn("Untested sequencefeature conflict code");
111 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
112 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
113 jalview.datamodel.SequenceFeature sf = getJalviewSeqFeature(dsa);
114 replaceJvObjMapping(feature, sf); // switch binding of dsa from old feature
115 // to newly created feature
116 dsSeq.addSequenceFeature(sf); // add new imported feature
117 addToDocument(); // and create a new feature in the document
120 public void updateToDoc()
122 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
123 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
124 if (dsa.getSeqRefCount() != 1)
126 replaceJvObjMapping(feature, null);
128 .warn("Binding of annotation to jalview feature has changed. Removing binding and recreating.");
129 doSync(); // re-verify bindings.
133 // Sync the features from Jalview
134 long oldref = dsa.get__last_hash();
135 getDSAnnotationFromJalview(dsa, feature);
136 if (oldref != dsa.hashCode())
139 .debug("Updated dataset sequence annotation from feature.");
140 addProvenance(dsa.getProvenance(), "modified");
146 public void updateFromDoc()
148 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
149 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
150 if (dsa.getSeqRefCount() != 1)
152 // conflicting update from document - we cannot map this feature anymore.
153 replaceJvObjMapping(feature, null);
157 + " bound to jalview feature cannot be mapped. Removing binding, deleting feature, and deleting feature.");
158 // - consider deleting the feature ?
159 dsSeq.deleteFeature(feature);
164 // Sync the features to Jalview - easiest to delete and add the feature
166 jalview.datamodel.SequenceFeature newsf = getJalviewSeqFeature(dsa);
167 dsSeq.deleteFeature(feature);
168 replaceJvObjMapping(feature, newsf);
169 dsSeq.addSequenceFeature(newsf);
170 if (feature.otherDetails != null)
172 // TODO later: leave this to finalise method ?
173 feature.otherDetails.clear();
179 * correctly create/update a RangeAnnotation from a jalview sequence feature
180 * TODO: refactor to a method in jalview.io.vamsas.RangeAnnotation class
183 * (typically DataSetAnnotations or AlignmentSequenceAnnotation)
185 * (the feature to be mapped from)
188 private RangeAnnotation getDSAnnotationFromJalview(RangeAnnotation dsa,
189 jalview.datamodel.SequenceFeature feature)
191 dsa.setType(feature.getType());
192 Seg vSeg = new Seg();
193 vSeg.setStart(feature.getBegin());
194 vSeg.setEnd(feature.getEnd());
195 vSeg.setInclusive(true);
196 if (dsa.getSegCount() > 1)
199 .debug("About to destroy complex annotation in vamsas document mapped to sequence feature ("
200 + dsa.getVorbaId() + ")");
204 dsa.setDescription(feature.getDescription());
205 dsa.setStatus(feature.getStatus());
206 if (feature.links != null && feature.links.size() > 0)
208 for (int i = 0, iSize = feature.links.size(); i < iSize; i++)
210 String link = (String) feature.links.elementAt(i);
211 UrlLink ulink = new UrlLink(link);
214 // We only add static links to the document.
215 Link vLink = new Link();
216 vLink.setContent(ulink.getLabel());
217 vLink.setHref(ulink.getTarget());
222 dsa.setGroup(feature.getFeatureGroup());
223 if (feature.getScore() != Float.NaN)
225 Score fscore = new Score();
226 dsa.setScore(new Score[]
228 fscore.setContent(feature.getScore());
229 fscore.setName(feature.getType());
231 if (feature.otherDetails != null)
233 Enumeration iter = feature.otherDetails.keys();
234 Vector props = dsa.getPropertyAsReference();
235 while (iter.hasMoreElements())
237 String key = (String) iter.nextElement();
238 if (!key.equalsIgnoreCase("score")
239 && !key.equalsIgnoreCase("status"))
241 Property nprop = new Property();
243 Object vlu = feature.getValue(key);
244 nprop.setContent(feature.getValue(key).toString());
245 boolean valid = false;
246 if (vlu instanceof String)
248 nprop.setType(uk.ac.vamsas.objects.utils.Properties.STRINGTYPE);
251 else if (vlu instanceof Integer)
254 nprop.setType(uk.ac.vamsas.objects.utils.Properties.INTEGERTYPE);
256 else if (vlu instanceof Float)
258 nprop.setType(uk.ac.vamsas.objects.utils.Properties.FLOATTYPE);
265 uk.ac.vamsas.objects.utils.Properties.addOrReplace(props,
270 dsa.addProperty(nprop);
279 private SequenceFeature getJalviewSeqFeature(RangeAnnotation dseta)
281 int[] se = getBounds(dseta);
282 SequenceFeature sf = new jalview.datamodel.SequenceFeature(
283 dseta.getType(), dseta.getDescription(), dseta.getStatus(),
284 se[0], se[1], dseta.getGroup());
285 if (dseta.getLinkCount() > 0)
287 Link[] links = dseta.getLink();
288 for (int i = 0; i < links.length; i++)
290 // TODO: use URLLink parsing/validation here.
291 sf.addLink(links[i].getContent() + "|" + links[i].getHref());
294 if (dseta.getScoreCount() > 0)
296 Enumeration scr = dseta.enumerateScore();
297 while (scr.hasMoreElements())
299 Score score = (Score) scr.nextElement();
300 if (score.getName().equals(sf.getType()))
302 sf.setScore(score.getContent());
306 sf.setValue(score.getName(), "" + score.getContent());
311 Enumeration props = dseta.enumerateProperty();
312 while (props.hasMoreElements())
314 Property p = (Property) props.nextElement();
316 if (Properties.isValid(p))
318 if (Properties.isString(p))
320 val = p.getContent();
322 if (Properties.isBoolean(p))
326 val = new Boolean(p.getContent());
327 } catch (Exception e)
331 if (Properties.isFloat(p))
335 val = new Float(p.getContent());
337 } catch (Exception e)
341 if (Properties.isInteger(p))
345 val = new Integer(p.getContent());
346 } catch (Exception e)
352 sf.setValue(p.getName(), val);