JAL-1831 added changes to allow auto-generation of BioJSON schema from src code
[jalview.git] / src / jalview / io / JSONFile.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
22 package jalview.io;
23
24 import jalview.api.AlignExportSettingI;
25 import jalview.api.AlignViewportI;
26 import jalview.api.AlignmentViewPanel;
27 import jalview.api.ComplexAlignFile;
28 import jalview.api.FeatureRenderer;
29 import jalview.api.FeaturesDisplayedI;
30 import jalview.bin.BuildDetails;
31 import jalview.datamodel.AlignmentAnnotation;
32 import jalview.datamodel.AlignmentI;
33 import jalview.datamodel.Annotation;
34 import jalview.datamodel.ColumnSelection;
35 import jalview.datamodel.HiddenSequences;
36 import jalview.datamodel.Sequence;
37 import jalview.datamodel.SequenceFeature;
38 import jalview.datamodel.SequenceGroup;
39 import jalview.datamodel.SequenceI;
40 import jalview.json.binding.biojson.v1.AlignmentAnnotationPojo;
41 import jalview.json.binding.biojson.v1.AlignmentPojo;
42 import jalview.json.binding.biojson.v1.AnnotationPojo;
43 import jalview.json.binding.biojson.v1.JalviewBioJsColorSchemeMapper;
44 import jalview.json.binding.biojson.v1.SequenceFeaturesPojo;
45 import jalview.json.binding.biojson.v1.SequenceGrpPojo;
46 import jalview.json.binding.biojson.v1.SequencePojo;
47 import jalview.schemes.ColourSchemeI;
48 import jalview.schemes.ColourSchemeProperty;
49 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
50
51 import java.awt.Color;
52 import java.io.IOException;
53 import java.io.Reader;
54 import java.util.ArrayList;
55 import java.util.Hashtable;
56 import java.util.Iterator;
57 import java.util.List;
58 import java.util.Vector;
59
60 import org.json.simple.JSONArray;
61 import org.json.simple.JSONObject;
62 import org.json.simple.parser.JSONParser;
63
64 public class JSONFile extends AlignFile implements ComplexAlignFile
65 {
66   private ColourSchemeI colourScheme;
67
68   private static String version = new BuildDetails().getVersion();
69
70   private String webstartUrl = "http://www.jalview.org/services/launchApp";
71
72   private String application = "Jalview";
73
74   public static final String FILE_EXT = "json";
75
76   public static final String FILE_DESC = "JSON";
77
78   private String globalColorScheme;
79
80   private boolean showSeqFeatures;
81
82   private Hashtable<String, Sequence> seqMap;
83
84   private FeaturesDisplayedI displayedFeatures;
85
86   private FeatureRenderer fr;
87
88   private List<int[]> hiddenColumns;
89
90   private ColumnSelection columnSelection;
91
92   private List<String> hiddenSeqRefs;
93
94   private ArrayList<SequenceI> hiddenSequences;
95
96   public JSONFile()
97   {
98     super();
99   }
100
101   public JSONFile(FileParse source) throws IOException
102   {
103     super(source);
104   }
105
106   public JSONFile(String inFile, String type) throws IOException
107   {
108     super(inFile, type);
109   }
110
111   @Override
112   public void parse() throws IOException
113   {
114     parse(getReader());
115
116   }
117
118   @Override
119   public String print()
120   {
121     String jsonOutput = null;
122     try
123     {
124       AlignmentPojo jsonAlignmentPojo = new AlignmentPojo();
125       AlignExportSettingI exportSettings = getExportSettings();
126
127       // if no export settings were supplied use the following with all values
128       // defaulting to true
129       if (exportSettings == null)
130       {
131         exportSettings = new AlignExportSettingI()
132         {
133           @Override
134           public boolean isExportHiddenSequences()
135           {
136             return true;
137           }
138
139           @Override
140           public boolean isExportHiddenColumns()
141           {
142             return true;
143           }
144
145           @Override
146           public boolean isExportGroups()
147           {
148             return true;
149           }
150
151           @Override
152           public boolean isExportFeatures()
153           {
154             return true;
155           }
156
157           @Override
158           public boolean isExportAnnotations()
159           {
160             return true;
161           }
162         };
163       }
164
165       int count = 0;
166       for (SequenceI seq : seqs)
167       {
168         StringBuilder name = new StringBuilder();
169         name.append(seq.getName()).append("/").append(seq.getStart())
170                 .append("-").append(seq.getEnd());
171         SequencePojo jsonSeqPojo = new SequencePojo();
172         jsonSeqPojo.setId(String.valueOf(seq.hashCode()));
173         jsonSeqPojo.setOrder(++count);
174         jsonSeqPojo.setEnd(seq.getEnd());
175         jsonSeqPojo.setStart(seq.getStart());
176         jsonSeqPojo.setName(name.toString());
177         jsonSeqPojo.setSeq(seq.getSequenceAsString());
178         jsonAlignmentPojo.getSeqs().add(jsonSeqPojo);
179       }
180       jsonAlignmentPojo.setGlobalColorScheme(globalColorScheme);
181       jsonAlignmentPojo.getAppSettings().put("application", application);
182       jsonAlignmentPojo.getAppSettings().put("version", version);
183       jsonAlignmentPojo.getAppSettings().put("webStartUrl", webstartUrl);
184       jsonAlignmentPojo.getAppSettings().put("showSeqFeatures",
185               String.valueOf(showSeqFeatures));
186
187       String[] hiddenSections = getHiddenSections();
188       if (hiddenSections != null)
189       {
190         if (hiddenSections[0] != null
191                 && exportSettings.isExportHiddenColumns())
192         {
193           jsonAlignmentPojo.getAppSettings().put("hiddenCols",
194                   String.valueOf(hiddenSections[0]));
195         }
196         if (hiddenSections[1] != null
197                 && exportSettings.isExportHiddenSequences())
198         {
199           jsonAlignmentPojo.getAppSettings().put("hiddenSeqs",
200                   String.valueOf(hiddenSections[1]));
201         }
202       }
203
204       if (exportSettings.isExportAnnotations())
205       {
206         jsonAlignmentPojo
207                 .setAlignAnnotation(annotationToJsonPojo(annotations));
208       }
209
210       if (exportSettings.isExportFeatures())
211       {
212         jsonAlignmentPojo
213                 .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr));
214       }
215
216       if (exportSettings.isExportGroups() && seqGroups != null
217               && seqGroups.size() > 0)
218       {
219         for (SequenceGroup seqGrp : seqGroups)
220         {
221           SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo();
222           seqGrpPojo.setGroupName(seqGrp.getName());
223           seqGrpPojo.setColourScheme(ColourSchemeProperty
224                   .getColourName(seqGrp.cs));
225           seqGrpPojo.setColourText(seqGrp.getColourText());
226           seqGrpPojo.setDescription(seqGrp.getDescription());
227           seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes());
228           seqGrpPojo.setDisplayText(seqGrp.getDisplayText());
229           seqGrpPojo.setEndRes(seqGrp.getEndRes());
230           seqGrpPojo.setStartRes(seqGrp.getStartRes());
231           seqGrpPojo.setShowNonconserved(seqGrp.getShowNonconserved());
232           for (SequenceI seq : seqGrp.getSequences())
233           {
234             seqGrpPojo.getSequenceRefs()
235                     .add(String.valueOf(seq.hashCode()));
236           }
237           jsonAlignmentPojo.getSeqGroups().add(seqGrpPojo);
238         }
239       }
240       org.json.JSONObject generatedJSon = new org.json.JSONObject(
241               jsonAlignmentPojo);
242       jsonOutput = generatedJSon.toString();
243       return jsonOutput.replaceAll("xstart", "xStart").replaceAll("xend",
244               "xEnd");
245     } catch (Exception e)
246     {
247       e.printStackTrace();
248     }
249     return jsonOutput;
250   }
251
252   public String[] getHiddenSections()
253   {
254     String[] hiddenSections = new String[2];
255     if (getViewport() == null)
256     {
257       return null;
258     }
259
260     // hidden column business
261     if (getViewport().hasHiddenColumns())
262     {
263       List<int[]> hiddenCols = getViewport().getColumnSelection()
264               .getHiddenColumns();
265       StringBuilder hiddenColsBuilder = new StringBuilder();
266       for (int[] range : hiddenCols)
267       {
268         hiddenColsBuilder.append(";").append(range[0]).append("-")
269                 .append(range[1]);
270       }
271
272       hiddenColsBuilder.deleteCharAt(0);
273       hiddenSections[0] = hiddenColsBuilder.toString();
274     }
275
276     // hidden rows/seqs business
277     HiddenSequences hiddenSeqsObj = getViewport().getAlignment()
278             .getHiddenSequences();
279     if (hiddenSeqsObj == null || hiddenSeqsObj.hiddenSequences == null)
280     {
281       return hiddenSections;
282     }
283
284     SequenceI[] hiddenSeqs = hiddenSeqsObj.hiddenSequences;
285     StringBuilder hiddenSeqsBuilder = new StringBuilder();
286     for (SequenceI hiddenSeq : hiddenSeqs)
287     {
288       if (hiddenSeq != null)
289       {
290         hiddenSeqsBuilder.append(";").append(hiddenSeq.hashCode());
291       }
292     }
293     if (hiddenSeqsBuilder.length() > 0)
294     {
295       hiddenSeqsBuilder.deleteCharAt(0);
296     }
297     hiddenSections[1] = hiddenSeqsBuilder.toString();
298
299     return hiddenSections;
300   }
301
302   public List<SequenceFeaturesPojo> sequenceFeatureToJsonPojo(
303           List<SequenceI> seqs, FeatureRenderer fr)
304   {
305     displayedFeatures = (fr == null) ? null : fr.getFeaturesDisplayed();
306     List<SequenceFeaturesPojo> sequenceFeaturesPojo = new ArrayList<SequenceFeaturesPojo>();
307     for (SequenceI seq : seqs)
308     {
309       SequenceI dataSetSequence = seq.getDatasetSequence();
310       SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null
311               : seq.getDatasetSequence().getSequenceFeatures();
312
313       seqFeatures = (seqFeatures == null) ? seq.getSequenceFeatures()
314               : seqFeatures;
315       if (seqFeatures == null)
316       {
317         continue;
318       }
319
320       for (SequenceFeature sf : seqFeatures)
321       {
322         if (displayedFeatures != null
323                 && displayedFeatures.isVisible(sf.getType()))
324         {
325           SequenceFeaturesPojo jsonFeature = new SequenceFeaturesPojo(
326                   String.valueOf(seq.hashCode()));
327
328           String featureColour = (fr == null) ? null : jalview.util.Format
329                   .getHexString(fr.findFeatureColour(Color.white, seq,
330                           seq.findIndex(sf.getBegin())));
331           jsonFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
332           jsonFeature.setXend(seq.findIndex(sf.getEnd()));
333           jsonFeature.setType(sf.getType());
334           jsonFeature.setDescription(sf.getDescription());
335           jsonFeature.setLinks(sf.links);
336           jsonFeature.setOtherDetails(sf.otherDetails);
337           jsonFeature.setScore(sf.getScore());
338           jsonFeature.setFillColor(featureColour);
339           jsonFeature.setFeatureGroup(sf.getFeatureGroup());
340           sequenceFeaturesPojo.add(jsonFeature);
341         }
342       }
343     }
344     return sequenceFeaturesPojo;
345   }
346
347   public static List<AlignmentAnnotationPojo> annotationToJsonPojo(
348           Vector<AlignmentAnnotation> annotations)
349   {
350     List<AlignmentAnnotationPojo> jsonAnnotations = new ArrayList<AlignmentAnnotationPojo>();
351     if (annotations == null)
352     {
353       return jsonAnnotations;
354     }
355     for (AlignmentAnnotation annot : annotations)
356     {
357       AlignmentAnnotationPojo alignAnnotPojo = new AlignmentAnnotationPojo();
358       alignAnnotPojo.setDescription(annot.description);
359       alignAnnotPojo.setLabel(annot.label);
360       for (Annotation annotation : annot.annotations)
361       {
362         AnnotationPojo annotationPojo = new AnnotationPojo();
363         if (annotation != null)
364         {
365           annotationPojo.setDescription(annotation.description);
366           annotationPojo.setValue(annotation.value);
367           annotationPojo
368                   .setSecondaryStructure(annotation.secondaryStructure);
369           annotationPojo.setDisplayCharacter(annotation.displayCharacter);
370           alignAnnotPojo.getAnnotations().add(annotationPojo);
371         }
372         else
373         {
374           alignAnnotPojo.getAnnotations().add(annotationPojo);
375         }
376       }
377       jsonAnnotations.add(alignAnnotPojo);
378     }
379     return jsonAnnotations;
380   }
381
382   @SuppressWarnings("unchecked")
383   public JSONFile parse(Reader jsonAlignmentString)
384   {
385     try
386     {
387       JSONParser jsonParser = new JSONParser();
388       JSONObject alignmentJsonObj = (JSONObject) jsonParser
389               .parse(jsonAlignmentString);
390       JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs");
391       JSONArray alAnnotJsonArray = (JSONArray) alignmentJsonObj
392               .get("alignAnnotation");
393       JSONArray jsonSeqArray = (JSONArray) alignmentJsonObj
394               .get("seqFeatures");
395       JSONArray seqGrpJsonArray = (JSONArray) alignmentJsonObj
396               .get("seqGroups");
397       JSONObject jvSettingsJsonObj = (JSONObject) alignmentJsonObj
398               .get("appSettings");
399
400       if (jvSettingsJsonObj != null)
401       {
402         String jsColourScheme = (String) jvSettingsJsonObj
403                 .get("globalColorScheme");
404         Boolean showFeatures = Boolean.valueOf(jvSettingsJsonObj.get(
405                 "showSeqFeatures").toString());
406         setColourScheme(getJalviewColorScheme(jsColourScheme));
407         setShowSeqFeatures(showFeatures);
408         parseHiddenSeqRefsAsList(jvSettingsJsonObj);
409         parseHiddenCols(jvSettingsJsonObj);
410       }
411
412       hiddenSequences = new ArrayList<SequenceI>();
413       seqMap = new Hashtable<String, Sequence>();
414       for (Iterator<JSONObject> sequenceIter = seqJsonArray.iterator(); sequenceIter
415               .hasNext();)
416       {
417         JSONObject sequence = sequenceIter.next();
418         String sequcenceString = sequence.get("seq").toString();
419         String sequenceName = sequence.get("name").toString();
420         String seqUniqueId = sequence.get("id").toString();
421         int start = Integer.valueOf(sequence.get("start").toString());
422         int end = Integer.valueOf(sequence.get("end").toString());
423         Sequence seq = new Sequence(sequenceName, sequcenceString, start,
424                 end);
425         if (hiddenSeqRefs != null && hiddenSeqRefs.contains(seqUniqueId))
426         {
427           hiddenSequences.add(seq);
428         }
429         seqs.add(seq);
430         seqMap.put(seqUniqueId, seq);
431       }
432       parseFeatures(jsonSeqArray);
433
434       for (Iterator<JSONObject> seqGrpIter = seqGrpJsonArray.iterator(); seqGrpIter
435               .hasNext();)
436       {
437         JSONObject seqGrpObj = seqGrpIter.next();
438         String grpName = seqGrpObj.get("groupName").toString();
439         String colourScheme = seqGrpObj.get("colourScheme").toString();
440         String description = (seqGrpObj.get("description") == null) ? null
441                 : seqGrpObj.get("description").toString();
442         boolean displayBoxes = Boolean.valueOf(seqGrpObj
443                 .get("displayBoxes").toString());
444         boolean displayText = Boolean.valueOf(seqGrpObj.get("displayText")
445                 .toString());
446         boolean colourText = Boolean.valueOf(seqGrpObj.get("colourText")
447                 .toString());
448         boolean showNonconserved = Boolean.valueOf(seqGrpObj.get(
449                 "showNonconserved").toString());
450         int startRes = Integer
451                 .valueOf(seqGrpObj.get("startRes").toString());
452         int endRes = Integer.valueOf(seqGrpObj.get("endRes").toString());
453         JSONArray sequenceRefs = (JSONArray) seqGrpObj.get("sequenceRefs");
454
455         ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
456         if (sequenceRefs.size() > 0)
457         {
458           Iterator<String> seqHashIter = sequenceRefs.iterator();
459           while (seqHashIter.hasNext())
460           {
461             String seqHash = seqHashIter.next();
462             Sequence sequence = seqMap.get(seqHash);
463             if (sequence != null)
464             {
465               grpSeqs.add(sequence);
466             }
467           }
468         }
469         ColourSchemeI grpColourScheme = getJalviewColorScheme(colourScheme);
470         SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName,
471                 grpColourScheme, displayBoxes, displayText, colourText,
472                 startRes, endRes);
473         seqGrp.setShowNonconserved(showNonconserved);
474         seqGrp.setDescription(description);
475         this.seqGroups.add(seqGrp);
476
477       }
478
479       for (Iterator<JSONObject> alAnnotIter = alAnnotJsonArray.iterator(); alAnnotIter
480               .hasNext();)
481       {
482         JSONObject alAnnot = alAnnotIter.next();
483         JSONArray annotJsonArray = (JSONArray) alAnnot.get("annotations");
484         Annotation[] annotations = new Annotation[annotJsonArray.size()];
485         int count = 0;
486         for (Iterator<JSONObject> annotIter = annotJsonArray.iterator(); annotIter
487                 .hasNext();)
488         {
489           JSONObject annot = annotIter.next();
490           if (annot == null)
491           {
492             annotations[count] = null;
493           }
494           else
495           {
496             float val = annot.get("value") == null ? null : Float
497                     .valueOf(annot.get("value").toString());
498             String desc = annot.get("description") == null ? null : annot
499                     .get("description").toString();
500
501             char ss = annot.get("secondaryStructure") == null ? ' ' : annot
502                     .get("secondaryStructure").toString().charAt(0);
503             String displayChar = annot.get("displayCharacter") == null ? ""
504                     : annot.get("displayCharacter").toString();
505
506             annotations[count] = new Annotation(displayChar, desc, ss, val);
507           }
508           ++count;
509         }
510
511         AlignmentAnnotation alignAnnot = new AlignmentAnnotation(alAnnot
512                 .get("label").toString(), alAnnot.get("description")
513                 .toString(), annotations);
514         this.annotations.add(alignAnnot);
515       }
516
517     } catch (Exception e)
518     {
519       e.printStackTrace();
520     }
521     return this;
522   }
523
524   public void parseHiddenSeqRefsAsList(JSONObject jvSettingsJson)
525   {
526     hiddenSeqRefs = new ArrayList<String>();
527     String hiddenSeqs = (String) jvSettingsJson.get("hiddenSeqs");
528     if (hiddenSeqs != null && !hiddenSeqs.isEmpty())
529     {
530       String[] seqRefs = hiddenSeqs.split(";");
531       for (String seqRef : seqRefs)
532       {
533         hiddenSeqRefs.add(seqRef);
534       }
535     }
536   }
537
538   public void parseHiddenCols(JSONObject jvSettingsJson)
539   {
540     String hiddenCols = (String) jvSettingsJson.get("hiddenCols");
541     if (hiddenCols != null && !hiddenCols.isEmpty())
542     {
543       columnSelection = new ColumnSelection();
544       String[] rangeStrings = hiddenCols.split(";");
545       for (String rangeString : rangeStrings)
546       {
547         String[] range = rangeString.split("-");
548         columnSelection.hideColumns(Integer.valueOf(range[0]),
549                 Integer.valueOf(range[1]));
550       }
551     }
552   }
553
554   @SuppressWarnings("unchecked")
555   private void parseFeatures(JSONArray jsonSeqFeatures)
556   {
557     if (jsonSeqFeatures != null)
558     {
559       displayedFeatures = new FeaturesDisplayed();
560       for (Iterator<JSONObject> seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr
561               .hasNext();)
562       {
563         JSONObject jsonFeature = seqFeatureItr.next();
564         Long begin = (Long) jsonFeature.get("xStart");
565         Long end = (Long) jsonFeature.get("xEnd");
566         String type = (String) jsonFeature.get("type");
567         String featureGrp = (String) jsonFeature.get("featureGroup");
568         String descripiton = (String) jsonFeature.get("description");
569         String seqRef = (String) jsonFeature.get("sequenceRef");
570         Float score = Float.valueOf(jsonFeature.get("score").toString());
571
572         Sequence seq = seqMap.get(seqRef);
573         SequenceFeature sequenceFeature = new SequenceFeature();
574         JSONArray linksJsonArray = (JSONArray) jsonFeature.get("links");
575         if (linksJsonArray != null && linksJsonArray.size() > 0)
576         {
577           Iterator<String> linkList = linksJsonArray.iterator();
578           while (linkList.hasNext())
579           {
580             String link = linkList.next();
581             sequenceFeature.addLink(link);
582           }
583         }
584         sequenceFeature.setFeatureGroup(featureGrp);
585         sequenceFeature.setScore(score);
586         sequenceFeature.setDescription(descripiton);
587         sequenceFeature.setType(type);
588         sequenceFeature.setBegin(seq.findPosition(begin.intValue()));
589         sequenceFeature.setEnd(seq.findPosition(end.intValue()) - 1);
590         seq.addSequenceFeature(sequenceFeature);
591         displayedFeatures.setVisible(type);
592       }
593     }
594   }
595
596   public static ColourSchemeI getJalviewColorScheme(
597           String bioJsColourSchemeName)
598   {
599     ColourSchemeI jalviewColor = null;
600     for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
601             .values())
602     {
603       if (cs.getBioJsName().equalsIgnoreCase(bioJsColourSchemeName))
604       {
605         jalviewColor = cs.getJvColourScheme();
606         break;
607       }
608     }
609     return jalviewColor;
610   }
611
612   public String getGlobalColorScheme()
613   {
614     return globalColorScheme;
615   }
616
617   public void setGlobalColorScheme(String globalColorScheme)
618   {
619     this.globalColorScheme = globalColorScheme;
620   }
621
622   public ColourSchemeI getColourScheme()
623   {
624     return colourScheme;
625   }
626
627   public void setColourScheme(ColourSchemeI colourScheme)
628   {
629     this.colourScheme = colourScheme;
630   }
631
632   @Override
633   public FeaturesDisplayedI getDisplayedFeatures()
634   {
635     return displayedFeatures;
636   }
637
638   public void setDisplayedFeatures(FeaturesDisplayedI displayedFeatures)
639   {
640     this.displayedFeatures = displayedFeatures;
641   }
642
643   public void configureForView(AlignmentViewPanel avpanel)
644   {
645     super.configureForView(avpanel);
646     AlignViewportI viewport = avpanel.getAlignViewport();
647     AlignmentI alignment = viewport.getAlignment();
648     AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
649
650     seqGroups = alignment.getGroups();
651     fr = avpanel.cloneFeatureRenderer();
652
653     // Add non auto calculated annotation to AlignFile
654     for (AlignmentAnnotation annot : annots)
655     {
656       if (annot != null && !annot.autoCalculated)
657       {
658         if (!annot.visible)
659         {
660           continue;
661         }
662         annotations.add(annot);
663       }
664     }
665     globalColorScheme = ColourSchemeProperty.getColourName(viewport
666             .getGlobalColourScheme());
667     setDisplayedFeatures(viewport.getFeaturesDisplayed());
668     showSeqFeatures = viewport.isShowSequenceFeatures();
669
670   }
671
672   public boolean isShowSeqFeatures()
673   {
674     return showSeqFeatures;
675   }
676
677   public void setShowSeqFeatures(boolean showSeqFeatures)
678   {
679     this.showSeqFeatures = showSeqFeatures;
680   }
681
682   public Vector<AlignmentAnnotation> getAnnotations()
683   {
684     return annotations;
685   }
686
687   public List<int[]> getHiddenColumns()
688   {
689     return hiddenColumns;
690   }
691
692   public ColumnSelection getColumnSelection()
693   {
694     return columnSelection;
695   }
696
697   public void setColumnSelection(ColumnSelection columnSelection)
698   {
699     this.columnSelection = columnSelection;
700   }
701
702   public SequenceI[] getHiddenSequences()
703   {
704     if (hiddenSequences == null || hiddenSequences.isEmpty())
705     {
706       return new SequenceI[] {};
707     }
708     synchronized (hiddenSequences)
709     {
710       return hiddenSequences.toArray(new SequenceI[hiddenSequences.size()]);
711     }
712   }
713
714   public void setHiddenSequences(ArrayList<SequenceI> hiddenSequences)
715   {
716     this.hiddenSequences = hiddenSequences;
717   }
718
719   public class JSONExportSettings
720   {
721     private boolean exportSequence;
722
723     private boolean exportSequenceFeatures;
724
725     private boolean exportAnnotations;
726
727     private boolean exportGroups;
728
729     private boolean exportJalviewSettings;
730
731     public boolean isExportSequence()
732     {
733       return exportSequence;
734     }
735
736     public void setExportSequence(boolean exportSequence)
737     {
738       this.exportSequence = exportSequence;
739     }
740
741     public boolean isExportSequenceFeatures()
742     {
743       return exportSequenceFeatures;
744     }
745
746     public void setExportSequenceFeatures(boolean exportSequenceFeatures)
747     {
748       this.exportSequenceFeatures = exportSequenceFeatures;
749     }
750
751     public boolean isExportAnnotations()
752     {
753       return exportAnnotations;
754     }
755
756     public void setExportAnnotations(boolean exportAnnotations)
757     {
758       this.exportAnnotations = exportAnnotations;
759     }
760
761     public boolean isExportGroups()
762     {
763       return exportGroups;
764     }
765
766     public void setExportGroups(boolean exportGroups)
767     {
768       this.exportGroups = exportGroups;
769     }
770
771     public boolean isExportJalviewSettings()
772     {
773       return exportJalviewSettings;
774     }
775
776     public void setExportJalviewSettings(boolean exportJalviewSettings)
777     {
778       this.exportJalviewSettings = exportJalviewSettings;
779     }
780   }
781 }