JAL-3032 moving Mungo's original JalviewJS.java out of src
[jalview.git] / unused / JalviewJS.java
1 package jalview.bin;
2
3 import jalview.analysis.AlignmentUtils;
4 import jalview.datamodel.AlignmentI;
5 import jalview.gui.AlignFrame;
6 import jalview.gui.SplitFrame;
7 import jalview.io.DataSourceType;
8 import jalview.io.FileFormatException;
9 import jalview.io.FileFormatI;
10 import jalview.io.FileLoader;
11 import jalview.io.IdentifyFile;
12 import jalview.structure.StructureSelectionManager;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 import javax.swing.JFrame;
20 import javax.swing.JInternalFrame;
21
22 /**
23  * Entry point for Jalview as Javascript. Expects parameter names as for the
24  * JalviewLite applet, formatted as for the Jalview application, for example
25  * 
26  * <pre>
27  *   JalviewJS file /examples/uniref50.fa features /examples/exampleFeatures.txt \
28  *       PDBFile "/examples/pdb1.txt seq1"
29  * </pre>
30  * 
31  * Note that (unlike the applet) parameter names are case sensitive
32  */
33 // TODO or format as file=/examples/uniref50.fa (etc)?
34 public class JalviewJS
35 {
36
37   static
38   {
39     /**
40      * @j2sNative
41      * 
42      *            thisApplet.__Info.args =
43      *            ["file","examples/uniref50.fa","features",
44      *            "examples/exampleFeatures.txt",
45      *            "props","/Users/gmcarstairs/.jalview_properties"];
46      */
47
48   }
49
50   private static final String PARAM_FILE = "file";
51
52   private static final String PARAM_FILE2 = "file2";
53
54   private static final String PARAM_TREE = "tree";
55
56   private static final String PARAM_FEATURES = "features";
57
58   private static final String PARAM_ANNOTATIONS = "annotations";
59
60   private static final String PARAM_SHOW_ANNOTATION = "showAnnotation";
61
62   private static final String PARAM_PDBFILE = "PDBFile";
63
64   private static final String PARAM_PROPS = "props";
65
66   private Map<String, String> params;
67
68   private List<String> pdbFileParams;
69
70   public static void main(String[] args) throws Exception
71   {
72     new JalviewJS().doMain(args);
73   }
74
75   /**
76    * Parses parameters and shows the frame and any loaded panels
77    * 
78    * @throws FileFormatException
79    */
80   void doMain(String[] args) throws FileFormatException
81   {
82     loadParameters(args);
83     if (getParameter(PARAM_FILE) == null)
84     {
85       usage();
86     }
87     else
88     {
89       showFrame();
90     }
91   }
92
93   /**
94    * Answers the value of the given runtime parameter, or null if not provided
95    * 
96    * @param paramName
97    * @return
98    */
99   private String getParameter(String paramName)
100   {
101     return params.get(paramName);
102   }
103
104   /**
105    * Prints a chastising, yet helpful, error message on syserr
106    */
107   private void usage()
108   {
109     System.err.println(
110             "Usage: JalviewJS file <alignmentFile> [features <featuresFile>]");
111     System.err.println("See documentation for full parameter list");
112   }
113
114   /**
115    * Parses any supplied parameters. Note that (unlike for the applet),
116    * parameter names are case sensitive.
117    * 
118    * @param args
119    * 
120    * @see http://www.jalview.org/examples/index.html#appletParameters
121    */
122   void loadParameters(String[] args)
123   {
124     ArgsParser parser = new ArgsParser(args);
125     params = new HashMap<>();
126
127     // TODO javascript-friendly source of properties
128     Cache.loadProperties(parser.getValue(PARAM_PROPS));
129     loadParameter(parser, PARAM_FILE);
130     loadParameter(parser, PARAM_FILE2);
131     loadParameter(parser, PARAM_TREE);
132     loadParameter(parser, PARAM_FEATURES);
133     loadParameter(parser, PARAM_ANNOTATIONS);
134     loadParameter(parser, PARAM_SHOW_ANNOTATION);
135     pdbFileParams = loadPdbParameters(parser);
136   }
137
138   /**
139    * Reads one command line parameter value and saves it against the parameter
140    * name. Note the saved value is null if the parameter is not present.
141    * 
142    * @param parser
143    * @param param
144    */
145   protected void loadParameter(ArgsParser parser, String param)
146   {
147     params.put(param, parser.getValue(param));
148   }
149
150   /**
151    * Reads parameter PDBFile, PDBFile1, PDFile2, ... and saves the value(s) (if
152    * any)
153    * 
154    * @param parser
155    * @return
156    */
157   List<String> loadPdbParameters(ArgsParser parser)
158   {
159     List<String> values = new ArrayList<>();
160     String value = parser.getValue(PARAM_PDBFILE);
161     if (value != null)
162     {
163       values.add(value);
164     }
165     int i = 1;
166     while (true)
167     {
168       value = parser.getValue(PARAM_PDBFILE + String.valueOf(i));
169       if (value != null)
170       {
171         values.add(value);
172       }
173       else
174       {
175         break;
176       }
177     }
178     return values;
179   }
180
181   /**
182    * Constructs and displays a JFrame containing an alignment panel (and any
183    * additional panels depending on parameters supplied)
184    * 
185    * @throws FileFormatException
186    */
187   void showFrame() throws FileFormatException
188   {
189     JFrame frame = new JFrame(getParameter(PARAM_FILE));
190     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
191
192     /*
193      * construct an AlignFrame (optionally with features)
194      */
195     AlignFrame alignFrame = createAlignFrame(PARAM_FILE);
196     loadFeatures(alignFrame, getParameter(PARAM_FEATURES));
197
198     JInternalFrame internalFrame = alignFrame;
199
200     /*
201      * convert to SplitFrame if a valid file2 is supplied
202      */
203     AlignFrame alignFrame2 = createAlignFrame(PARAM_FILE2);
204     if (alignFrame2 != null)
205     {
206       SplitFrame splitFrame = loadSplitFrame(alignFrame, alignFrame2);
207       if (splitFrame != null)
208       {
209         internalFrame = splitFrame;
210       }
211     }
212
213     /*
214      * move AlignFrame (or SplitFrame) menu bar and content pane to our frame
215      * TODO there may be a less obscure way to do this
216      */
217     frame.setContentPane(internalFrame.getContentPane());
218     frame.setJMenuBar(internalFrame.getJMenuBar());
219
220     // fudge so that dialogs can be opened with this frame as parent
221     // todo JAL-3031 also override Desktop.addInternalFrame etc
222     // Desktop.parent = frame.getContentPane();
223
224     frame.pack();
225     frame.setSize(AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
226     frame.setVisible(true);
227   }
228
229   /**
230    * Constructs a SplitFrame if cdna-protein mappings can be made between the
231    * given alignment frames, else returns null. Any mappings made are registered
232    * with StructureSelectionManager to enable broadcast to listeners.
233    * 
234    * @param alignFrame
235    * @param alignFrame2
236    * @return
237    */
238   protected SplitFrame loadSplitFrame(AlignFrame alignFrame,
239           AlignFrame alignFrame2)
240   {
241     // code borrowed from AlignViewport.openLinkedAlignment
242     AlignmentI al1 = alignFrame.getViewport().getAlignment();
243     AlignmentI al2 = alignFrame2.getViewport().getAlignment();
244     boolean al1Nuc = al1.isNucleotide();
245     if (al1Nuc == al2.isNucleotide())
246     {
247       System.err.println("Can't make split frame as alignments are both "
248               + (al1Nuc ? "nucleotide" : "protein"));
249       return null;
250     }
251     AlignmentI protein = al1Nuc ? al2 : al1;
252     AlignmentI cdna = al1Nuc ? al1 : al2;
253     boolean mapped = AlignmentUtils.mapProteinAlignmentToCdna(protein,
254             cdna);
255     if (!mapped)
256     {
257       System.err.println("Can't make any mappings for split frame");
258       return null;
259     }
260
261     /*
262      * register sequence mappings
263      */
264     StructureSelectionManager ssm = StructureSelectionManager
265             .getStructureSelectionManager(null);
266     ssm.registerMappings(protein.getCodonFrames());
267
268     cdna.alignAs(protein);
269
270     SplitFrame splitFrame = new SplitFrame(
271             al1Nuc ? alignFrame : alignFrame2,
272             al1Nuc ? alignFrame2 : alignFrame);
273
274     return splitFrame;
275   }
276
277   /**
278    * Loads on a features file if one was specified as a parameter
279    * 
280    * @param alignFrame
281    * @param featureFile
282    */
283   protected void loadFeatures(AlignFrame alignFrame, String featureFile)
284   {
285     if (featureFile != null)
286     {
287       // todo extract helper for protocol resolution from JalviewLite
288       DataSourceType sourceType = featureFile.startsWith("http")
289               ? DataSourceType.URL
290               : DataSourceType.RELATIVE_URL;
291       alignFrame.parseFeaturesFile(featureFile, sourceType);
292     }
293   }
294
295   /**
296    * Constructs and returns the frame containing the alignment and its
297    * annotations. Returns null if the specified parameter value is not set.
298    * 
299    * @param fileParam
300    * 
301    * @return
302    * @throws FileFormatException
303    */
304   AlignFrame createAlignFrame(String fileParam) throws FileFormatException
305   {
306     AlignFrame af = null;
307     String file = getParameter(fileParam);
308     if (file != null)
309     {
310       DataSourceType protocol = file.startsWith("http") ? DataSourceType.URL
311               : DataSourceType.RELATIVE_URL;
312       // DataSourceType protocol = AppletFormatAdapter.checkProtocol(file);
313       FileFormatI format = new IdentifyFile().identify(file, protocol);
314       FileLoader fileLoader = new FileLoader(false);
315       af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
316     }
317
318     return af;
319   }
320
321 }