2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.io.vamsas;
20 import java.util.Enumeration;
21 import java.util.Vector;
23 import uk.ac.vamsas.objects.core.DataSetAnnotations;
24 import uk.ac.vamsas.objects.core.Link;
25 import uk.ac.vamsas.objects.core.Property;
26 import uk.ac.vamsas.objects.core.Provenance;
27 import uk.ac.vamsas.objects.core.RangeAnnotation;
28 import uk.ac.vamsas.objects.core.Score;
29 import uk.ac.vamsas.objects.core.Seg;
30 import uk.ac.vamsas.objects.utils.Properties;
31 import jalview.bin.Cache;
32 import jalview.datamodel.SequenceFeature;
33 import jalview.datamodel.SequenceI;
34 import jalview.io.VamsasAppDatastore;
35 import jalview.util.UrlLink;
41 public class Sequencefeature extends Rangetype
44 uk.ac.vamsas.objects.core.DataSet dataset;
46 uk.ac.vamsas.objects.core.Sequence sequence;
48 private SequenceI dsSeq;
50 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
51 SequenceFeature sequenceFeature,
52 uk.ac.vamsas.objects.core.DataSet dataset,
53 uk.ac.vamsas.objects.core.Sequence sequence)
55 super(vamsasAppDatastore, sequenceFeature, DataSetAnnotations.class);
56 this.dataset = dataset;
57 this.sequence = sequence;
61 public Sequencefeature(VamsasAppDatastore vamsasAppDatastore,
62 DataSetAnnotations dseta, SequenceI dsSeq)
64 super(vamsasAppDatastore, dseta,
65 jalview.datamodel.SequenceFeature.class);
70 public void addToDocument()
72 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
73 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
74 dsa = (DataSetAnnotations) getDSAnnotationFromJalview(
75 new DataSetAnnotations(), feature);
76 if (dsa.getProvenance() == null)
78 dsa.setProvenance(new Provenance());
80 addProvenance(dsa.getProvenance(), "created"); // JBPNote - need
82 dsa.addSeqRef(sequence); // we have just created this annotation
83 // - so safe to use this
84 bindjvvobj(feature, dsa);
85 dataset.addDataSetAnnotations(dsa);
88 public void addFromDocument()
90 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
91 if (dsa.getSeqRefCount() != 1)
96 + " to Sequence Feature - has multiple dataset sequence references.");
99 jalview.datamodel.SequenceFeature sf = (jalview.datamodel.SequenceFeature) jvobj;
100 dsSeq.addSequenceFeature(sf = getJalviewSeqFeature(dsa));
105 public void conflict()
107 log.warn("Untested sequencefeature conflict code");
108 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
109 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
110 jalview.datamodel.SequenceFeature sf = getJalviewSeqFeature(dsa);
111 replaceJvObjMapping(feature, sf); // switch binding of dsa from old feature
112 // to newly created feature
113 dsSeq.addSequenceFeature(sf); // add new imported feature
114 addToDocument(); // and create a new feature in the document
117 public void updateToDoc()
119 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
120 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
121 if (dsa.getSeqRefCount() != 1)
123 replaceJvObjMapping(feature, null);
125 .warn("Binding of annotation to jalview feature has changed. Removing binding and recreating.");
126 doSync(); // re-verify bindings.
130 // Sync the features from Jalview
131 long oldref = dsa.get__last_hash();
132 getDSAnnotationFromJalview(dsa, feature);
133 if (oldref != dsa.hashCode())
136 .debug("Updated dataset sequence annotation from feature.");
137 addProvenance(dsa.getProvenance(), "modified");
143 public void updateFromDoc()
145 DataSetAnnotations dsa = (DataSetAnnotations) vobj;
146 jalview.datamodel.SequenceFeature feature = (jalview.datamodel.SequenceFeature) jvobj;
147 if (dsa.getSeqRefCount() != 1)
149 // conflicting update from document - we cannot map this feature anymore.
150 replaceJvObjMapping(feature, null);
154 + " bound to jalview feature cannot be mapped. Removing binding, deleting feature, and deleting feature.");
155 // - consider deleting the feature ?
156 dsSeq.deleteFeature(feature);
161 // Sync the features to Jalview - easiest to delete and add the feature
163 jalview.datamodel.SequenceFeature newsf = getJalviewSeqFeature(dsa);
164 dsSeq.deleteFeature(feature);
165 replaceJvObjMapping(feature, newsf);
166 dsSeq.addSequenceFeature(newsf);
167 if (feature.otherDetails != null)
169 // TODO later: leave this to finalise method ?
170 feature.otherDetails.clear();
176 * correctly create/update a RangeAnnotation from a jalview sequence feature
177 * TODO: refactor to a method in jalview.io.vamsas.RangeAnnotation class
180 * (typically DataSetAnnotations or AlignmentSequenceAnnotation)
182 * (the feature to be mapped from)
185 private RangeAnnotation getDSAnnotationFromJalview(RangeAnnotation dsa,
186 jalview.datamodel.SequenceFeature feature)
188 dsa.setType(feature.getType());
189 Seg vSeg = new Seg();
190 vSeg.setStart(feature.getBegin());
191 vSeg.setEnd(feature.getEnd());
192 vSeg.setInclusive(true);
193 if (dsa.getSegCount() > 1)
196 .debug("About to destroy complex annotation in vamsas document mapped to sequence feature ("
197 + dsa.getVorbaId() + ")");
201 dsa.setDescription(feature.getDescription());
202 dsa.setStatus(feature.getStatus());
203 if (feature.links != null && feature.links.size() > 0)
205 for (int i = 0, iSize = feature.links.size(); i < iSize; i++)
207 String link = (String) feature.links.elementAt(i);
208 UrlLink ulink = new UrlLink(link);
211 // We only add static links to the document.
212 Link vLink = new Link();
213 vLink.setContent(ulink.getLabel());
214 vLink.setHref(ulink.getTarget());
219 dsa.setGroup(feature.getFeatureGroup());
220 if (feature.getScore() != Float.NaN)
222 Score fscore = new Score();
223 dsa.setScore(new Score[]
225 fscore.setContent(feature.getScore());
226 fscore.setName(feature.getType());
228 if (feature.otherDetails != null)
230 Enumeration iter = feature.otherDetails.keys();
231 Vector props = dsa.getPropertyAsReference();
232 while (iter.hasMoreElements())
234 String key = (String) iter.nextElement();
235 if (!key.equalsIgnoreCase("score")
236 && !key.equalsIgnoreCase("status"))
238 Property nprop = new Property();
240 Object vlu = feature.getValue(key);
241 nprop.setContent(feature.getValue(key).toString());
242 boolean valid = false;
243 if (vlu instanceof String)
245 nprop.setType(uk.ac.vamsas.objects.utils.Properties.STRINGTYPE);
248 else if (vlu instanceof Integer)
251 nprop.setType(uk.ac.vamsas.objects.utils.Properties.INTEGERTYPE);
253 else if (vlu instanceof Float)
255 nprop.setType(uk.ac.vamsas.objects.utils.Properties.FLOATTYPE);
262 uk.ac.vamsas.objects.utils.Properties.addOrReplace(props,
267 dsa.addProperty(nprop);
276 private SequenceFeature getJalviewSeqFeature(RangeAnnotation dseta)
278 int[] se = getBounds(dseta);
279 SequenceFeature sf = new jalview.datamodel.SequenceFeature(
280 dseta.getType(), dseta.getDescription(), dseta.getStatus(),
281 se[0], se[1], dseta.getGroup());
282 if (dseta.getLinkCount() > 0)
284 Link[] links = dseta.getLink();
285 for (int i = 0; i < links.length; i++)
287 // TODO: use URLLink parsing/validation here.
288 sf.addLink(links[i].getContent() + "|" + links[i].getHref());
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(sf.getType()))
299 sf.setScore(score.getContent());
303 sf.setValue(score.getName(), "" + score.getContent());
308 Enumeration props = dseta.enumerateProperty();
309 while (props.hasMoreElements())
311 Property p = (Property) props.nextElement();
313 if (Properties.isValid(p))
315 if (Properties.isString(p))
317 val = p.getContent();
319 if (Properties.isBoolean(p))
323 val = new Boolean(p.getContent());
324 } catch (Exception e)
328 if (Properties.isFloat(p))
332 val = new Float(p.getContent());
334 } catch (Exception e)
338 if (Properties.isInteger(p))
342 val = new Integer(p.getContent());
343 } catch (Exception e)
349 sf.setValue(p.getName(), val);