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