Merge branch 'develop' into features/JAL-2446NCList
[jalview.git] / src / jalview / io / vamsas / Datasetsequence.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package jalview.io.vamsas;
22
23 import jalview.datamodel.DBRefEntry;
24 import jalview.datamodel.SequenceFeature;
25 import jalview.datamodel.SequenceI;
26 import jalview.io.VamsasAppDatastore;
27
28 import java.util.List;
29
30 import uk.ac.vamsas.objects.core.DataSet;
31 import uk.ac.vamsas.objects.core.DbRef;
32 import uk.ac.vamsas.objects.core.Sequence;
33
34 /**
35  * synchronize a vamsas dataset sequence with a jalview dataset sequence. This
36  * class deals with all sequence features and database references associated
37  * with the jalview sequence.
38  * 
39  * @author JimP
40  * 
41  */
42 public class Datasetsequence extends DatastoreItem
43 {
44   String dict;
45
46   private DataSet dataset;
47
48   // private AlignmentI jvdset;
49
50   public Datasetsequence(VamsasAppDatastore vamsasAppDatastore,
51           SequenceI sq, String dict, DataSet dataset)
52   {
53     super(vamsasAppDatastore, sq, uk.ac.vamsas.objects.core.Sequence.class);
54     this.dataset = dataset;
55     // this.jvdset = jvdset;
56     this.dict = dict;
57     doSync();
58   }
59
60   public Datasetsequence(VamsasAppDatastore vamsasAppDatastore,
61           Sequence vdseq)
62   {
63     super(vamsasAppDatastore, vdseq, SequenceI.class);
64     doJvUpdate();
65   }
66
67   @Override
68   public void addFromDocument()
69   {
70     Sequence vseq = (Sequence) vobj;
71     SequenceI dsseq = new jalview.datamodel.Sequence(vseq.getName(),
72             vseq.getSequence(), (int) vseq.getStart(), (int) vseq.getEnd());
73     dsseq.setDescription(vseq.getDescription());
74     bindjvvobj(dsseq, vseq);
75     dsseq.setVamsasId(vseq.getVorbaId().getId());
76     jvobj = dsseq;
77     modified = true;
78   }
79
80   @Override
81   public void updateFromDoc()
82   {
83     Sequence sq = (Sequence) vobj;
84     SequenceI sequence = (SequenceI) jvobj;
85     if (!sequence.getSequenceAsString().equals(sq.getSequence()))
86     {
87       log.warn("Potential Client Error ! - mismatch of dataset sequence: and jalview internal dataset sequence.");
88     }
89     else
90     {
91       // verify and update principal attributes.
92       if (sequence.getDescription() != null
93               && (sequence.getDescription() == null || !sequence
94                       .getDescription().equals(sq.getDescription())))
95       {
96         sequence.setDescription(sq.getDescription());
97         modified = true;
98       }
99       if (sequence.getSequence() == null
100               || !sequence.getSequenceAsString().equals(sq.getSequence()))
101       {
102         if (sequence.getStart() != sq.getStart()
103                 || sequence.getEnd() != sq.getEnd())
104         {
105           // update modified sequence.
106           sequence.setSequence(sq.getSequence());
107           sequence.setStart((int) sq.getStart());
108           sequence.setEnd((int) sq.getEnd());
109           modified = true;
110         }
111       }
112       if (!sequence.getName().equals(sq.getName()))
113       {
114         sequence.setName(sq.getName());
115         modified = true;
116       }
117       modified |= updateJvDbRefs();
118       // updateJvFeatures();
119     }
120   }
121
122   /*
123    * private void updateJvFeatures() { Sequence vsq = (Sequence) vobj;
124    * 
125    * // add or update any new features/references on dataset sequence if
126    * (vsq.getgetSequenceFeatures() != null) { int sfSize =
127    * sq.getSequenceFeatures().length;
128    * 
129    * for (int sf = 0; sf < sfSize; sf++) { new
130    * jalview.io.vamsas.Sequencefeature(datastore,
131    * (jalview.datamodel.SequenceFeature) sq .getSequenceFeatures()[sf], dataset,
132    * (Sequence) vobj); } } }
133    */
134   private boolean updateSqFeatures()
135   {
136     boolean changed = false;
137     SequenceI sq = (SequenceI) jvobj;
138
139     // add or update any new features/references on dataset sequence
140     List<SequenceFeature> sfs = sq.getSequenceFeatures();
141     for (SequenceFeature sf : sfs)
142     {
143       changed |= new jalview.io.vamsas.Sequencefeature(datastore, sf,
144               dataset, (Sequence) vobj).docWasUpdated();
145     }
146
147     return changed;
148   }
149
150   @Override
151   public void addToDocument()
152   {
153     SequenceI sq = (SequenceI) jvobj;
154     Sequence sequence = new Sequence();
155     bindjvvobj(sq, sequence);
156     sq.setVamsasId(sequence.getVorbaId().getId());
157     sequence.setSequence(sq.getSequenceAsString());
158     sequence.setDictionary(dict);
159     sequence.setName(sq.getName());
160     sequence.setStart(sq.getStart());
161     sequence.setEnd(sq.getEnd());
162     sequence.setDescription(sq.getDescription());
163     dataset.addSequence(sequence);
164     vobj = sequence;
165     updateSqFeatures();
166     updateDbRefs();// sq,(Sequence) vobj, dataset);
167   }
168
169   /**
170    * sync database references from jv to document
171    * 
172    * @return true if document was modified
173    */
174   private boolean updateDbRefs()
175   {
176     boolean modifiedthedoc = false;
177     SequenceI sq = (SequenceI) jvobj;
178
179     if (sq.getDatasetSequence() == null && sq.getDBRefs() != null)
180     {
181       // only sync database references for dataset sequences
182       DBRefEntry[] entries = sq.getDBRefs();
183       // jalview.datamodel.DBRefEntry dbentry;
184       for (int db = 0; db < entries.length; db++)
185       {
186         modifiedthedoc |= new jalview.io.vamsas.Dbref(datastore,
187         // dbentry =
188                 entries[db], sq, (Sequence) vobj, dataset).docWasUpdated();
189
190       }
191
192     }
193     return modifiedthedoc;
194   }
195
196   /**
197    * sync database references from document to jv sequence
198    * 
199    * @return true if local sequence refs were modified
200    */
201   private boolean updateJvDbRefs()
202   {
203     boolean modifiedtheseq = false;
204     SequenceI sq = (SequenceI) jvobj;
205     Sequence vsq = (Sequence) vobj;
206     if (vsq.getDbRefCount() > 0)
207     {
208       // only sync database references for dataset sequences
209       DbRef[] entries = vsq.getDbRef();
210       // DbRef dbentry;
211       for (int db = 0; db < entries.length; db++)
212       {
213         modifiedtheseq |= new jalview.io.vamsas.Dbref(datastore,
214         // dbentry =
215                 entries[db], vsq, sq).jvWasUpdated();
216       }
217     }
218     return modifiedtheseq;
219   }
220
221   @Override
222   public void conflict()
223   {
224     log.warn("Conflict in dataset sequence update to document. Overwriting document");
225     // TODO: could try to import from document data to jalview first. and then
226     updateToDoc();
227   }
228
229   boolean modified = false;
230
231   @Override
232   public void updateToDoc()
233   {
234     SequenceI sq = (SequenceI) jvobj;
235     Sequence sequence = (Sequence) vobj;
236     // verify and update principal attributes.
237     if (sequence.getDescription() != null
238             && (sequence.getDescription() == null || !sequence
239                     .getDescription().equals(sq.getDescription())))
240     {
241       sequence.setDescription(sq.getDescription());
242       modified = true;
243     }
244     if (sequence.getSequence() == null
245             || !sequence.getSequence().equals(sq.getSequenceAsString()))
246     {
247       if (sequence.getStart() != sq.getStart()
248               || sequence.getEnd() != sq.getEnd())
249       {
250         // update modified sequence.
251         sequence.setSequence(sq.getSequenceAsString());
252         sequence.setStart(sq.getStart());
253         sequence.setEnd(sq.getEnd());
254         modified = true;
255       }
256     }
257     if (!dict.equals(sequence.getDictionary()))
258     {
259       sequence.setDictionary(dict);
260       modified = true;
261     }
262     if (!sequence.getName().equals(sq.getName()))
263     {
264       sequence.setName(sq.getName());
265       modified = true;
266     }
267     modified |= updateDbRefs();
268     modified |= updateSqFeatures();
269   }
270
271   /**
272    * (probably could just do vobj.isModified(), but..)
273    * 
274    * @return true if document's dataset sequence was modified
275    */
276   public boolean getModified()
277   {
278     return modified;
279   }
280
281 }