| /* | 
 |  * Copyright (c) 1994, 2002, Oracle and/or its affiliates. All rights reserved. | 
 |  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
 |  * | 
 |  * This code is free software; you can redistribute it and/or modify it | 
 |  * under the terms of the GNU General Public License version 2 only, as | 
 |  * published by the Free Software Foundation.  Oracle designates this | 
 |  * particular file as subject to the "Classpath" exception as provided | 
 |  * by Oracle in the LICENSE file that accompanied this code. | 
 |  * | 
 |  * This code is distributed in the hope that it will be useful, but WITHOUT | 
 |  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
 |  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
 |  * version 2 for more details (a copy is included in the LICENSE file that | 
 |  * accompanied this code). | 
 |  * | 
 |  * You should have received a copy of the GNU General Public License version | 
 |  * 2 along with this work; if not, write to the Free Software Foundation, | 
 |  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
 |  * | 
 |  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
 |  * or visit www.oracle.com if you need additional information or have any | 
 |  * questions. | 
 |  */ | 
 |  | 
 | package sun.net.www; | 
 | import java.net.URL; | 
 | import java.io.*; | 
 | import java.util.StringTokenizer; | 
 |  | 
 | public class MimeEntry implements Cloneable { | 
 |     private String typeName;    // of the form: "type/subtype" | 
 |     private String tempFileNameTemplate; | 
 |  | 
 |     private int action; | 
 |     private String command; | 
 |     private String description; | 
 |     private String imageFileName; | 
 |     private String fileExtensions[]; | 
 |  | 
 |     boolean starred; | 
 |  | 
 |     // Actions | 
 |     public static final int             UNKNOWN                 = 0; | 
 |     public static final int             LOAD_INTO_BROWSER       = 1; | 
 |     public static final int             SAVE_TO_FILE            = 2; | 
 |     public static final int             LAUNCH_APPLICATION      = 3; | 
 |  | 
 |     static final String[] actionKeywords = { | 
 |         "unknown", | 
 |         "browser", | 
 |         "save", | 
 |         "application", | 
 |     }; | 
 |  | 
 |     /** | 
 |      * Construct an empty entry of the given type and subtype. | 
 |      */ | 
 |     public MimeEntry(String type) { | 
 |         // Default action is UNKNOWN so clients can decide what the default | 
 |         // should be, typically save to file or ask user. | 
 |         this(type, UNKNOWN, null, null, null); | 
 |     } | 
 |  | 
 |     // | 
 |     // The next two constructors are used only by the deprecated | 
 |     // PlatformMimeTable classes or, in last case, is called by the public | 
 |     // constructor.  They are kept here anticipating putting support for | 
 |     // mailcap formatted config files back in (so BOTH the properties format | 
 |     // and the mailcap formats are supported). | 
 |     // | 
 |     MimeEntry(String type, String imageFileName, String extensionString) { | 
 |         typeName = type.toLowerCase(); | 
 |         action = UNKNOWN; | 
 |         command = null; | 
 |         this.imageFileName = imageFileName; | 
 |         setExtensions(extensionString); | 
 |         starred = isStarred(typeName); | 
 |     } | 
 |  | 
 |     // For use with MimeTable::parseMailCap | 
 |     MimeEntry(String typeName, int action, String command, | 
 |               String tempFileNameTemplate) { | 
 |         this.typeName = typeName.toLowerCase(); | 
 |         this.action = action; | 
 |         this.command = command; | 
 |         this.imageFileName = null; | 
 |         this.fileExtensions = null; | 
 |  | 
 |         this.tempFileNameTemplate = tempFileNameTemplate; | 
 |     } | 
 |  | 
 |     // This is the one called by the public constructor. | 
 |     MimeEntry(String typeName, int action, String command, | 
 |               String imageFileName, String fileExtensions[]) { | 
 |  | 
 |         this.typeName = typeName.toLowerCase(); | 
 |         this.action = action; | 
 |         this.command = command; | 
 |         this.imageFileName = imageFileName; | 
 |         this.fileExtensions = fileExtensions; | 
 |  | 
 |         starred = isStarred(typeName); | 
 |  | 
 |     } | 
 |  | 
 |     public synchronized String getType() { | 
 |         return typeName; | 
 |     } | 
 |  | 
 |     public synchronized void setType(String type) { | 
 |         typeName = type.toLowerCase(); | 
 |     } | 
 |  | 
 |     public synchronized int getAction() { | 
 |         return action; | 
 |     } | 
 |  | 
 |     public synchronized void setAction(int action, String command) { | 
 |         this.action = action; | 
 |         this.command = command; | 
 |     } | 
 |  | 
 |     public synchronized void setAction(int action) { | 
 |         this.action = action; | 
 |     } | 
 |  | 
 |     public synchronized String getLaunchString() { | 
 |         return command; | 
 |     } | 
 |  | 
 |     public synchronized void setCommand(String command) { | 
 |         this.command = command; | 
 |     } | 
 |  | 
 |     public synchronized String getDescription() { | 
 |         return (description != null ? description : typeName); | 
 |     } | 
 |  | 
 |     public synchronized void setDescription(String description) { | 
 |         this.description = description; | 
 |     } | 
 |  | 
 |     // ??? what to return for the image -- the file name or should this return | 
 |     // something more advanced like an image source or something? | 
 |     // returning the name has the least policy associated with it. | 
 |     // pro tempore, we'll use the name | 
 |     public String getImageFileName() { | 
 |         return imageFileName; | 
 |     } | 
 |  | 
 |     public synchronized void setImageFileName(String filename) { | 
 |         File file = new File(filename); | 
 |         if (file.getParent() == null) { | 
 |             imageFileName = System.getProperty( | 
 |                                      "java.net.ftp.imagepath."+filename); | 
 |         } | 
 |         else { | 
 |             imageFileName = filename; | 
 |         } | 
 |  | 
 |         if (filename.lastIndexOf('.') < 0) { | 
 |             imageFileName = imageFileName + ".gif"; | 
 |         } | 
 |     } | 
 |  | 
 |     public String getTempFileTemplate() { | 
 |         return tempFileNameTemplate; | 
 |     } | 
 |  | 
 |     public synchronized String[] getExtensions() { | 
 |         return fileExtensions; | 
 |     } | 
 |  | 
 |     public synchronized String getExtensionsAsList() { | 
 |         String extensionsAsString = ""; | 
 |         if (fileExtensions != null) { | 
 |             for (int i = 0; i < fileExtensions.length; i++) { | 
 |                 extensionsAsString += fileExtensions[i]; | 
 |                 if (i < (fileExtensions.length - 1)) { | 
 |                     extensionsAsString += ","; | 
 |                 } | 
 |             } | 
 |         } | 
 |  | 
 |         return extensionsAsString; | 
 |     } | 
 |  | 
 |     public synchronized void setExtensions(String extensionString) { | 
 |         StringTokenizer extTokens = new StringTokenizer(extensionString, ","); | 
 |         int numExts = extTokens.countTokens(); | 
 |         String extensionStrings[] = new String[numExts]; | 
 |  | 
 |         for (int i = 0; i < numExts; i++) { | 
 |             String ext = (String)extTokens.nextElement(); | 
 |             extensionStrings[i] = ext.trim(); | 
 |         } | 
 |  | 
 |         fileExtensions = extensionStrings; | 
 |     } | 
 |  | 
 |     private boolean isStarred(String typeName) { | 
 |         return (typeName != null) | 
 |             && (typeName.length() > 0) | 
 |             && (typeName.endsWith("/*")); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Invoke the MIME type specific behavior for this MIME type. | 
 |      * Returned value can be one of several types: | 
 |      * <ol> | 
 |      * <li>A thread -- the caller can choose when to launch this thread. | 
 |      * <li>A string -- the string is loaded into the browser directly. | 
 |      * <li>An input stream -- the caller can read from this byte stream and | 
 |      *     will typically store the results in a file. | 
 |      * <li>A document (?) -- | 
 |      * </ol> | 
 |      */ | 
 |     public Object launch(java.net.URLConnection urlc, InputStream is, MimeTable mt) throws ApplicationLaunchException { | 
 |         switch (action) { | 
 |         case SAVE_TO_FILE: | 
 |             // REMIND: is this really the right thing to do? | 
 |             try { | 
 |                 return is; | 
 |             } catch(Exception e) { | 
 |                 // I18N | 
 |                 return "Load to file failed:\n" + e; | 
 |             } | 
 |  | 
 |         case LOAD_INTO_BROWSER: | 
 |             // REMIND: invoke the content handler? | 
 |             // may be the right thing to do, may not be -- short term | 
 |             // where docs are not loaded asynch, loading and returning | 
 |             // the content is the right thing to do. | 
 |             try { | 
 |                 return urlc.getContent(); | 
 |             } catch (Exception e) { | 
 |                 return null; | 
 |             } | 
 |  | 
 |         case LAUNCH_APPLICATION: | 
 |             { | 
 |                 String threadName = command; | 
 |                 int fst = threadName.indexOf(' '); | 
 |                 if (fst > 0) { | 
 |                     threadName = threadName.substring(0, fst); | 
 |                 } | 
 |  | 
 |                 return new MimeLauncher(this, urlc, is, | 
 |                                         mt.getTempFileTemplate(), threadName); | 
 |             } | 
 |  | 
 |         case UNKNOWN: | 
 |             // REMIND: What do do here? | 
 |             return null; | 
 |         } | 
 |  | 
 |         return null; | 
 |     } | 
 |  | 
 |     public boolean matches(String type) { | 
 |         if (starred) { | 
 |           // REMIND: is this the right thing or not? | 
 |           return type.startsWith(typeName); | 
 |         } else { | 
 |             return type.equals(typeName); | 
 |         } | 
 |     } | 
 |  | 
 |     public Object clone() { | 
 |         // return a shallow copy of this. | 
 |         MimeEntry theClone = new MimeEntry(typeName); | 
 |         theClone.action = action; | 
 |         theClone.command = command; | 
 |         theClone.description = description; | 
 |         theClone.imageFileName = imageFileName; | 
 |         theClone.tempFileNameTemplate = tempFileNameTemplate; | 
 |         theClone.fileExtensions = fileExtensions; | 
 |  | 
 |         return theClone; | 
 |     } | 
 |  | 
 |     public synchronized String toProperty() { | 
 |         StringBuffer buf = new StringBuffer(); | 
 |  | 
 |         String separator = "; "; | 
 |         boolean needSeparator = false; | 
 |  | 
 |         int action = getAction(); | 
 |         if (action != MimeEntry.UNKNOWN) { | 
 |             buf.append("action=" + actionKeywords[action]); | 
 |             needSeparator = true; | 
 |         } | 
 |  | 
 |         String command = getLaunchString(); | 
 |         if (command != null && command.length() > 0) { | 
 |             if (needSeparator) { | 
 |                 buf.append(separator); | 
 |             } | 
 |             buf.append("application=" + command); | 
 |             needSeparator = true; | 
 |         } | 
 |  | 
 |         if (getImageFileName() != null) { | 
 |             if (needSeparator) { | 
 |                 buf.append(separator); | 
 |             } | 
 |             buf.append("icon=" + getImageFileName()); | 
 |             needSeparator = true; | 
 |         } | 
 |  | 
 |         String extensions = getExtensionsAsList(); | 
 |         if (extensions.length() > 0) { | 
 |             if (needSeparator) { | 
 |                 buf.append(separator); | 
 |             } | 
 |             buf.append("file_extensions=" + extensions); | 
 |             needSeparator = true; | 
 |         } | 
 |  | 
 |         String description = getDescription(); | 
 |         if (description != null && !description.equals(getType())) { | 
 |             if (needSeparator) { | 
 |                 buf.append(separator); | 
 |             } | 
 |             buf.append("description=" + description); | 
 |         } | 
 |  | 
 |         return buf.toString(); | 
 |     } | 
 |  | 
 |     public String toString() { | 
 |         return "MimeEntry[contentType=" + typeName | 
 |             + ", image=" + imageFileName | 
 |             + ", action=" + action | 
 |             + ", command=" + command | 
 |             + ", extensions=" + getExtensionsAsList() | 
 |             + "]"; | 
 |     } | 
 | } |