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