Merge branch 'develop' into JAL-1483_29dev
[jalview.git] / src / jalview / io / BioJsHTMLOutput.java
1 package jalview.io;
2
3 import jalview.api.FeaturesDisplayedI;
4 import jalview.datamodel.AlignmentI;
5 import jalview.datamodel.SequenceFeature;
6 import jalview.datamodel.SequenceI;
7 import jalview.exceptions.NoFileSelectedException;
8 import jalview.gui.AlignViewport;
9 import jalview.gui.AlignmentPanel;
10 import jalview.gui.FeatureRenderer;
11 import jalview.json.binding.v1.BioJsAlignmentPojo;
12 import jalview.json.binding.v1.BioJsFeaturePojo;
13 import jalview.json.binding.v1.BioJsSeqPojo;
14 import jalview.schemes.ColourSchemeProperty;
15 import jalview.util.MessageManager;
16
17 import java.awt.Color;
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.InputStreamReader;
21 import java.io.PrintWriter;
22 import java.net.URL;
23 import java.util.ArrayList;
24
25 import com.json.JSONException;
26
27 public class BioJsHTMLOutput
28 {
29   private AlignViewport av;
30
31   private jalview.api.FeatureRenderer fr;
32
33   private String globalColorScheme;
34
35   private FeaturesDisplayedI displayedFeatures;
36
37   private String jalviewVersion;
38
39   private String webStartLaunchServletUrl = "http://www.jalview.org/services/launchApp";
40
41   public BioJsHTMLOutput(AlignmentPanel ap,
42           FeatureRenderer fr1)
43   {
44
45     jalviewVersion = jalview.bin.Cache.getProperty("VERSION");
46     webStartLaunchServletUrl = jalview.bin.Cache.getDefault(
47             "www.jalview.org", "http://www.jalview.org")
48             + "/services/launchApp";
49     if (ap != null)
50     {
51       this.av = ap.av;
52       this.globalColorScheme = ColourSchemeProperty.getColourName(av
53               .getGlobalColourScheme());
54       this.fr = ap.cloneFeatureRenderer();
55       displayedFeatures = av.getFeaturesDisplayed();
56     }
57   }
58
59   private void exportJalviewAlignmentAsBioJsHtmlFile()
60   {
61     try
62     {
63       String outputFile = getOutputFile();
64       String jalviewAlignmentJson = getJalviewAlignmentAsJsonString(av
65               .getAlignment());
66       String bioJSTemplateString = getBioJsTemplateAsString(this);
67       String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
68               .replaceAll(
69 "#sequenceData#", jalviewAlignmentJson)
70               .toString();
71
72       PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
73               outputFile));
74       out.print(generatedBioJsWithJalviewAlignmentAsJson);
75       out.flush();
76       out.close();
77       jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
78     } catch (NoFileSelectedException ex)
79     {
80       // do noting if no file was selected
81     } catch (Exception e)
82     {
83       e.printStackTrace();
84     }
85   }
86
87   public String getOutputFile() throws NoFileSelectedException
88   {
89     String selectedFile = null;
90     JalviewFileChooser jvFileChooser = new JalviewFileChooser(
91             jalview.bin.Cache.getProperty("LAST_DIRECTORY"), new String[]
92             { "html" }, new String[]
93             { "HTML files" }, "HTML files");
94     jvFileChooser.setFileView(new JalviewFileView());
95
96     // TODO uncomment when supported by MassageManager
97     jvFileChooser.setDialogTitle(MessageManager
98             .getString("label.save_as_biojs_html"));
99     jvFileChooser.setDialogTitle("save as BioJs HTML");
100     jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
101
102     int fileChooserOpt = jvFileChooser.showSaveDialog(null);
103     if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
104     {
105       jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
106               .getSelectedFile().getParent());
107       selectedFile = jvFileChooser.getSelectedFile().getPath();
108     }
109     else
110     {
111       throw new NoFileSelectedException("No file was selected.");
112     }
113
114     return selectedFile;
115   }
116
117   public String getJalviewAlignmentAsJsonString(AlignmentI alignment)
118           throws IOException, JSONException
119   {
120     BioJsAlignmentPojo bjsAlignment = new BioJsAlignmentPojo();
121
122     bjsAlignment.setGlobalColorScheme(getGlobalColorScheme());
123     bjsAlignment.setJalviewVersion(jalviewVersion);
124     bjsAlignment.setWebStartUrl(webStartLaunchServletUrl);
125
126     int count = 0;
127     for (SequenceI seq : alignment.getSequences())
128     {
129       StringBuilder name = new StringBuilder();
130       name.append(seq.getName()).append("/").append(seq.getStart())
131               .append("-").append(seq.getEnd());
132
133       BioJsSeqPojo seqPojo = new BioJsSeqPojo();
134       seqPojo.setId(String.valueOf(++count));
135       seqPojo.setEnd(seq.getEnd());
136       seqPojo.setStart(seq.getStart());
137       seqPojo.setName(name.toString());
138       seqPojo.setSeq(seq.getSequenceAsString());
139
140       SequenceFeature[] seqFeatures = seq.getDatasetSequence()
141               .getSequenceFeatures();
142       if (seqFeatures != null)
143       {
144         ArrayList<BioJsFeaturePojo> bjsSeqFeatures = new ArrayList<BioJsFeaturePojo>();
145         for (SequenceFeature sf : seqFeatures)
146         {
147           if (displayedFeatures != null
148                   && displayedFeatures.isVisible(sf.getType()))
149           {
150
151             // TODO: translate graduated/complex colourschemes to biojs model
152             String featureColour = jalview.util.Format.getHexString(fr
153                     .findFeatureColour(Color.white, seq,
154                             seq.findIndex(sf.getBegin())));
155             BioJsFeaturePojo bjsFeature = new BioJsFeaturePojo();
156             bjsFeature.setFillColor(featureColour);
157             bjsFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
158             bjsFeature.setXend(seq.findIndex(sf.getEnd()));
159             bjsFeature.setText(sf.getType());
160             bjsSeqFeatures.add(bjsFeature);
161           }
162         }
163         seqPojo.setFeatures(bjsSeqFeatures);
164       }
165       bjsAlignment.getSeqs().add(seqPojo);
166     }
167
168     return new com.json.JSONObject(bjsAlignment).toString()
169             .replaceAll("xstart", "xStart").replaceAll("xend", "xEnd");
170   }
171
172   public static String getBioJsTemplateAsString(Object currentObj)
173           throws IOException
174   {
175     InputStreamReader isReader = null;
176     BufferedReader buffReader = null;
177     StringBuilder sb = new StringBuilder();
178     URL url = currentObj.getClass().getResource(
179             "/templates/BioJSTemplate.txt");
180     if (url != null)
181     {
182       try
183       {
184         isReader = new InputStreamReader(url.openStream());
185         buffReader = new BufferedReader(isReader);
186         String line;
187         String lineSeparator = System.getProperty("line.separator");
188         while ((line = buffReader.readLine()) != null)
189         {
190           sb.append(line).append(lineSeparator);
191         }
192
193       } catch (Exception ex)
194       {
195         ex.printStackTrace();
196       } finally
197       {
198         if (isReader != null)
199         {
200           isReader.close();
201         }
202
203         if (buffReader != null)
204         {
205           buffReader.close();
206         }
207       }
208     }
209     return sb.toString();
210   }
211
212   public String getGlobalColorScheme()
213   {
214     return globalColorScheme;
215   }
216
217   public void setGlobalColorScheme(String globalColorScheme)
218   {
219     this.globalColorScheme = globalColorScheme;
220   }
221
222 }