001/*
002 * Copyright (c) 2002-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.geon;
031
032import java.io.File;
033import java.io.IOException;
034import java.lang.reflect.Method;
035import java.net.URI;
036
037import ptolemy.actor.TypedAtomicActor;
038import ptolemy.actor.TypedIOPort;
039import ptolemy.data.BooleanToken;
040import ptolemy.data.StringToken;
041import ptolemy.data.type.BaseType;
042import ptolemy.gui.MessageHandler;
043import ptolemy.kernel.CompositeEntity;
044import ptolemy.kernel.attributes.URIAttribute;
045import ptolemy.kernel.util.IllegalActionException;
046import ptolemy.kernel.util.NameDuplicationException;
047
048//////////////////////////////////////////////////////////////////////////
049//// BrowserDisplay
050/**
051 * This actor displays a file or a URL using the BrowserLauncher class. The URL
052 * to display is specified through the inputURL port.
053 * 
054 * @UserLevelDocumentation This actor displays a file or a URL specified by
055 *                         inputURL using the the appropriate application.
056 * @author Efrat Jaeger
057 * @version $Id: BrowserDisplay.java 24234 2010-05-06 05:21:26Z welker $
058 * @since Ptolemy II 3.0.2
059 */
060
061public class BrowserDisplay extends TypedAtomicActor {
062
063        /**
064         * Construct an actor with the given container and name.
065         * 
066         * @param container
067         *            The container.
068         * @param name
069         *            The name of this actor.
070         * @exception IllegalActionException
071         *                If the actor cannot be contained by the proposed
072         *                container.
073         * @exception NameDuplicationException
074         *                If the container already has an actor with this name.
075         */
076        public BrowserDisplay(CompositeEntity container, String name)
077                        throws IllegalActionException, NameDuplicationException {
078                super(container, name);
079
080                // fileOrURL = new FileParameter(this, "fileOrURL");
081                inputURL = new TypedIOPort(this, "inputURL", true, false);
082                inputURL.setTypeEquals(BaseType.STRING);
083
084                trigger = new TypedIOPort(this, "trigger", true, false);
085                trigger.setTypeEquals(BaseType.BOOLEAN);
086
087        }
088
089        // /////////////////////////////////////////////////////////////////
090        // // ports and parameters ////
091
092        // public FileParameter fileOrURL;
093
094        /**
095         * The file name or URL to be displayed.
096         * 
097         * @UserLevelDocumentation The input file or URL to be displayed.
098         */
099        public TypedIOPort inputURL;
100
101        /**
102         * A trigger to invoke the actor.
103         * 
104         * @UserLevelDocumentation This port is used to trigger the actor.
105         */
106        public TypedIOPort trigger;
107
108        // /////////////////////////////////////////////////////////////////
109        // // public methods ////
110
111        /**
112         * Display the input file or URL if it is other than null.
113         * 
114         * @exception IllegalActionException
115         *                If there's no director.
116         */
117
118        public void fire() throws IllegalActionException {
119                boolean val = false;
120                for (int i = 0; i < trigger.getWidth(); i++) {
121                        if (trigger.hasToken(i)) {
122                                val = ((BooleanToken) trigger.get(i)).booleanValue();
123                                if (val == false) {
124                                        System.out.println("value is false!!!");
125                                        inputURL.get(0);
126                                        return;
127                                } else
128                                        System.out.println("TRUE!!!");
129                        }
130                }
131                try {
132                        System.out.println("Reading from the browser - val = " + val);
133                        StringToken fileToken = null;
134                        try {
135                                // Check whether a token has been consumed.
136                                fileToken = (StringToken) inputURL.get(0);
137                        } catch (Exception ex) {
138                        }
139                        if (fileToken != null) {
140                                strFileOrURL = fileToken.stringValue();
141                                // the following line replaces all '\\' (double backslashes)
142                                // with single forward slashes
143                                // this is sometimes needed on Windows platforms
144                                // Dan Higgins April 2006
145                                strFileOrURL = strFileOrURL.replaceAll("\\\\\\\\", "/");
146                                int lineEndInd = strFileOrURL.indexOf("\n");
147                                if (lineEndInd != -1) { // Read until the "\n".
148                                        strFileOrURL = strFileOrURL.substring(0, lineEndInd);
149                                }
150                                if (!strFileOrURL.trim().toLowerCase().startsWith("http")) {
151                                        File toDisplay = new File(strFileOrURL);
152                                        if (!toDisplay.isAbsolute()) {
153                                                // Try to resolve the base directory.
154                                                URI modelURI = URIAttribute.getModelURI(this);
155                                                if (modelURI != null) {
156                                                        URI newURI = modelURI.resolve(strFileOrURL);
157                                                        toDisplay = new File(newURI);
158                                                        strFileOrURL = toDisplay.getAbsolutePath();
159                                                }
160                                        }
161                                        String canonicalPath = toDisplay.getCanonicalPath(); // Dan
162                                                                                                                                                        // Higgins
163
164                                        // strFileOrURL = "file:///" + strFileOrURL;
165                                        strFileOrURL = "file:///" + canonicalPath; // Dan Higgins
166                                }
167                                /*
168                                 * else { // The file to display is a file attribute. URL url =
169                                 * fileOrURL.asURL(); strFileOrURL = url.toString(); String
170                                 * decoded = URLDecoder.decode(strFileOrURL); if
171                                 * (decoded.toLowerCase().startsWith("file")) { url = new
172                                 * URL(decoded); if (decoded.charAt(6) != '/') { // should be
173                                 * "file://". strFileOrURL = decoded.substring(0, 6) +
174                                 * decoded.substring(5); //url = new URL(file); } } }
175                                 */
176
177                                BareBonesBrowserLaunch bl = new BareBonesBrowserLaunch(); // Dan
178                                                                                                                                                        // Higgins
179                                bl.openURL(strFileOrURL); // Dan Higgins
180                                // LaunchBrowser lb = new LaunchBrowser(); // Dan Higgins
181                                // lb.displayFileOrURL(strFileOrURL); // Dan Higgins
182                        } else {
183                                // There are no more tokens to consume.
184                                reFire = false;
185                        }
186                } catch (Exception e) {
187                        MessageHandler.error("Error opening browser", e);
188                }
189        }
190
191        /**
192         * If there are no more URLs to display (the input token was null) returns
193         * false.
194         * 
195         * @exception IllegalActionException
196         *                If thrown by the super class.
197         */
198        public boolean postfire() throws IllegalActionException {
199                return reFire;
200        }
201
202        /**
203         * set reFire to true.
204         */
205        public void wrapup() {
206                reFire = true;
207        }
208
209        // /////////////////////////////////////////////////////////////////
210        // // inner classes ////
211
212        /**
213         * Launch the default browser from within java.
214         */
215
216        public class LaunchBrowser {
217                public void displayFileOrURL(String strFileOrURL) {
218                        String cmd = null;
219                        try {
220                                if (isWindows()) {
221                                        String cmdStr = "C:/Program Files/Internet Explorer/IEXPLORE.exe ";
222                                        cmdStr += strFileOrURL;
223                                        // cmd = _winAct + " " + _winFlag + " " + strFileOrURL;
224                                        Process p = Runtime.getRuntime().exec(cmdStr);
225                                        /*
226                                         * try { p.waitFor(); } catch (Exception ex) {
227                                         * MessageHandler.error("Error in waitFor", ex); }
228                                         */
229                                } else {
230                                        cmd = _unixAct + " " + _unixFlag + "(" + strFileOrURL + ")";
231                                        Process p = Runtime.getRuntime().exec(cmd);
232                                        try {
233                                                int exitCode = p.waitFor();
234                                                if (exitCode != 0) {
235                                                        cmd = _unixAct + " " + strFileOrURL;
236                                                        Runtime.getRuntime().exec(cmd);
237                                                }
238                                        } catch (InterruptedException ex) {
239                                                MessageHandler.error("Error opening browser, cmd='"
240                                                                + cmd, ex);
241                                        }
242                                }
243                        } catch (IOException ex) {
244                                MessageHandler.error("Error invoking browser, cmd=" + cmd, ex);
245                        }
246                }
247
248                public boolean isWindows() {
249                        String osName = System.getProperty("os.name");
250                        if (osName != null)
251                                return osName.startsWith(_winOS);
252                        else
253                                return false;
254                }
255
256                private static final String _winOS = "Windows";
257                private static final String _winAct = "rundll32";
258                private static final String _winFlag = "url.dll,FileProtocolHandler";
259
260                private static final String _unixAct = "netscape";
261                private static final String _unixFlag = "-remote openURL";
262        }
263
264        // added by Dan Higgins
265
266        // ///////////////////////////////////////////////////////
267        // Bare Bones Browser Launch //
268        // Version 1.5 //
269        // December 10, 2005 //
270        // Supports: Mac OS X, GNU/Linux, Unix, Windows XP //
271        // Example Usage: //
272        // String url = "http://www.centerkey.com/"; //
273        // BareBonesBrowserLaunch.openURL(url); //
274        // Public Domain Software -- Free to Use as You Like //
275        // ///////////////////////////////////////////////////////
276
277        public class BareBonesBrowserLaunch {
278
279                public void openURL(String url) {
280                        String osName = System.getProperty("os.name");
281                        try {
282                                if (osName.startsWith("Mac OS")) {
283                                        Class fileMgr = Class.forName("com.apple.eio.FileManager");
284                                        Method openURL = fileMgr.getDeclaredMethod("openURL",
285                                                        new Class[] { String.class });
286                                        openURL.invoke(null, new Object[] { url });
287                                } else if (osName.startsWith("Windows"))
288                                        Runtime.getRuntime().exec(
289                                                        "rundll32 url.dll,FileProtocolHandler " + url);
290                                else { // assume Unix or Linux
291                                        String[] browsers = { "firefox", "opera", "konqueror",
292                                                        "epiphany", "mozilla", "netscape" };
293                                        String browser = null;
294                                        for (int count = 0; count < browsers.length
295                                                        && browser == null; count++)
296                                                if (Runtime.getRuntime().exec(
297                                                                new String[] { "which", browsers[count] })
298                                                                .waitFor() == 0)
299                                                        browser = browsers[count];
300                                        if (browser == null)
301                                                throw new Exception("Could not find web browser");
302                                        else
303                                                Runtime.getRuntime()
304                                                                .exec(new String[] { browser, url });
305                                }
306                        } catch (Exception e) {
307                                System.out.println("error in BrowserLauncher - "
308                                                + e.getLocalizedMessage());
309                        }
310                }
311        }
312
313        // end added by Dan Higgins
314
315        /** Represent the URL to be display. */
316        private String strFileOrURL;
317        /** Indicator that there are more tokens to consume. */
318        private boolean reFire = true;
319}