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