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