001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas/
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see https://www.gnu.org/licenses/.
027 */
028
029package edu.wisc.ssec.mcidasv.data;
030
031import java.io.BufferedInputStream;
032import java.io.BufferedReader;
033import java.io.DataInputStream;
034import java.io.InputStream;
035import java.io.InputStreamReader;
036import java.net.URL;
037import java.net.URLConnection;
038import java.util.ArrayList;
039import java.util.List;
040import java.util.StringTokenizer;
041
042import ucar.unidata.util.IOUtil;
043
044/**
045 * Class McIdasXInfo Holds the state of the McIDAS-X session
046 * on the other end of the bridge
047 */
048public class McIdasXInfo {
049
050    /** Conduit protocol info */
051    private String versionString = "2";
052    private String hostString = "localhost";
053    private String portString = "8080";
054    private String keyString = "00000000000000000000000000000000";
055    
056    /**
057     * Constructor
058     */
059    public McIdasXInfo() {}
060
061    /**
062     * Copy constructor
063     *
064     * @param that The McIdasXInfo to copy
065     *
066     */
067    public McIdasXInfo(McIdasXInfo that) {
068        this.hostString = that.hostString;
069        this.portString = that.portString;
070        this.keyString  = that.keyString;
071    }
072
073    /**
074     * Constructor
075     */
076    public McIdasXInfo(String host, String port, String key) {
077        this.hostString = host;
078        this.portString = port;
079        this.keyString  = key;
080    }
081
082    /**
083     * Get the hostString property.
084     *
085     * @return The hostString property.
086     */
087    public String getHostString() {
088        return this.hostString;
089    }
090
091    /**
092     * Get the portString property.
093     *
094     * @return The portString property.
095     */
096    public String getPortString() {
097        return this.portString;
098    }
099
100    /**
101     * Get the keyString property.
102     *
103     * @return The keyString property.
104     */
105    public String getKeyString() {
106        return this.keyString;
107    }
108
109    /**
110     * Set the hostString property.
111     *
112     * @param newValue The new vaue for the hostString property.
113     */
114    public void setHostString(String newValue) {
115        this.hostString = newValue;
116    }
117
118    /**
119     * Set the portString property.
120     *
121     * @param newValue The new vaue for the portString property.
122     */
123    public void setPortString(String newValue) {
124        this.portString = newValue;
125    }
126
127    /**
128     * Set the keyString property.
129     *
130     * @param newValue The new vaue for the keyString property.
131     */
132    public void setKeyString(String newValue) {
133        this.keyString = newValue;
134    }
135    
136    /**
137     * Get the frame request string.
138     *
139     * @return The frame request string.
140     */
141    private String getFrameRequest() {
142        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
143                                "&version=" + versionString + "&frame=0&x=0&y=0&type=V";
144    }
145    
146    /**
147     * Get the frames request string.
148     *
149     * @return The frames request string.
150     */
151    private String getFramesRequest() {
152        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
153                                "&version=" + versionString + "&frame=0&x=0&y=0&type=U";
154    }
155    
156    /**
157     * Get the file request string.
158     *
159     * @return The file request string.
160     */
161    private String getFileRequest(String filename) {
162        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
163                                "&version=" + versionString + "&frame=0&x=0&y=0&type=F&text=" + filename;
164    }
165    
166    /**
167     * Get the file request DataInputStream.
168     *
169     * @return The file request DataInputStream.
170     */
171    public DataInputStream getFileInputStream(String filename) {
172        return getXInputStream(getFileRequest(filename));
173    }
174    
175    /**
176     * Get the data request string.
177     *
178     * @return The data request string.
179     */
180    private String getDataRequest(Integer frame) {
181        if (frame < 1) frame = getCurrentFrame();
182        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
183                                "&version=" + versionString + "&frame=0&x=0&y=0&type=D&text=" + frame;
184    }
185    
186    /**
187     * Get the data request DataInputStream.
188     *
189     * @return The data request DataInputStream.
190     */
191    public DataInputStream getDataInputStream(Integer frame) {
192        if (frame < 1) frame = getCurrentFrame();
193        return getXInputStream(getDataRequest(frame));
194    }
195    
196    /**
197     * Get the graphics request string.
198     *
199     * @return The graphics request string.
200     */
201    private String getGraphicsRequest(Integer frame) {
202        if (frame < 1) frame = getCurrentFrame();
203        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
204                                "&version=" + versionString + "&frame=0&x=0&y=0&type=P&text=" + frame;
205    }
206    
207    /**
208     * Get the graphics request DataInputStream.
209     *
210     * @return The graphics request DataInputStream.
211     */
212    public DataInputStream getGraphicsInputStream(Integer frame) {
213        return getXInputStream(getGraphicsRequest(frame));
214    }
215    
216    /**
217     * Get the command request string.
218     *
219     * @return The command request string.
220     */
221    private String getCommandRequest(String commandLine) {
222        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
223                                "&version=" + versionString + "&frame=0&x=0&y=0&type=T&text=" + commandLine;
224    }
225    
226    /**
227     * Get the command request string.
228     *
229     * @return The command request string.
230     */
231    private String getCommandRequest(String commandLine, int frame) {
232        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
233                                "&version=" + versionString + "&frame=" + frame + "&x=0&y=0&type=T&text=" + commandLine;
234    }
235    
236    /**
237     * Get the command request DataInputStream.
238     *
239     * @return The command request DataInputStream.
240     */
241    public DataInputStream getCommandInputStream(String commandLine) {
242        return getXInputStream(getCommandRequest(commandLine));
243    }
244    
245    /**
246     * Get the command request DataInputStream.
247     *
248     * @return The command request DataInputStream.
249     */
250    public DataInputStream getCommandInputStream(String commandLine, int frame) {
251        return getXInputStream(getCommandRequest(commandLine, frame));
252    }
253    
254    /**
255     * Get the GIF request string.
256     *
257     * @return The GIF request string.
258     */
259    private String getGIFRequest(Integer frame) {
260        return "http://" + hostString  + ":" + portString + "/?sessionkey=" + keyString +
261                                "&version=" + versionString + "&frame=0&x=0&y=0&type=C&text=" + frame;
262    }
263    
264    /**
265     * Get the GIF request DataInputStream.
266     *
267     * @return The GIF request DataInputStream.
268     */
269    public DataInputStream getGIFInputStream(Integer frame) {
270        return getXInputStream(getGIFRequest(frame));
271    }
272
273    /**
274     * Get a String representation of this object
275     * 
276     * @return a string representation
277     */
278    public String toString() {
279        StringBuffer buf = new StringBuffer();
280        buf.append("McIdasXInfo as string: ");
281        buf.append("hostString=");
282        buf.append(this.hostString);
283        buf.append(", portString=");
284        buf.append(this.portString);
285        buf.append(", keyString=");
286        buf.append(this.keyString);
287        return buf.toString();
288    }
289
290    /**
291     * Get a DataInputStream from a given request String.
292     * 
293     * @return a DataInputStream
294     */
295    private DataInputStream getXInputStream(String newRequest) {
296        URLConnection urlc;
297        DataInputStream retStream = null;
298        try {
299            urlc = IOUtil.getUrlConnection(newRequest);
300            InputStream is = urlc.getInputStream();
301            retStream = new DataInputStream(new BufferedInputStream(is));
302        } catch (Exception e) {
303            return retStream;
304        }
305        return retStream;
306    }
307    
308    /**
309     * Get the current frame in McIDAS-X.
310     * 
311     * @return The current frame in McIDAS-X.
312     */
313    public int getCurrentFrame() {
314        int ret = -1;
315        DataInputStream inputStream = getXInputStream(getFrameRequest());
316        try {
317                BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
318                // Burn key line
319                String lineOut = br.readLine();
320                lineOut = br.readLine();
321                StringTokenizer tok = new StringTokenizer(lineOut, " ");
322            String responseType = tok.nextToken();
323            if (!responseType.equals("V")) {
324                System.out.println("getCurrentFrame unexpected responseType: " + responseType);
325                try { inputStream.close(); }
326                catch (Exception ee) {}
327                return ret;
328            }
329            ret = Integer.parseInt(tok.nextToken());
330            } catch (Exception e) {
331                System.out.println("getCurrentFrame exception: " + e);
332            try { inputStream.close(); }
333            catch (Exception ee) {}
334                return ret;
335            }
336        System.out.println("getCurrentFrame: " + ret);
337            return ret;
338    }
339    
340    /**
341     * Get the number of frames in McIDAS-X.
342     * 
343     * @return The number of frames in McIDAS-X.
344     */
345    public int getNumberOfFrames() {
346        int ret = -1;
347        String token = null;
348        DataInputStream inputStream = getXInputStream(getFrameRequest());
349        try {
350                BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
351                // Burn key line
352                String lineOut = br.readLine();
353                lineOut = br.readLine();
354                StringTokenizer tok = new StringTokenizer(lineOut, " ");
355            String responseType = tok.nextToken();
356            if (!responseType.equals("V")) {
357                System.out.println("getNumberOfFrames unexpected responseType: " + responseType);
358                try { inputStream.close(); }
359                catch (Exception ee) {}
360                return ret;
361            }
362            token = tok.nextToken();
363            token = tok.nextToken();
364            ret = Integer.parseInt(token.substring(1,4));
365            } catch (Exception e) {
366                System.out.println("getNumberOfFrames exception: " + e);
367            try { inputStream.close(); }
368            catch (Exception ee) {}
369                return ret;
370            }
371        System.out.println("getNumberOfFrames: " + ret);
372            return ret;
373    }
374    
375    /**
376     * Get the list of frame numbers in McIDAS-X.
377     * 
378     * @return The list of frame numbers in McIDAS-X.
379     */
380    public List getFrameNumbers() {
381        List frameNumbers = new ArrayList();
382        DataInputStream inputStream = getXInputStream(getFramesRequest());
383        if (inputStream == null) return frameNumbers;
384        String responseType = null;
385        StringTokenizer tok;
386        try {
387                BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
388                // Burn key line
389                String lineOut = br.readLine();
390                lineOut = br.readLine();
391                while (lineOut != null) {
392                        tok = new StringTokenizer(lineOut, " ");
393                    responseType = tok.nextToken();
394                    if (!responseType.equals("U")) {
395                        System.out.println("getFrameNumbers unexpected responseType: " + responseType);
396                        try { inputStream.close(); }
397                        catch (Exception ee) {}
398                        return frameNumbers;
399                    }
400                    Integer frameInt = Integer.parseInt(tok.nextToken());
401                    frameNumbers.add(frameInt);
402                    lineOut = br.readLine();
403                }
404            } catch (Exception e) {
405                System.out.println("getFrameNumbers exception: " + e);
406            try { inputStream.close(); }
407            catch (Exception ee) {}
408                return frameNumbers;
409            }
410//        System.out.println("getFrameNumbers: " + frameNumbers);
411            return frameNumbers;
412    }
413    
414}