build fix
[jalview.git] / src / jalview / io / JSONFile.java
1 package jalview.io;
2
3 import jalview.api.AlignViewportI;
4 import jalview.api.FeatureRenderer;
5 import jalview.api.FeaturesDisplayedI;
6 import jalview.datamodel.AlignmentAnnotation;
7 import jalview.datamodel.Annotation;
8 import jalview.datamodel.Sequence;
9 import jalview.datamodel.SequenceFeature;
10 import jalview.datamodel.SequenceGroup;
11 import jalview.datamodel.SequenceI;
12 import jalview.gui.AlignFrame;
13 import jalview.json.binding.v1.AlignmentAnnotationPojo;
14 import jalview.json.binding.v1.AlignmentPojo;
15 import jalview.json.binding.v1.AnnotationPojo;
16 import jalview.json.binding.v1.JalviewSettingsPojo;
17 import jalview.json.binding.v1.JalviewSettingsPojo.JalviewBioJsColorSchemeMapper;
18 import jalview.json.binding.v1.SequenceFeaturesPojo;
19 import jalview.json.binding.v1.SequenceGrpPojo;
20 import jalview.json.binding.v1.SequencePojo;
21 import jalview.schemes.ColourSchemeI;
22 import jalview.schemes.ColourSchemeProperty;
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 public class JSONFile extends AlignFile
37 {
38   private ColourSchemeI colourScheme;
39
40   private String jalviewVersion;
41
42   private String webStartLaunchServletUrl;
43
44   public static final String FILE_EXT = "json";
45
46   public static final String FILE_DESC = "JSON";
47
48   private String globalColorScheme;
49
50   private boolean showSeqFeatures;
51
52   private Hashtable<String, Sequence> seqMap;
53
54   private FeaturesDisplayedI displayedFeatures;
55
56   private FeatureRenderer fr;
57
58   private JSONExportSettings jsonExportSettings;
59
60   public JSONFile()
61   {
62     super();
63   }
64
65   public JSONFile(FileParse source) throws IOException
66   {
67     super(source);
68   }
69
70   public JSONFile(String inFile, String type) throws IOException
71   {
72     super(inFile, type);
73   }
74
75   @Override
76   public void parse() throws IOException
77   {
78     StringBuilder jsonStringBuilder = new StringBuilder();
79     String currentLine;
80     while ((currentLine = nextLine()) != null)
81     {
82       jsonStringBuilder.append(currentLine);
83     }
84     parse(jsonStringBuilder.toString());
85
86   }
87
88   @Override
89   public String print()
90   {
91     String jsonOutput = null;
92     try
93     {
94       if (getJsonExportSettings() == null)
95       {
96         jsonExportSettings = new JSONExportSettings();
97         jsonExportSettings.setExportAnnotations(true);
98         jsonExportSettings.setExportGroups(true);
99         jsonExportSettings.setExportJalviewSettings(true);
100         jsonExportSettings.setExportSequenceFeatures(true);
101       }
102
103       AlignmentPojo jsonAlignmentPojo = new AlignmentPojo();
104       if (getViewport() != null)
105       {
106         globalColorScheme = ColourSchemeProperty
107                 .getColourName(getViewport()
108                 .getGlobalColourScheme());
109         setDisplayedFeatures(getViewport().getFeaturesDisplayed());
110         showSeqFeatures = getViewport().isShowSequenceFeatures();
111         fr = getViewport().getFeatureRenderer();
112       }
113
114       int count = 0;
115       for (SequenceI seq : seqs)
116       {
117         StringBuilder name = new StringBuilder();
118         name.append(seq.getName()).append("/").append(seq.getStart())
119                 .append("-").append(seq.getEnd());
120         SequencePojo jsonSeqPojo = new SequencePojo();
121         jsonSeqPojo.setId(seq.getName() + "_" + seq.hashCode());
122         jsonSeqPojo.setOrder(++count);
123         jsonSeqPojo.setEnd(seq.getEnd());
124         jsonSeqPojo.setStart(seq.getStart());
125         jsonSeqPojo.setName(name.toString());
126         jsonSeqPojo.setSeq(seq.getSequenceAsString());
127         jsonAlignmentPojo.getSeqs().add(jsonSeqPojo);
128       }
129
130       if (jsonExportSettings.isExportJalviewSettings())
131       {
132         jalviewVersion = jalview.bin.Cache.getProperty("VERSION");
133         webStartLaunchServletUrl = jalview.bin.Cache.getDefault(
134                 "www.jalview.org", "http://www.jalview.org")
135                 + "/services/launchApp";
136
137         JalviewSettingsPojo jvSettings = new JalviewSettingsPojo();
138         jvSettings.setGlobalColorScheme(globalColorScheme);
139         jvSettings.setJalviewVersion(jalviewVersion);
140         jvSettings.setWebStartUrl(webStartLaunchServletUrl);
141         jvSettings.setShowSeqFeatures(showSeqFeatures);
142         jsonAlignmentPojo.setJalviewSettings(jvSettings);
143       }
144
145       if (jsonExportSettings.isExportAnnotations())
146       {
147         jsonAlignmentPojo
148                 .setAlignAnnotation(annotationToJsonPojo(annotations));
149       }
150
151       if (jsonExportSettings.isExportSequenceFeatures())
152       {
153         jsonAlignmentPojo
154                 .setSeqFeatures(sequenceFeatureToJsonPojo(seqs, fr));
155       }
156
157       if (jsonExportSettings.isExportGroups() && seqGroups != null
158               && seqGroups.size() > 0)
159       {
160         for (SequenceGroup seqGrp : seqGroups)
161         {
162           SequenceGrpPojo seqGrpPojo = new SequenceGrpPojo();
163           seqGrpPojo.setGroupName(seqGrp.getName());
164           seqGrpPojo.setColourScheme(ColourSchemeProperty
165                   .getColourName(seqGrp.cs));
166           seqGrpPojo.setColourText(seqGrp.getColourText());
167           seqGrpPojo.setDescription(seqGrp.getDescription());
168           seqGrpPojo.setDisplayBoxes(seqGrp.getDisplayBoxes());
169           seqGrpPojo.setDisplayText(seqGrp.getDisplayText());
170           seqGrpPojo.setEndRes(seqGrp.getEndRes());
171           seqGrpPojo.setStartRes(seqGrp.getStartRes());
172           seqGrpPojo.setShowNonconserved(seqGrp.getShowNonconserved());
173           for (SequenceI seq : seqGrp.getSequences())
174           {
175             seqGrpPojo.getSeqsHash().add(
176                     seq.getName() + "_" + seq.hashCode());
177           }
178           jsonAlignmentPojo.getSeqGroups().add(seqGrpPojo);
179         }
180       }
181       com.json.JSONObject generatedJSon = new com.json.JSONObject(
182               jsonAlignmentPojo);
183       jsonOutput = generatedJSon.toString();
184       return jsonOutput.replaceAll("xstart", "xStart").replaceAll("xend",
185               "xEnd");
186     } catch (Exception e)
187     {
188       e.printStackTrace();
189     }
190     return jsonOutput;
191   }
192
193   public static List<SequenceFeaturesPojo> sequenceFeatureToJsonPojo(
194           List<SequenceI> seqs, FeatureRenderer fr)
195   {
196     FeaturesDisplayedI displayedFeatures = (fr == null) ? null : fr
197             .getFeaturesDisplayed();
198     List<SequenceFeaturesPojo> sequenceFeaturesPojo = new ArrayList<SequenceFeaturesPojo>();
199     for (SequenceI seq : seqs)
200     {
201       SequenceI dataSetSequence = seq.getDatasetSequence();
202       SequenceFeature[] seqFeatures = (dataSetSequence == null) ? null
203               : seq.getDatasetSequence().getSequenceFeatures();
204
205       if (seqFeatures == null)
206       {
207         continue;
208       }
209
210       for (SequenceFeature sf : seqFeatures)
211       {
212         if (displayedFeatures != null
213                 && displayedFeatures.isVisible(sf.getType()))
214         {
215           SequenceFeaturesPojo jsonFeature = new SequenceFeaturesPojo(
216                   seq.getName() + "_" + seq.hashCode());
217           String featureColour = (fr == null) ? null : jalview.util.Format
218                   .getHexString(fr
219                   .findFeatureColour(Color.white, seq,
220                           seq.findIndex(sf.getBegin())));
221           jsonFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
222           jsonFeature.setXend(seq.findIndex(sf.getEnd()));
223           jsonFeature.setType(sf.getType());
224           jsonFeature.setDescription(sf.getDescription());
225           jsonFeature.setLinks(sf.links);
226           jsonFeature.setOtherDetails(sf.otherDetails);
227           jsonFeature.setScore(sf.getScore());
228           jsonFeature.setFillColor(featureColour);
229           jsonFeature.setFeatureGroup(sf.getFeatureGroup());
230           sequenceFeaturesPojo.add(jsonFeature);
231         }
232       }
233     }
234     return sequenceFeaturesPojo;
235   }
236
237   public static List<AlignmentAnnotationPojo> annotationToJsonPojo(
238           Vector<AlignmentAnnotation> annotations)
239   {
240     List<AlignmentAnnotationPojo> jsonAnnotations = new ArrayList<AlignmentAnnotationPojo>();
241     if (annotations == null)
242     {
243       return jsonAnnotations;
244     }
245     for (AlignmentAnnotation annot : annotations)
246     {
247       AlignmentAnnotationPojo alignAnnotPojo = new AlignmentAnnotationPojo();
248       alignAnnotPojo.setDescription(annot.description);
249       alignAnnotPojo.setLabel(annot.label);
250       for (Annotation annotation : annot.annotations)
251       {
252         AnnotationPojo annotationPojo = new AnnotationPojo();
253         if (annotation != null)
254         {
255           annotationPojo.setDescription(annotation.description);
256           annotationPojo.setValue(annotation.value);
257           annotationPojo
258                   .setSecondaryStructure(annotation.secondaryStructure);
259           annotationPojo.setDisplayCharacter(annotation.displayCharacter);
260           alignAnnotPojo.getAnnotations().add(annotationPojo);
261         }
262         else
263         {
264           alignAnnotPojo.getAnnotations().add(annotationPojo);
265         }
266       }
267       jsonAnnotations.add(alignAnnotPojo);
268     }
269     return jsonAnnotations;
270   }
271
272   @SuppressWarnings("unchecked")
273   public JSONFile parse(String jsonAlignmentString)
274   {
275     try
276     {
277       JSONParser jsonParser = new JSONParser();
278       JSONObject alignmentJsonObj = (JSONObject) jsonParser
279               .parse(jsonAlignmentString);
280       JSONArray seqJsonArray = (JSONArray) alignmentJsonObj.get("seqs");
281       JSONArray alAnnotJsonArray = (JSONArray) alignmentJsonObj
282               .get("alignAnnotation");
283       JSONArray jsonSeqArray = (JSONArray) alignmentJsonObj
284               .get("seqFeatures");
285       JSONArray seqGrpJsonArray = (JSONArray) alignmentJsonObj
286               .get("seqGroups");
287       JSONObject jvSettingsJsonObj = (JSONObject) alignmentJsonObj
288               .get("jalviewSettings");
289
290       if (jvSettingsJsonObj != null)
291       {
292         String jsColourScheme = (String) jvSettingsJsonObj
293                 .get("globalColorScheme");
294         Boolean showFeatures = Boolean.valueOf(jvSettingsJsonObj.get(
295                 "showSeqFeatures").toString());
296         setColourScheme(getJalviewColorScheme(jsColourScheme));
297         setShowSeqFeatures(showFeatures);
298       }
299
300       seqMap = new Hashtable<String, Sequence>();
301       for (Iterator<JSONObject> sequenceIter = seqJsonArray.iterator(); sequenceIter
302               .hasNext();)
303       {
304         JSONObject sequence = sequenceIter.next();
305         String sequcenceString = sequence.get("seq").toString();
306         String sequenceName = sequence.get("name").toString();
307         String seqUniqueId = sequence.get("id").toString();
308         int start = Integer.valueOf(sequence.get("start").toString());
309         int end = Integer.valueOf(sequence.get("end").toString());
310         Sequence seq = new Sequence(sequenceName, sequcenceString, start,
311                 end);
312         seqs.add(seq);
313         seqMap.put(seqUniqueId, seq);
314       }
315       parseFeatures(jsonSeqArray);
316
317       for (Iterator<JSONObject> seqGrpIter = seqGrpJsonArray.iterator(); seqGrpIter
318               .hasNext();)
319       {
320         JSONObject seqGrpObj = seqGrpIter.next();
321         String grpName = seqGrpObj.get("groupName").toString();
322         String colourScheme = seqGrpObj.get("colourScheme").toString();
323         String description = (seqGrpObj.get("description") == null) ? null
324                 : seqGrpObj.get("description").toString();
325         boolean displayBoxes = Boolean.valueOf(seqGrpObj
326                 .get("displayBoxes").toString());
327         boolean displayText = Boolean.valueOf(seqGrpObj.get("displayText")
328                 .toString());
329         boolean colourText = Boolean.valueOf(seqGrpObj.get("colourText")
330                 .toString());
331         boolean showNonconserved = Boolean.valueOf(seqGrpObj.get(
332                 "showNonconserved").toString());
333         int startRes = Integer
334                 .valueOf(seqGrpObj.get("startRes").toString());
335         int endRes = Integer.valueOf(seqGrpObj.get("endRes").toString());
336         JSONArray seqsHashArray = (JSONArray) seqGrpObj.get("seqsHash");
337
338         ArrayList<SequenceI> grpSeqs = new ArrayList<SequenceI>();
339         if (seqsHashArray.size() > 0)
340         {
341           Iterator<String> seqHashIter = seqsHashArray.iterator();
342           while (seqHashIter.hasNext())
343           {
344             String seqHash = seqHashIter.next();
345             Sequence sequence = seqMap.get(seqHash);
346             if (sequence != null)
347             {
348               grpSeqs.add(sequence);
349             }
350           }
351         }
352         ColourSchemeI scheme = getJalviewColorScheme(colourScheme);
353         SequenceGroup seqGrp = new SequenceGroup(grpSeqs, grpName, scheme,
354                 displayBoxes, displayText, colourText, startRes, endRes);
355         seqGrp.setShowNonconserved(showNonconserved);
356         seqGrp.setDescription(description);
357         this.seqGroups.add(seqGrp);
358
359       }
360
361       for (Iterator<JSONObject> alAnnotIter = alAnnotJsonArray.iterator(); alAnnotIter
362               .hasNext();)
363       {
364         JSONObject alAnnot = alAnnotIter.next();
365         JSONArray annotJsonArray = (JSONArray) alAnnot.get("annotations");
366         Annotation[] annotations = new Annotation[annotJsonArray.size()];
367         int count = 0;
368         for (Iterator<JSONObject> annotIter = annotJsonArray.iterator(); annotIter
369                 .hasNext();)
370         {
371           JSONObject annot = annotIter.next();
372           if (annot == null)
373           {
374             annotations[count] = null;
375           }
376           else
377           {
378             float val = annot.get("value") == null ? null : Float
379                     .valueOf(annot.get("value").toString());
380             String desc = annot.get("description") == null ? null : annot
381                     .get("description").toString();
382
383             char ss = annot.get("secondaryStructure") == null ? null
384                     : annot.get("secondaryStructure").toString().charAt(0);
385             String displayChar = annot.get("displayCharacter").toString();
386
387             annotations[count] = new Annotation(displayChar, desc, ss, val);
388           }
389           ++count;
390         }
391
392         AlignmentAnnotation alignAnnot = new AlignmentAnnotation(alAnnot
393                 .get("label").toString(), alAnnot.get("description")
394                 .toString(), annotations);
395         this.annotations.add(alignAnnot);
396       }
397
398     } catch (Exception e)
399     {
400       e.printStackTrace();
401     }
402     return this;
403   }
404
405
406   @SuppressWarnings("unchecked")
407   private void parseFeatures(JSONArray jsonSeqFeatures)
408   {
409     if (jsonSeqFeatures != null)
410     {
411       for (Iterator<JSONObject> seqFeatureItr = jsonSeqFeatures.iterator(); seqFeatureItr
412               .hasNext();)
413       {
414         JSONObject jsonFeature = seqFeatureItr.next();
415         Long begin = (Long) jsonFeature.get("xStart");
416         Long end = (Long) jsonFeature.get("xEnd");
417         String type = (String) jsonFeature.get("type");
418         String featureGrp = (String) jsonFeature.get("featureGroup");
419         String descripiton = (String) jsonFeature.get("description");
420         String seqRef = (String) jsonFeature.get("sequenceRef");
421         Float score = Float.valueOf(jsonFeature.get("score").toString());
422         // Hashtable otherDetails = (Hashtable) jsonFeature
423         // .get("otherDetails");
424         // sequenceFeature.otherDetails = otherDetails;
425
426         Sequence seq = seqMap.get(seqRef);
427         SequenceFeature sequenceFeature = new SequenceFeature();
428         JSONArray linksJsonArray = (JSONArray) jsonFeature.get("links");
429         if (linksJsonArray != null && linksJsonArray.size() > 0)
430         {
431           Iterator<String> linkList = linksJsonArray.iterator();
432           while (linkList.hasNext())
433           {
434             String link = linkList.next();
435             sequenceFeature.addLink(link);
436           }
437         }
438         sequenceFeature.setFeatureGroup(featureGrp);
439         sequenceFeature.setScore(score);
440         sequenceFeature.setDescription(descripiton);
441         sequenceFeature.setType(type);
442         sequenceFeature.setBegin(seq.findPosition(begin.intValue()));
443         sequenceFeature.setEnd(seq.findPosition(end.intValue()) - 1);
444         seq.addSequenceFeature(sequenceFeature);
445       }
446     }
447   }
448
449   public static ColourSchemeI getJalviewColorScheme(
450           String bioJsColourSchemeName)
451   {
452     ColourSchemeI jalviewColor = null;
453     for (JalviewBioJsColorSchemeMapper cs : JalviewBioJsColorSchemeMapper
454             .values())
455     {
456       if (cs.getBioJsName().equalsIgnoreCase(bioJsColourSchemeName))
457       {
458         jalviewColor = cs.getJvColourScheme();
459         break;
460       }
461     }
462     return jalviewColor;
463   }
464
465   public void applySettingsToAlignFrame(AlignFrame af)
466   {
467     af.setShowSeqFeatures(isShowSeqFeatures());
468     af.changeColour(getColourScheme());
469     af.setMenusForViewport();
470   }
471
472   public String getGlobalColorScheme()
473   {
474     return globalColorScheme;
475   }
476
477   public void setGlobalColorScheme(String globalColorScheme)
478   {
479     this.globalColorScheme = globalColorScheme;
480   }
481
482   public ColourSchemeI getColourScheme()
483   {
484     return colourScheme;
485   }
486
487   public void setColourScheme(ColourSchemeI colourScheme)
488   {
489     this.colourScheme = colourScheme;
490   }
491
492   public FeaturesDisplayedI getDisplayedFeatures()
493   {
494     return displayedFeatures;
495   }
496
497   public void setDisplayedFeatures(FeaturesDisplayedI displayedFeatures)
498   {
499     this.displayedFeatures = displayedFeatures;
500   }
501
502   public JSONExportSettings getJsonExportSettings()
503   {
504     return jsonExportSettings;
505   }
506
507   public void setJsonExportSettings(JSONExportSettings jsonExportSettings)
508   {
509     this.jsonExportSettings = jsonExportSettings;
510   }
511
512   public static String getJSONData(AlignViewportI av)
513   {
514     JSONFile jsonFile = new JSONFile();
515     jsonFile.setViewport(av);
516     jsonFile.seqGroups = av.getAlignment().getGroups();
517     jsonFile.setDisplayedFeatures(av.getFeaturesDisplayed());
518
519     for (SequenceI seq : av.getAlignment().getSequences())
520     {
521       jsonFile.seqs.add(seq);
522     }
523   
524     // Add non auto calculated annotation to AlignFile
525     for (AlignmentAnnotation annot : av.getAlignment()
526             .getAlignmentAnnotation())
527     {
528       if (annot != null && !annot.autoCalculated)
529       {
530         if (annot.label.equals("PDB.CATempFactor"))
531         {
532           continue;
533         }
534         jsonFile.annotations.add(annot);
535       }
536     }
537     String jsonString = jsonFile.print();
538     return jsonString;
539   }
540
541   public boolean isShowSeqFeatures()
542   {
543     return showSeqFeatures;
544   }
545
546   public void setShowSeqFeatures(boolean showSeqFeatures)
547   {
548     this.showSeqFeatures = showSeqFeatures;
549   }
550
551   public class JSONExportSettings
552   {
553     private boolean exportSequence;
554
555     private boolean exportSequenceFeatures;
556
557     private boolean exportAnnotations;
558
559     private boolean exportGroups;
560
561     private boolean exportJalviewSettings;
562
563     public boolean isExportSequence()
564     {
565       return exportSequence;
566     }
567
568     public void setExportSequence(boolean exportSequence)
569     {
570       this.exportSequence = exportSequence;
571     }
572
573     public boolean isExportSequenceFeatures()
574     {
575       return exportSequenceFeatures;
576     }
577
578     public void setExportSequenceFeatures(boolean exportSequenceFeatures)
579     {
580       this.exportSequenceFeatures = exportSequenceFeatures;
581     }
582
583     public boolean isExportAnnotations()
584     {
585       return exportAnnotations;
586     }
587
588     public void setExportAnnotations(boolean exportAnnotations)
589     {
590       this.exportAnnotations = exportAnnotations;
591     }
592
593     public boolean isExportGroups()
594     {
595       return exportGroups;
596     }
597
598     public void setExportGroups(boolean exportGroups)
599     {
600       this.exportGroups = exportGroups;
601     }
602
603     public boolean isExportJalviewSettings()
604     {
605       return exportJalviewSettings;
606     }
607
608     public void setExportJalviewSettings(boolean exportJalviewSettings)
609     {
610       this.exportJalviewSettings = exportJalviewSettings;
611     }
612   }
613 }