Home | History | Annotate | Download | only in www
      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 
     26 package sun.net.www;
     27 import java.net.URL;
     28 import java.io.*;
     29 import java.util.StringTokenizer;
     30 
     31 public 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