2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
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
10 * of the License, or (at your option) any later version.
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.
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.
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;
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;
60 import org.json.simple.JSONArray;
61 import org.json.simple.JSONObject;
62 import org.json.simple.parser.JSONParser;
64 public class JSONFile extends AlignFile implements ComplexAlignFile
66 private ColourSchemeI colourScheme;
68 private static String version = new BuildDetails().getVersion();
70 private String webstartUrl = "http://www.jalview.org/services/launchApp";
72 private String application = "Jalview";
74 public static final String FILE_EXT = "json";
76 public static final String FILE_DESC = "JSON";
78 private String globalColorScheme;
80 private boolean showSeqFeatures;
82 private Hashtable<String, Sequence> seqMap;
84 private FeaturesDisplayedI displayedFeatures;
86 private FeatureRenderer fr;
88 private List<int[]> hiddenColumns;
90 private ColumnSelection columnSelection;
92 private List<String> hiddenSeqRefs;
94 private ArrayList<SequenceI> hiddenSequences;
101 public JSONFile(FileParse source) throws IOException
106 public JSONFile(String inFile, String type) throws IOException
112 public void parse() throws IOException
119 public String print()
121 String jsonOutput = null;
124 AlignmentPojo jsonAlignmentPojo = new AlignmentPojo();
125 AlignExportSettingI exportSettings = getExportSettings();
127 // if no export settings were supplied use the following with all values
128 // defaulting to true
129 if (exportSettings == null)
131 exportSettings = new AlignExportSettingI()
134 public boolean isExportHiddenSequences()
140 public boolean isExportHiddenColumns()
146 public boolean isExportGroups()
152 public boolean isExportFeatures()
158 public boolean isExportAnnotations()
164 public boolean isCancelled()
172 for (SequenceI seq : seqs)
174 StringBuilder name = new StringBuilder();
175 name.append(seq.getName()).append("/").append(seq.getStart())
176 .append("-").append(seq.getEnd());
177 SequencePojo jsonSeqPojo = new SequencePojo();
178 jsonSeqPojo.setId(String.valueOf(seq.hashCode()));
179 jsonSeqPojo.setOrder(++count);
180 jsonSeqPojo.setEnd(seq.getEnd());
181 jsonSeqPojo.setStart(seq.getStart());
182 jsonSeqPojo.setName(name.toString());
183 jsonSeqPojo.setSeq(seq.getSequenceAsString());
184 jsonAlignmentPojo.getSeqs().add(jsonSeqPojo);
186 jsonAlignmentPojo.setGlobalColorScheme(globalColorScheme);
187 jsonAlignmentPojo.getAppSettings().put("application", application);
188 jsonAlignmentPojo.getAppSettings().put("version", version);
189 jsonAlignmentPojo.getAppSettings().put("webStartUrl", webstartUrl);
190 jsonAlignmentPojo.getAppSettings().put("showSeqFeatures",
191 String.valueOf(showSeqFeatures));
193 String[] hiddenSections = getHiddenSections();
194 if (hiddenSections != null)
196 if (hiddenSections[0] != null
197 && exportSettings.isExportHiddenColumns())
199 jsonAlignmentPojo.getAppSettings().put("hiddenCols",
200 String.valueOf(hiddenSections[0]));
202 if (hiddenSections[1] != null
203 && exportSettings.isExportHiddenSequences())
205 jsonAlignmentPojo.getAppSettings().put("hiddenSeqs",
206 String.valueOf(hiddenSections[1]));
210 if (exportSettings.isExportAnnotations())
213 .setAlignAnnotation(annotationToJsonPojo(annotations));
216 if (exportSettings.isExportFeatures())
219 .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr));
222 if (exportSettings.isExportGroups() && seqGroups != null
223 && seqGroups.size() > 0)
225 for (SequenceGroup seqGrp : seqGroups)
227 SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo();
228 seqGrpPojo.setGroupName(seqGrp.getName());
229 seqGrpPojo.setColourScheme(ColourSchemeProperty
230 .getColourName(seqGrp.cs));
231 seqGrpPojo.setColourText(seqGrp.getColourText());
232 seqGrpPojo.setDescription(seqGrp.getDescription());
233 seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes());
234 seqGrpPojo.setDisplayText(seqGrp.getDisplayText());
235 seqGrpPojo.setEndRes(seqGrp.getEndRes());
236 seqGrpPojo.setStartRes(seqGrp.getStartRes());
237 seqGrpPojo.setShowNonconserved(seqGrp.getShowNonconserved());
238 for (SequenceI seq : seqGrp.getSequences())
240 seqGrpPojo.getSequenceRefs()
241 .add(String.valueOf(seq.hashCode()));
243 jsonAlignmentPojo.getSeqGroups().add(seqGrpPojo);
246 org.json.JSONObject generatedJSon = new org.json.JSONObject(
248 jsonOutput = generatedJSon.toString();
249 return jsonOutput.replaceAll("xstart", "xStart").replaceAll("xend",
251 } catch (Exception e)
258 public String[] getHiddenSections()
260 String[] hiddenSections = new String[2];
261 if (getViewport() == null)
266 // hidden column business
267 if (getViewport().hasHiddenColumns())
269 List<int[]> hiddenCols = getViewport().getColumnSelection()
271 StringBuilder hiddenColsBuilder = new StringBuilder();
272 for (int[] range : hiddenCols)
274 hiddenColsBuilder.append(";").append(range[0]).append("-")
278 hiddenColsBuilder.deleteCharAt(0);
279 hiddenSections[0] = hiddenColsBuilder.toString();
282 // hidden rows/seqs business
283 HiddenSequences hiddenSeqsObj = getViewport().getAlignment()
284 .getHiddenSequences();
285 if (hiddenSeqsObj == null || hiddenSeqsObj.hiddenSequences == null)
287 return hiddenSections;
290 SequenceI[] hiddenSeqs = hiddenSeqsObj.hiddenSequences;
291 StringBuilder hiddenSeqsBuilder = new StringBuilder();
292 for (SequenceI hiddenSeq : hiddenSeqs)
294 if (hiddenSeq != null)
296 hiddenSeqsBuilder.append(";").append(hiddenSeq.hashCode());
299 if (hiddenSeqsBuilder.length() > 0)
301 hiddenSeqsBuilder.deleteCharAt(0);
303 hiddenSections[1] = hiddenSeqsBuilder.toString();
305 return hiddenSections;
308 public List<SequenceFeaturesPojo> sequenceFeatureToJsonPojo(
309 List<SequenceI> seqs, FeatureRenderer fr)
311 displayedFeatures = (fr == null) ? null : fr.getFeaturesDisplayed();
312 List<SequenceFeaturesPojo> sequenceFeaturesPojo = new ArrayList<SequenceFeaturesPojo>();
313 for (SequenceI seq : seqs)
315 SequenceI dataSetSequence = seq.getDatasetSequence();
316 SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null
317 : seq.getDatasetSequence().getSequenceFeatures();
319 seqFeatures = (seqFeatures == null) ? seq.getSequenceFeatures()
321 if (seqFeatures == null)
326 for (SequenceFeature sf : seqFeatures)
328 if (displayedFeatures != null
329 && displayedFeatures.isVisible(sf.getType()))
331 SequenceFeaturesPojo jsonFeature = new SequenceFeaturesPojo(
332 String.valueOf(seq.hashCode()));
334 String featureColour = (fr == null) ? null : jalview.util.Format
335 .getHexString(fr.findFeatureColour(Color.white, seq,
336 seq.findIndex(sf.getBegin())));
337 jsonFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
338 jsonFeature.setXend(seq.findIndex(sf.getEnd()));
339 jsonFeature.setType(sf.getType());
340 jsonFeature.setDescription(sf.getDescription());
341 jsonFeature.setLinks(sf.links);
342 jsonFeature.setOtherDetails(sf.otherDetails);
343 jsonFeature.setScore(sf.getScore());
344 jsonFeature.setFillColor(featureColour);
345 jsonFeature.setFeatureGroup(sf.getFeatureGroup());
346 sequenceFeaturesPojo.add(jsonFeature);
350 return sequenceFeaturesPojo;
353 public static List<AlignmentAnnotationPojo> annotationToJsonPojo(
354 Vector<AlignmentAnnotation> annotations)
356 List<AlignmentAnnotationPojo> jsonAnnotations = new ArrayList<AlignmentAnnotationPojo>();
357 if (annotations == null)
359 return jsonAnnotations;
361 for (AlignmentAnnotation annot : annotations)
363 AlignmentAnnotationPojo alignAnnotPojo = new AlignmentAnnotationPojo();
364 alignAnnotPojo.setDescription(annot.description);
365 alignAnnotPojo.setLabel(annot.label);
366 for (Annotation annotation : annot.annotations)
368 AnnotationPojo annotationPojo = new AnnotationPojo();
369 if (annotation != null)
371 annotationPojo.setDescription(annotation.description);
372 annotationPojo.setValue(annotation.value);
374 .setSecondaryStructure(annotation.secondaryStructure);
375 annotationPojo.setDisplayCharacter(annotation.displayCharacter);
376 alignAnnotPojo.getAnnotations().add(annotationPojo);
380 alignAnnotPojo.getAnnotations().add(annotationPojo);
383 jsonAnnotations.add(alignAnnotPojo);
385 return jsonAnnotations;
388 @SuppressWarnings("unchecked")
389 public JSONFile parse(Reader jsonAlignmentString)
393 JSONParser jsonParser = new JSONParser();
394 JSONObject alignmentJsonObj = (JSONObject) jsonParser
395 .parse(jsonAlignmentString);
396 JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs");
397 JSONArray alAnnotJsonArray = (JSONArray) alignmentJsonObj
398 .get("alignAnnotation");
399 JSONArray jsonSeqArray = (JSONArray) alignmentJsonObj
401 JSONArray seqGrpJsonArray = (JSONArray) alignmentJsonObj
403 JSONObject jvSettingsJsonObj = (JSONObject) alignmentJsonObj
406 if (jvSettingsJsonObj != null)
408 String jsColourScheme = (String) jvSettingsJsonObj
409 .get("globalColorScheme");
410 Boolean showFeatures = Boolean.valueOf(jvSettingsJsonObj.get(
411 "showSeqFeatures").toString());
412 setColourScheme(getJalviewColorScheme(jsColourScheme));
413 setShowSeqFeatures(showFeatures);
414 parseHiddenSeqRefsAsList(jvSettingsJsonObj);
415 parseHiddenCols(jvSettingsJsonObj);
418 hiddenSequences = new ArrayList<SequenceI>();
419 seqMap = new Hashtable<String, Sequence>();
420 for (Iterator<JSONObject> sequenceIter = seqJsonArray.iterator(); sequenceIter
423 JSONObject sequence = sequenceIter.next();
424 String sequcenceString = sequence.get("seq").toString();
425 String sequenceName = sequence.get("name").toString();
426 String seqUniqueId = sequence.get("id").toString();
427 int start = Integer.valueOf(sequence.get("start").toString());
428 int end = Integer.valueOf(sequence.get("end").toString());
429 Sequence seq = new Sequence(sequenceName, sequcenceString, start,
431 if (hiddenSeqRefs != null && hiddenSeqRefs.contains(seqUniqueId))
433 hiddenSequences.add(seq);
436 seqMap.put(seqUniqueId, seq);
438 parseFeatures(jsonSeqArray);
440 for (Iterator<JSONObject> seqGrpIter = seqGrpJsonArray.iterator(); seqGrpIter
443 JSONObject seqGrpObj = seqGrpIter.next();
444 String grpName = seqGrpObj.get("groupName").toString();
445 String colourScheme = seqGrpObj.get("colourScheme").toString();
446 String description = (seqGrpObj.get("description") == null) ? null
447 : seqGrpObj.get("description").toString();
448 boolean displayBoxes = Boolean.valueOf(seqGrpObj
449 .get("displayBoxes").toString());
450 boolean displayText = Boolean.valueOf(seqGrpObj.get("displayText")
452 boolean colourText = Boolean.valueOf(seqGrpObj.get("colourText")
454 boolean showNonconserved = Boolean.valueOf(seqGrpObj.get(
455 "showNonconserved").toString());
456 int startRes = Integer
457 .valueOf(seqGrpObj.get("startRes").toString());
458 int endRes = Integer.valueOf(seqGrpObj.get("endRes").toString());
459 JSONArray sequenceRefs = (JSONArray) seqGrpObj.get("sequenceRefs");
461 ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
462 if (sequenceRefs.size() > 0)
464 Iterator<String> seqHashIter = sequenceRefs.iterator();
465 while (seqHashIter.hasNext())
467 String seqHash = seqHashIter.next();
468 Sequence sequence = seqMap.get(seqHash);
469 if (sequence != null)
471 grpSeqs.add(sequence);
475 ColourSchemeI grpColourScheme = getJalviewColorScheme(colourScheme);
476 SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName,
477 grpColourScheme, displayBoxes, displayText, colourText,
479 seqGrp.setShowNonconserved(showNonconserved);
480 seqGrp.setDescription(description);
481 this.seqGroups.add(seqGrp);
485 for (Iterator<JSONObject> alAnnotIter = alAnnotJsonArray.iterator(); alAnnotIter
488 JSONObject alAnnot = alAnnotIter.next();
489 JSONArray annotJsonArray = (JSONArray) alAnnot.get("annotations");
490 Annotation[] annotations = new Annotation[annotJsonArray.size()];
492 for (Iterator<JSONObject> annotIter = annotJsonArray.iterator(); annotIter
495 JSONObject annot = annotIter.next();
498 annotations[count] = null;
502 float val = annot.get("value") == null ? null : Float
503 .valueOf(annot.get("value").toString());
504 String desc = annot.get("description") == null ? null : annot
505 .get("description").toString();
507 char ss = annot.get("secondaryStructure") == null ? ' ' : annot
508 .get("secondaryStructure").toString().charAt(0);
509 String displayChar = annot.get("displayCharacter") == null ? ""
510 : annot.get("displayCharacter").toString();
512 annotations[count] = new Annotation(displayChar, desc, ss, val);
517 AlignmentAnnotation alignAnnot = new AlignmentAnnotation(alAnnot
518 .get("label").toString(), alAnnot.get("description")
519 .toString(), annotations);
520 this.annotations.add(alignAnnot);
523 } catch (Exception e)
530 public void parseHiddenSeqRefsAsList(JSONObject jvSettingsJson)
532 hiddenSeqRefs = new ArrayList<String>();
533 String hiddenSeqs = (String) jvSettingsJson.get("hiddenSeqs");
534 if (hiddenSeqs != null && !hiddenSeqs.isEmpty())
536 String[] seqRefs = hiddenSeqs.split(";");
537 for (String seqRef : seqRefs)
539 hiddenSeqRefs.add(seqRef);
544 public void parseHiddenCols(JSONObject jvSettingsJson)
546 String hiddenCols = (String) jvSettingsJson.get("hiddenCols");
547 if (hiddenCols != null && !hiddenCols.isEmpty())
549 columnSelection = new ColumnSelection();
550 String[] rangeStrings = hiddenCols.split(";");
551 for (String rangeString : rangeStrings)
553 String[] range = rangeString.split("-");
554 columnSelection.hideColumns(Integer.valueOf(range[0]),
555 Integer.valueOf(range[1]));
560 @SuppressWarnings("unchecked")
561 private void parseFeatures(JSONArray jsonSeqFeatures)
563 if (jsonSeqFeatures != null)
565 displayedFeatures = new FeaturesDisplayed();
566 for (Iterator<JSONObject> seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr
569 JSONObject jsonFeature = seqFeatureItr.next();
570 Long begin = (Long) jsonFeature.get("xStart");
571 Long end = (Long) jsonFeature.get("xEnd");
572 String type = (String) jsonFeature.get("type");
573 String featureGrp = (String) jsonFeature.get("featureGroup");
574 String descripiton = (String) jsonFeature.get("description");
575 String seqRef = (String) jsonFeature.get("sequenceRef");
576 Float score = Float.valueOf(jsonFeature.get("score").toString());
578 Sequence seq = seqMap.get(seqRef);
579 SequenceFeature sequenceFeature = new SequenceFeature();
580 JSONArray linksJsonArray = (JSONArray) jsonFeature.get("links");
581 if (linksJsonArray != null && linksJsonArray.size() > 0)
583 Iterator<String> linkList = linksJsonArray.iterator();
584 while (linkList.hasNext())
586 String link = linkList.next();
587 sequenceFeature.addLink(link);
590 sequenceFeature.setFeatureGroup(featureGrp);
591 sequenceFeature.setScore(score);
592 sequenceFeature.setDescription(descripiton);
593 sequenceFeature.setType(type);
594 sequenceFeature.setBegin(seq.findPosition(begin.intValue()));
595 sequenceFeature.setEnd(seq.findPosition(end.intValue()) - 1);
596 seq.addSequenceFeature(sequenceFeature);
597 displayedFeatures.setVisible(type);
602 public static ColourSchemeI getJalviewColorScheme(
603 String bioJsColourSchemeName)
605 ColourSchemeI jalviewColor = null;
606 for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
609 if (cs.getBioJsName().equalsIgnoreCase(bioJsColourSchemeName))
611 jalviewColor = cs.getJvColourScheme();
618 public String getGlobalColorScheme()
620 return globalColorScheme;
623 public void setGlobalColorScheme(String globalColorScheme)
625 this.globalColorScheme = globalColorScheme;
628 public ColourSchemeI getColourScheme()
633 public void setColourScheme(ColourSchemeI colourScheme)
635 this.colourScheme = colourScheme;
639 public FeaturesDisplayedI getDisplayedFeatures()
641 return displayedFeatures;
644 public void setDisplayedFeatures(FeaturesDisplayedI displayedFeatures)
646 this.displayedFeatures = displayedFeatures;
649 public void configureForView(AlignmentViewPanel avpanel)
651 super.configureForView(avpanel);
652 AlignViewportI viewport = avpanel.getAlignViewport();
653 AlignmentI alignment = viewport.getAlignment();
654 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
656 seqGroups = alignment.getGroups();
657 fr = avpanel.cloneFeatureRenderer();
659 // Add non auto calculated annotation to AlignFile
660 for (AlignmentAnnotation annot : annots)
662 if (annot != null && !annot.autoCalculated)
668 annotations.add(annot);
671 globalColorScheme = ColourSchemeProperty.getColourName(viewport
672 .getGlobalColourScheme());
673 setDisplayedFeatures(viewport.getFeaturesDisplayed());
674 showSeqFeatures = viewport.isShowSequenceFeatures();
678 public boolean isShowSeqFeatures()
680 return showSeqFeatures;
683 public void setShowSeqFeatures(boolean showSeqFeatures)
685 this.showSeqFeatures = showSeqFeatures;
688 public Vector<AlignmentAnnotation> getAnnotations()
693 public List<int[]> getHiddenColumns()
695 return hiddenColumns;
698 public ColumnSelection getColumnSelection()
700 return columnSelection;
703 public void setColumnSelection(ColumnSelection columnSelection)
705 this.columnSelection = columnSelection;
708 public SequenceI[] getHiddenSequences()
710 if (hiddenSequences == null || hiddenSequences.isEmpty())
712 return new SequenceI[] {};
714 synchronized (hiddenSequences)
716 return hiddenSequences.toArray(new SequenceI[hiddenSequences.size()]);
720 public void setHiddenSequences(ArrayList<SequenceI> hiddenSequences)
722 this.hiddenSequences = hiddenSequences;
725 public class JSONExportSettings
727 private boolean exportSequence;
729 private boolean exportSequenceFeatures;
731 private boolean exportAnnotations;
733 private boolean exportGroups;
735 private boolean exportJalviewSettings;
737 public boolean isExportSequence()
739 return exportSequence;
742 public void setExportSequence(boolean exportSequence)
744 this.exportSequence = exportSequence;
747 public boolean isExportSequenceFeatures()
749 return exportSequenceFeatures;
752 public void setExportSequenceFeatures(boolean exportSequenceFeatures)
754 this.exportSequenceFeatures = exportSequenceFeatures;
757 public boolean isExportAnnotations()
759 return exportAnnotations;
762 public void setExportAnnotations(boolean exportAnnotations)
764 this.exportAnnotations = exportAnnotations;
767 public boolean isExportGroups()
772 public void setExportGroups(boolean exportGroups)
774 this.exportGroups = exportGroups;
777 public boolean isExportJalviewSettings()
779 return exportJalviewSettings;
782 public void setExportJalviewSettings(boolean exportJalviewSettings)
784 this.exportJalviewSettings = exportJalviewSettings;