001: /*
002: * @(#)MimeLauncher.java 1.35 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.net.www;
029:
030: import java.net.URL;
031: import java.io.*;
032: import java.util.StringTokenizer;
033:
034: class MimeLauncher extends Thread {
035: java.net.URLConnection uc;
036: MimeEntry m;
037: String genericTempFileTemplate;
038: InputStream is;
039: String execPath;
040:
041: MimeLauncher(MimeEntry M, java.net.URLConnection uc,
042: InputStream is, String tempFileTemplate, String threadName)
043: throws ApplicationLaunchException {
044: super (threadName);
045: m = M;
046: this .uc = uc;
047: this .is = is;
048: genericTempFileTemplate = tempFileTemplate;
049:
050: /* get the application to launch */
051: String launchString = m.getLaunchString();
052:
053: /* get a valid path to launch application - sets
054: the execPath instance variable with the correct path.
055: */
056: if (!findExecutablePath(launchString)) {
057: /* strip off parameters i.e %s */
058: String appName;
059: int index = launchString.indexOf(' ');
060: if (index != -1) {
061: appName = launchString.substring(0, index);
062: } else {
063: appName = launchString;
064: }
065: throw new ApplicationLaunchException(appName);
066: }
067: }
068:
069: protected String getTempFileName(URL url, String template) {
070: String tempFilename = template;
071:
072: // Replace all but last occurrance of "%s" with timestamp to insure
073: // uniqueness. There's a subtle behavior here: if there is anything
074: // _after_ the last "%s" we need to append it so that unusual launch
075: // strings that have the datafile in the middle can still be used.
076: int wildcard = tempFilename.lastIndexOf("%s");
077: String prefix = tempFilename.substring(0, wildcard);
078:
079: String suffix = "";
080: if (wildcard < tempFilename.length() - 2) {
081: suffix = tempFilename.substring(wildcard + 2);
082: }
083:
084: long timestamp = System.currentTimeMillis() / 1000;
085: int argIndex = 0;
086: while ((argIndex = prefix.indexOf("%s")) >= 0) {
087: prefix = prefix.substring(0, argIndex) + timestamp
088: + prefix.substring(argIndex + 2);
089: }
090:
091: // Add a file name and file-extension if known
092: String filename = url.getFile();
093:
094: String extension = "";
095: int dot = filename.lastIndexOf('.');
096:
097: // BugId 4084826: Temp MIME file names not always valid.
098: // Fix: don't allow slashes in the file name or extension.
099: if (dot >= 0 && dot > filename.lastIndexOf('/')) {
100: extension = filename.substring(dot);
101: }
102:
103: filename = "HJ" + url.hashCode();
104:
105: tempFilename = prefix + filename + timestamp + extension
106: + suffix;
107:
108: return tempFilename;
109: }
110:
111: public void run() {
112: try {
113: String ofn = m.getTempFileTemplate();
114: if (ofn == null) {
115: ofn = genericTempFileTemplate;
116: }
117:
118: ofn = getTempFileName(uc.getURL(), ofn);
119: try {
120: OutputStream os = new FileOutputStream(ofn);
121: byte buf[] = new byte[2048];
122: int i = 0;
123: try {
124: while ((i = is.read(buf)) >= 0) {
125: os.write(buf, 0, i);
126: }
127: } catch (IOException e) {
128: //System.err.println("Exception in write loop " + i);
129: //e.printStackTrace();
130: } finally {
131: os.close();
132: is.close();
133: }
134: } catch (IOException e) {
135: //System.err.println("Exception in input or output stream");
136: //e.printStackTrace();
137: }
138:
139: int inx = 0;
140: String c = execPath;
141: while ((inx = c.indexOf("%t")) >= 0) {
142: c = c.substring(0, inx) + uc.getContentType()
143: + c.substring(inx + 2);
144: }
145:
146: boolean substituted = false;
147: while ((inx = c.indexOf("%s")) >= 0) {
148: c = c.substring(0, inx) + ofn + c.substring(inx + 2);
149: substituted = true;
150: }
151: if (!substituted)
152: c = c + " <" + ofn;
153:
154: // System.out.println("Execing " +c);
155:
156: Runtime.getRuntime().exec(c);
157: } catch (IOException e) {
158: }
159: }
160:
161: /* This method determines the path for the launcher application
162: and sets the execPath instance variable. It uses the exec.path
163: property to obtain a list of paths that is in turn used to
164: location the application. If a valid path is not found, it
165: returns false else true. */
166: private boolean findExecutablePath(String str) {
167: if (str == null || str.length() == 0) {
168: return false;
169: }
170:
171: String command;
172: int index = str.indexOf(' ');
173: if (index != -1) {
174: command = str.substring(0, index);
175: } else {
176: command = str;
177: }
178:
179: File f = new File(command);
180: if (f.isFile()) {
181: // Already executable as it is
182: execPath = str;
183: return true;
184: }
185:
186: String execPathList;
187: execPathList = (String) java.security.AccessController
188: .doPrivileged(new sun.security.action.GetPropertyAction(
189: "exec.path"));
190: if (execPathList == null) {
191: // exec.path property not set
192: return false;
193: }
194:
195: StringTokenizer iter = new StringTokenizer(execPathList, "|");
196: while (iter.hasMoreElements()) {
197: String prefix = (String) iter.nextElement();
198: String fullCmd = prefix + File.separator + command;
199: f = new File(fullCmd);
200: if (f.isFile()) {
201: execPath = prefix + File.separator + str;
202: return true;
203: }
204: }
205:
206: return false; // application not found in exec.path
207: }
208: }
|