4e24354b1f2b9e4b4b901b0c3551401266725c9c
[jalview.git] / src / jalview / bin / JalviewJS.java
1 package jalview.bin;
2
3 import jalview.gui.AlignFrame;
4 import jalview.gui.Desktop;
5 import jalview.io.AppletFormatAdapter;
6 import jalview.io.DataSourceType;
7 import jalview.io.FileFormatException;
8 import jalview.io.FileFormatI;
9 import jalview.io.FileLoader;
10 import jalview.io.IdentifyFile;
11
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Objects;
17
18 import javax.swing.JFrame;
19
20 /**
21  * Entry point for Jalview as Javascript. Expects parameter names as for the
22  * JalviewLite applet, formatted as for the Jalview application, for example
23  * 
24  * <pre>
25  *   JalviewJS file /examples/uniref50.fa features /examples/exampleFeatures.txt \
26  *       PDBFile "/examples/pdb1.txt seq1"
27  * </pre>
28  * 
29  * Note that (unlike the applet) parameter names are case sensitive
30  */
31 // TODO or format as file=/examples/uniref50.fa (etc)?
32 public class JalviewJS
33 {
34   private static final String PARAM_FILE = "file";
35
36   private static final String PARAM_FILE2 = "file2";
37
38   private static final String PARAM_TREE = "tree";
39
40   private static final String PARAM_FEATURES = "features";
41
42   private static final String PARAM_ANNOTATIONS = "annotations";
43
44   private static final String PARAM_SHOW_ANNOTATION = "showAnnotation";
45
46   private static final String PARAM_PDBFILE = "PDBFile";
47
48   private static final String PARAM_PROPS = "props";
49
50   private Map<String, String> params;
51
52   private List<String> pdbFileParams;
53
54   public static void main(String[] args)
55   {
56     try
57     {
58       new JalviewJS().doMain(args);
59     } catch (FileFormatException e)
60     {
61       e.printStackTrace();
62     }
63   }
64
65   /**
66    * Parses parameters and shows the frame and any loaded panels
67    * 
68    * @throws FileFormatException
69    */
70   void doMain(String[] args) throws FileFormatException
71   {
72     loadParameters(args);
73     if (getParameter(PARAM_FILE) == null)
74     {
75       usage();
76     }
77     else
78     {
79       showFrame();
80     }
81   }
82
83   /**
84    * Answers the value of the given runtime parameter, or null if not provided
85    * 
86    * @param paramName
87    * @return
88    */
89   private String getParameter(String paramName)
90   {
91     return params.get(paramName);
92   }
93
94   /**
95    * Prints a chastising, yet helpful, error message on syserr
96    */
97   private void usage()
98   {
99     System.err.println("Usage: JalviewJS file <alignmentFile>");
100     System.err.println("See documentation for full parameter list");
101   }
102
103   /**
104    * Parses any supplied parameters. Note that (unlike for the applet),
105    * parameter names are case sensitive.
106    * 
107    * @param args
108    * 
109    * @see http://www.jalview.org/examples/index.html#appletParameters
110    */
111   void loadParameters(String[] args)
112   {
113     ArgsParser parser = new ArgsParser(args);
114     params = new HashMap<>();
115
116     // TODO javascript-friendly source of properties
117     Cache.loadProperties(parser.getValue(PARAM_PROPS));
118     loadParameter(parser, PARAM_FILE);
119     loadParameter(parser, PARAM_FILE2);
120     loadParameter(parser, PARAM_TREE);
121     loadParameter(parser, PARAM_FEATURES);
122     loadParameter(parser, PARAM_ANNOTATIONS);
123     loadParameter(parser, PARAM_SHOW_ANNOTATION);
124     pdbFileParams = loadPdbParameters(parser);
125   }
126
127   /**
128    * Reads one command line parameter value and saves it against the parameter
129    * name. Note the saved value is null if the parameter is not present.
130    * 
131    * @param parser
132    * @param param
133    */
134   protected void loadParameter(ArgsParser parser, String param)
135   {
136     params.put(param, parser.getValue(param));
137   }
138
139   /**
140    * Reads parameter PDBFile, PDBFile1, PDFile2, ... and saves the value(s) (if
141    * any)
142    * 
143    * @param parser
144    * @return
145    */
146   List<String> loadPdbParameters(ArgsParser parser)
147   {
148     List<String> values = new ArrayList<>();
149     String value = parser.getValue(PARAM_PDBFILE);
150     if (value != null)
151     {
152       values.add(value);
153     }
154     int i = 1;
155     while (true)
156     {
157       value = parser.getValue(PARAM_PDBFILE + String.valueOf(i));
158       if (value != null)
159       {
160         values.add(value);
161       }
162       else
163       {
164         break;
165       }
166     }
167     return values;
168   }
169
170   /**
171    * Constructs and displays a JFrame containing an alignment panel (and any
172    * additional panels depending on parameters supplied)
173    * 
174    * @throws FileFormatException
175    */
176   void showFrame() throws FileFormatException
177   {
178     JFrame frame = new JFrame(getParameter(PARAM_FILE));
179     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
180
181     /*
182      * construct an AlignFrame and extract its contents and menu bar
183      * TODO there may be a less obscure way to do this
184      */
185     AlignFrame alignFrame = createAlignFrame();
186     frame.setContentPane(alignFrame.getContentPane());
187     frame.setJMenuBar(alignFrame.getJMenuBar());
188
189     // fudge so that dialogs can be opened with this frame as parent
190     Desktop.parent = frame.getContentPane();
191
192     loadFeatures(alignFrame, getParameter(PARAM_FEATURES));
193
194     frame.pack();
195     frame.setSize(AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
196     frame.setVisible(true);
197   }
198
199   /**
200    * Load on a features file if one was specified as a parameter
201    * 
202    * @param alignFrame
203    * 
204    * @param featureFile
205    */
206   protected void loadFeatures(AlignFrame alignFrame, String featureFile)
207   {
208     if (featureFile != null)
209     {
210       // todo extract helper for protocol resolution from JalviewLite
211       DataSourceType sourceType = featureFile.startsWith("http")
212               ? DataSourceType.URL
213               : DataSourceType.FILE;
214       alignFrame.parseFeaturesFile(featureFile, sourceType);
215     }
216   }
217
218   /**
219    * Constructs and returns the frame containing the alignment and its
220    * annotations
221    * 
222    * @return
223    * @throws FileFormatException
224    */
225   AlignFrame createAlignFrame() throws FileFormatException
226   {
227     String file = getParameter(PARAM_FILE);
228     Objects.requireNonNull(file);
229
230     DataSourceType protocol = AppletFormatAdapter.checkProtocol(file);
231     FileFormatI format = new IdentifyFile().identify(file, protocol);
232     FileLoader fileLoader = new FileLoader(false);
233     AlignFrame af = fileLoader.LoadFileWaitTillLoaded(file, protocol,
234             format);
235
236     return af;
237   }
238
239 }