2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ 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 jalview.bin.Cache;
24 import jalview.datamodel.SequenceFeature;
25 import jalview.datamodel.SequenceI;
26 import jalview.io.VamsasAppDatastore;
27 import jalview.util.UrlLink;
29 import java.util.Enumeration;
30 import java.util.Iterator;
31 import java.util.Vector;
33 import uk.ac.vamsas.objects.core.DataSetAnnotations;
34 import uk.ac.vamsas.objects.core.Link;
35 import uk.ac.vamsas.objects.core.Property;
36 import uk.ac.vamsas.objects.core.Provenance;
37 import uk.ac.vamsas.objects.core.RangeAnnotation;
38 import uk.ac.vamsas.objects.core.Score;
39 import uk.ac.vamsas.objects.core.Seg;
40 import uk.ac.vamsas.objects.utils.Properties;
46 public class Sequencefeature extends Rangetype
49 uk.ac.vamsas.objects.core.DataSet dataset;
51 uk.ac.vamsas.objects.core.Sequence sequence;
53 private SequenceI dsSeq;
55 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
56 SequenceFeature sequenceFeature,
57 uk.ac.vamsas.objects.core.DataSet dataset,
58 uk.ac.vamsas.objects.core.Sequence sequence)
60 super(vamsasAppDatastore, sequenceFeature, DataSetAnnotations.class);
61 this.dataset = dataset;
62 this.sequence = sequence;
66 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
67 DataSetAnnotations dseta, SequenceI dsSeq)
69 super(vamsasAppDatastore, dseta,
70 jalview.datamodel.SequenceFeature.class);
76 public void addToDocument()
78 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
79 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
80 dsa = (DataSetAnnotations) getDSAnnotationFromJalview(
81 new DataSetAnnotations(), feature);
82 if (dsa.getProvenance() == null)
84 dsa.setProvenance(new Provenance());
86 addProvenance(dsa.getProvenance(), "created"); // JBPNote - need
88 dsa.addSeqRef(sequence); // we have just created this annotation
89 // - so safe to use this
90 bindjvvobj(feature, dsa);
91 dataset.addDataSetAnnotations(dsa);
95 public void addFromDocument()
97 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
98 if (dsa.getSeqRefCount() != 1)
100 Cache.log.warn("Not binding " + dsa.getVorbaId()
101 + " to Sequence Feature - has multiple dataset sequence references.");
104 jalview.datamodel.SequenceFeature sf = (jalview.datamodel.SequenceFeature) jvobj;
105 dsSeq.addSequenceFeature(sf = getJalviewSeqFeature(dsa));
111 public void conflict()
113 log.warn("Untested sequencefeature conflict code");
114 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
115 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
116 jalview.datamodel.SequenceFeature sf = getJalviewSeqFeature(dsa);
117 replaceJvObjMapping(feature, sf); // switch binding of dsa from old feature
118 // to newly created feature
119 dsSeq.addSequenceFeature(sf); // add new imported feature
120 addToDocument(); // and create a new feature in the document
124 public void updateToDoc()
126 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
127 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
128 if (dsa.getSeqRefCount() != 1)
130 replaceJvObjMapping(feature, null);
132 "Binding of annotation to jalview feature has changed. Removing binding and recreating.");
133 doSync(); // re-verify bindings.
137 // Sync the features from Jalview
138 long oldref = dsa.get__last_hash();
139 getDSAnnotationFromJalview(dsa, feature);
140 if (oldref != dsa.hashCode())
143 .debug("Updated dataset sequence annotation from feature.");
144 addProvenance(dsa.getProvenance(), "modified");
151 public void updateFromDoc()
153 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
154 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
155 if (dsa.getSeqRefCount() != 1)
157 // conflicting update from document - we cannot map this feature anymore.
158 replaceJvObjMapping(feature, null);
159 Cache.log.warn("annotation (" + dsa.getVorbaId()
160 + " bound to jalview feature cannot be mapped. Removing binding, deleting feature, and deleting feature.");
161 // - consider deleting the feature ?
162 dsSeq.deleteFeature(feature);
167 // Sync the features to Jalview - easiest to delete and add the feature
169 jalview.datamodel.SequenceFeature newsf = getJalviewSeqFeature(dsa);
170 dsSeq.deleteFeature(feature);
171 replaceJvObjMapping(feature, newsf);
172 dsSeq.addSequenceFeature(newsf);
173 if (feature.otherDetails != null)
175 // TODO later: leave this to finalise method ?
176 feature.otherDetails.clear();
182 * correctly create/update a RangeAnnotation from a jalview sequence feature
183 * TODO: refactor to a method in jalview.io.vamsas.RangeAnnotation class
186 * (typically DataSetAnnotations or AlignmentSequenceAnnotation)
188 * (the feature to be mapped from)
191 private RangeAnnotation getDSAnnotationFromJalview(RangeAnnotation dsa,
192 jalview.datamodel.SequenceFeature feature)
194 dsa.setType(feature.getType());
195 Seg vSeg = new Seg();
196 vSeg.setStart(feature.getBegin());
197 vSeg.setEnd(feature.getEnd());
198 vSeg.setInclusive(true);
199 if (dsa.getSegCount() > 1)
202 "About to destroy complex annotation in vamsas document mapped to sequence feature ("
203 + dsa.getVorbaId() + ")");
205 dsa.setSeg(new Seg[] { vSeg });
206 dsa.setDescription(feature.getDescription());
207 dsa.setStatus(feature.getStatus());
208 if (feature.links != null && feature.links.size() > 0)
210 for (int i = 0, iSize = feature.links.size(); i < iSize; i++)
212 String link = feature.links.elementAt(i);
213 UrlLink ulink = new UrlLink(link);
216 // We only add static links to the document.
217 Link vLink = new Link();
218 vLink.setContent(ulink.getLabel());
219 vLink.setHref(ulink.getTarget());
224 dsa.setGroup(feature.getFeatureGroup());
225 if (!Float.isNaN(feature.getScore()))
227 Score fscore = new Score();
228 dsa.setScore(new Score[] { fscore });
229 fscore.setContent(feature.getScore());
230 fscore.setName(feature.getType());
232 if (feature.otherDetails != null)
234 Iterator<String> iter = feature.otherDetails.keySet().iterator();
235 Vector props = dsa.getPropertyAsReference();
236 while (iter.hasNext())
238 String key = iter.next();
239 if (!key.equalsIgnoreCase("score")
240 && !key.equalsIgnoreCase("status"))
242 Property nprop = new Property();
244 Object vlu = feature.getValue(key);
245 nprop.setContent(feature.getValue(key).toString());
246 boolean valid = false;
247 if (vlu instanceof String)
249 nprop.setType(uk.ac.vamsas.objects.utils.Properties.STRINGTYPE);
252 else if (vlu instanceof Integer)
256 uk.ac.vamsas.objects.utils.Properties.INTEGERTYPE);
258 else if (vlu instanceof Float)
260 nprop.setType(uk.ac.vamsas.objects.utils.Properties.FLOATTYPE);
267 uk.ac.vamsas.objects.utils.Properties.addOrReplace(props,
272 dsa.addProperty(nprop);
281 private SequenceFeature getJalviewSeqFeature(RangeAnnotation dseta)
283 int[] se = getBounds(dseta);
286 * try to identify feature score
288 boolean scoreFound = false;
290 String featureType = dseta.getType();
291 if (dseta.getScoreCount() > 0)
293 Enumeration scr = dseta.enumerateScore();
294 while (scr.hasMoreElements())
296 Score score = (Score) scr.nextElement();
297 if (score.getName().equals(featureType))
299 theScore = score.getContent();
305 SequenceFeature sf = null;
308 sf = new SequenceFeature(featureType, dseta.getDescription(), se[0],
309 se[1], theScore, dseta.getGroup());
313 sf = new SequenceFeature(featureType, dseta.getDescription(), se[0],
314 se[1], dseta.getGroup());
316 sf.setStatus(dseta.getStatus());
317 if (dseta.getLinkCount() > 0)
319 Link[] links = dseta.getLink();
320 for (int i = 0; i < links.length; i++)
322 // TODO: use URLLink parsing/validation here.
323 sf.addLink(links[i].getContent() + "|" + links[i].getHref());
326 if (dseta.getScoreCount() > 0)
328 Enumeration scr = dseta.enumerateScore();
329 while (scr.hasMoreElements())
331 Score score = (Score) scr.nextElement();
332 if (!score.getName().equals(sf.getType()))
334 sf.setValue(score.getName(), "" + score.getContent());
339 Enumeration props = dseta.enumerateProperty();
340 while (props.hasMoreElements())
342 Property p = (Property) props.nextElement();
344 if (Properties.isValid(p))
346 if (Properties.isString(p))
348 val = p.getContent();
350 if (Properties.isBoolean(p))
354 val = new Boolean(p.getContent());
355 } catch (Exception e)
359 if (Properties.isFloat(p))
363 val = new Float(p.getContent());
365 } catch (Exception e)
369 if (Properties.isInteger(p))
373 val = new Integer(p.getContent());
374 } catch (Exception e)
380 sf.setValue(p.getName(), val);