1/* 2 * Copyright (c) 1994, 2002, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package sun.net.www; 27import java.net.URL; 28import java.io.*; 29import java.util.StringTokenizer; 30 31public class MimeEntry implements Cloneable { 32 private String typeName; // of the form: "type/subtype" 33 private String tempFileNameTemplate; 34 35 private int action; 36 private String command; 37 private String description; 38 private String imageFileName; 39 private String fileExtensions[]; 40 41 boolean starred; 42 43 // Actions 44 public static final int UNKNOWN = 0; 45 public static final int LOAD_INTO_BROWSER = 1; 46 public static final int SAVE_TO_FILE = 2; 47 public static final int LAUNCH_APPLICATION = 3; 48 49 static final String[] actionKeywords = { 50 "unknown", 51 "browser", 52 "save", 53 "application", 54 }; 55 56 /** 57 * Construct an empty entry of the given type and subtype. 58 */ 59 public MimeEntry(String type) { 60 // Default action is UNKNOWN so clients can decide what the default 61 // should be, typically save to file or ask user. 62 this(type, UNKNOWN, null, null, null); 63 } 64 65 // 66 // The next two constructors are used only by the deprecated 67 // PlatformMimeTable classes or, in last case, is called by the public 68 // constructor. They are kept here anticipating putting support for 69 // mailcap formatted config files back in (so BOTH the properties format 70 // and the mailcap formats are supported). 71 // 72 MimeEntry(String type, String imageFileName, String extensionString) { 73 typeName = type.toLowerCase(); 74 action = UNKNOWN; 75 command = null; 76 this.imageFileName = imageFileName; 77 setExtensions(extensionString); 78 starred = isStarred(typeName); 79 } 80 81 // For use with MimeTable::parseMailCap 82 MimeEntry(String typeName, int action, String command, 83 String tempFileNameTemplate) { 84 this.typeName = typeName.toLowerCase(); 85 this.action = action; 86 this.command = command; 87 this.imageFileName = null; 88 this.fileExtensions = null; 89 90 this.tempFileNameTemplate = tempFileNameTemplate; 91 } 92 93 // This is the one called by the public constructor. 94 MimeEntry(String typeName, int action, String command, 95 String imageFileName, String fileExtensions[]) { 96 97 this.typeName = typeName.toLowerCase(); 98 this.action = action; 99 this.command = command; 100 this.imageFileName = imageFileName; 101 this.fileExtensions = fileExtensions; 102 103 starred = isStarred(typeName); 104 105 } 106 107 public synchronized String getType() { 108 return typeName; 109 } 110 111 public synchronized void setType(String type) { 112 typeName = type.toLowerCase(); 113 } 114 115 public synchronized int getAction() { 116 return action; 117 } 118 119 public synchronized void setAction(int action, String command) { 120 this.action = action; 121 this.command = command; 122 } 123 124 public synchronized void setAction(int action) { 125 this.action = action; 126 } 127 128 public synchronized String getLaunchString() { 129 return command; 130 } 131 132 public synchronized void setCommand(String command) { 133 this.command = command; 134 } 135 136 public synchronized String getDescription() { 137 return (description != null ? description : typeName); 138 } 139 140 public synchronized void setDescription(String description) { 141 this.description = description; 142 } 143 144 // ??? what to return for the image -- the file name or should this return 145 // something more advanced like an image source or something? 146 // returning the name has the least policy associated with it. 147 // pro tempore, we'll use the name 148 public String getImageFileName() { 149 return imageFileName; 150 } 151 152 public synchronized void setImageFileName(String filename) { 153 File file = new File(filename); 154 if (file.getParent() == null) { 155 imageFileName = System.getProperty( 156 "java.net.ftp.imagepath."+filename); 157 } 158 else { 159 imageFileName = filename; 160 } 161 162 if (filename.lastIndexOf('.') < 0) { 163 imageFileName = imageFileName + ".gif"; 164 } 165 } 166 167 public String getTempFileTemplate() { 168 return tempFileNameTemplate; 169 } 170 171 public synchronized String[] getExtensions() { 172 return fileExtensions; 173 } 174 175 public synchronized String getExtensionsAsList() { 176 String extensionsAsString = ""; 177 if (fileExtensions != null) { 178 for (int i = 0; i < fileExtensions.length; i++) { 179 extensionsAsString += fileExtensions[i]; 180 if (i < (fileExtensions.length - 1)) { 181 extensionsAsString += ","; 182 } 183 } 184 } 185 186 return extensionsAsString; 187 } 188 189 public synchronized void setExtensions(String extensionString) { 190 StringTokenizer extTokens = new StringTokenizer(extensionString, ","); 191 int numExts = extTokens.countTokens(); 192 String extensionStrings[] = new String[numExts]; 193 194 for (int i = 0; i < numExts; i++) { 195 String ext = (String)extTokens.nextElement(); 196 extensionStrings[i] = ext.trim(); 197 } 198 199 fileExtensions = extensionStrings; 200 } 201 202 private boolean isStarred(String typeName) { 203 return (typeName != null) 204 && (typeName.length() > 0) 205 && (typeName.endsWith("/*")); 206 } 207 208 /** 209 * Invoke the MIME type specific behavior for this MIME type. 210 * Returned value can be one of several types: 211 * <ol> 212 * <li>A thread -- the caller can choose when to launch this thread. 213 * <li>A string -- the string is loaded into the browser directly. 214 * <li>An input stream -- the caller can read from this byte stream and 215 * will typically store the results in a file. 216 * <li>A document (?) -- 217 * </ol> 218 */ 219 public Object launch(java.net.URLConnection urlc, InputStream is, MimeTable mt) throws ApplicationLaunchException { 220 switch (action) { 221 case SAVE_TO_FILE: 222 // REMIND: is this really the right thing to do? 223 try { 224 return is; 225 } catch(Exception e) { 226 // I18N 227 return "Load to file failed:\n" + e; 228 } 229 230 case LOAD_INTO_BROWSER: 231 // REMIND: invoke the content handler? 232 // may be the right thing to do, may not be -- short term 233 // where docs are not loaded asynch, loading and returning 234 // the content is the right thing to do. 235 try { 236 return urlc.getContent(); 237 } catch (Exception e) { 238 return null; 239 } 240 241 case LAUNCH_APPLICATION: 242 { 243 String threadName = command; 244 int fst = threadName.indexOf(' '); 245 if (fst > 0) { 246 threadName = threadName.substring(0, fst); 247 } 248 249 return new MimeLauncher(this, urlc, is, 250 mt.getTempFileTemplate(), threadName); 251 } 252 253 case UNKNOWN: 254 // REMIND: What do do here? 255 return null; 256 } 257 258 return null; 259 } 260 261 public boolean matches(String type) { 262 if (starred) { 263 // REMIND: is this the right thing or not? 264 return type.startsWith(typeName); 265 } else { 266 return type.equals(typeName); 267 } 268 } 269 270 public Object clone() { 271 // return a shallow copy of this. 272 MimeEntry theClone = new MimeEntry(typeName); 273 theClone.action = action; 274 theClone.command = command; 275 theClone.description = description; 276 theClone.imageFileName = imageFileName; 277 theClone.tempFileNameTemplate = tempFileNameTemplate; 278 theClone.fileExtensions = fileExtensions; 279 280 return theClone; 281 } 282 283 public synchronized String toProperty() { 284 StringBuffer buf = new StringBuffer(); 285 286 String separator = "; "; 287 boolean needSeparator = false; 288 289 int action = getAction(); 290 if (action != MimeEntry.UNKNOWN) { 291 buf.append("action=" + actionKeywords[action]); 292 needSeparator = true; 293 } 294 295 String command = getLaunchString(); 296 if (command != null && command.length() > 0) { 297 if (needSeparator) { 298 buf.append(separator); 299 } 300 buf.append("application=" + command); 301 needSeparator = true; 302 } 303 304 if (getImageFileName() != null) { 305 if (needSeparator) { 306 buf.append(separator); 307 } 308 buf.append("icon=" + getImageFileName()); 309 needSeparator = true; 310 } 311 312 String extensions = getExtensionsAsList(); 313 if (extensions.length() > 0) { 314 if (needSeparator) { 315 buf.append(separator); 316 } 317 buf.append("file_extensions=" + extensions); 318 needSeparator = true; 319 } 320 321 String description = getDescription(); 322 if (description != null && !description.equals(getType())) { 323 if (needSeparator) { 324 buf.append(separator); 325 } 326 buf.append("description=" + description); 327 } 328 329 return buf.toString(); 330 } 331 332 public String toString() { 333 return "MimeEntry[contentType=" + typeName 334 + ", image=" + imageFileName 335 + ", action=" + action 336 + ", command=" + command 337 + ", extensions=" + getExtensionsAsList() 338 + "]"; 339 } 340} 341