Save This Page
Home » openjdk-7 » sun.net.www.protocol » jar » [javadoc | source]
    1   /*
    2    * Copyright 1997-2006 Sun Microsystems, Inc.  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.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package sun.net.www.protocol.jar;
   27   
   28   import java.io.InputStream;
   29   import java.io.IOException;
   30   import java.io.FileNotFoundException;
   31   import java.io.BufferedInputStream;
   32   import java.net.URL;
   33   import java.net.URLConnection;
   34   import java.net.MalformedURLException;
   35   import java.net.UnknownServiceException;
   36   import java.util.Enumeration;
   37   import java.util.Map;
   38   import java.util.List;
   39   import java.util.jar.JarEntry;
   40   import java.util.jar.JarFile;
   41   import java.util.jar.Manifest;
   42   import java.security.Permission;
   43   
   44   /**
   45    * @author Benjamin Renaud
   46    * @since 1.2
   47    */
   48   public class JarURLConnection extends java.net.JarURLConnection {
   49   
   50       private static final boolean debug = false;
   51   
   52       /* the Jar file factory. It handles both retrieval and caching.
   53        */
   54       private static JarFileFactory factory = new JarFileFactory();
   55   
   56       /* the url for the Jar file */
   57       private URL jarFileURL;
   58   
   59       /* the permission to get this JAR file. This is the actual, ultimate,
   60        * permission, returned by the jar file factory.
   61        */
   62       private Permission permission;
   63   
   64       /* the url connection for the JAR file */
   65       private URLConnection jarFileURLConnection;
   66   
   67       /* the entry name, if any */
   68       private String entryName;
   69   
   70       /* the JarEntry */
   71       private JarEntry jarEntry;
   72   
   73       /* the jar file corresponding to this connection */
   74       private JarFile jarFile;
   75   
   76       /* the content type for this connection */
   77       private String contentType;
   78   
   79       public JarURLConnection(URL url, Handler handler)
   80       throws MalformedURLException, IOException {
   81           super(url);
   82   
   83           jarFileURL = getJarFileURL();
   84           jarFileURLConnection = jarFileURL.openConnection();
   85           entryName = getEntryName();
   86       }
   87   
   88       public JarFile getJarFile() throws IOException {
   89           connect();
   90           return jarFile;
   91       }
   92   
   93       public JarEntry getJarEntry() throws IOException {
   94           connect();
   95           return jarEntry;
   96       }
   97   
   98       public Permission getPermission() throws IOException {
   99           return jarFileURLConnection.getPermission();
  100       }
  101   
  102       class JarURLInputStream extends java.io.FilterInputStream {
  103           JarURLInputStream (InputStream src) {
  104               super (src);
  105           }
  106           public void close () throws IOException {
  107               try {
  108                   super.close();
  109               } finally {
  110                   if (!getUseCaches()) {
  111                       jarFile.close();
  112                   }
  113               }
  114           }
  115       }
  116   
  117   
  118   
  119       public void connect() throws IOException {
  120           if (!connected) {
  121               /* the factory call will do the security checks */
  122               jarFile = factory.get(getJarFileURL(), getUseCaches());
  123   
  124               /* we also ask the factory the permission that was required
  125                * to get the jarFile, and set it as our permission.
  126                */
  127               if (getUseCaches()) {
  128                   jarFileURLConnection = factory.getConnection(jarFile);
  129               }
  130   
  131               if ((entryName != null)) {
  132                   jarEntry = (JarEntry)jarFile.getEntry(entryName);
  133                   if (jarEntry == null) {
  134                       try {
  135                           if (!getUseCaches()) {
  136                               jarFile.close();
  137                           }
  138                       } catch (Exception e) {
  139                       }
  140                       throw new FileNotFoundException("JAR entry " + entryName +
  141                                                       " not found in " +
  142                                                       jarFile.getName());
  143                   }
  144               }
  145               connected = true;
  146           }
  147       }
  148   
  149       public InputStream getInputStream() throws IOException {
  150           connect();
  151   
  152           InputStream result = null;
  153   
  154           if (entryName == null) {
  155               throw new IOException("no entry name specified");
  156           } else {
  157               if (jarEntry == null) {
  158                   throw new FileNotFoundException("JAR entry " + entryName +
  159                                                   " not found in " +
  160                                                   jarFile.getName());
  161               }
  162               result = new JarURLInputStream (jarFile.getInputStream(jarEntry));
  163           }
  164           return result;
  165       }
  166   
  167       public int getContentLength() {
  168           long result = getContentLengthLong();
  169           if (result > Integer.MAX_VALUE)
  170               return -1;
  171           return (int) result;
  172       }
  173   
  174       public long getContentLengthLong() {
  175           long result = -1;
  176           try {
  177               connect();
  178               if (jarEntry == null) {
  179                   /* if the URL referes to an archive */
  180                   result = jarFileURLConnection.getContentLengthLong();
  181               } else {
  182                   /* if the URL referes to an archive entry */
  183                   result = getJarEntry().getSize();
  184               }
  185           } catch (IOException e) {
  186           }
  187           return result;
  188       }
  189   
  190       public Object getContent() throws IOException {
  191           Object result = null;
  192   
  193           connect();
  194           if (entryName == null) {
  195               result = jarFile;
  196           } else {
  197               result = super.getContent();
  198           }
  199           return result;
  200       }
  201   
  202       public String getContentType() {
  203           if (contentType == null) {
  204               if (entryName == null) {
  205                   contentType = "x-java/jar";
  206               } else {
  207                   try {
  208                       connect();
  209                       InputStream in = jarFile.getInputStream(jarEntry);
  210                       contentType = guessContentTypeFromStream(
  211                                           new BufferedInputStream(in));
  212                       in.close();
  213                   } catch (IOException e) {
  214                       // don't do anything
  215                   }
  216               }
  217               if (contentType == null) {
  218                   contentType = guessContentTypeFromName(entryName);
  219               }
  220               if (contentType == null) {
  221                   contentType = "content/unknown";
  222               }
  223           }
  224           return contentType;
  225       }
  226   
  227       public String getHeaderField(String name) {
  228           return jarFileURLConnection.getHeaderField(name);
  229       }
  230   
  231       /**
  232        * Sets the general request property.
  233        *
  234        * @param   key     the keyword by which the request is known
  235        *                  (e.g., "<code>accept</code>").
  236        * @param   value   the value associated with it.
  237        */
  238       public void setRequestProperty(String key, String value) {
  239           jarFileURLConnection.setRequestProperty(key, value);
  240       }
  241   
  242       /**
  243        * Returns the value of the named general request property for this
  244        * connection.
  245        *
  246        * @return  the value of the named general request property for this
  247        *           connection.
  248        */
  249       public String getRequestProperty(String key) {
  250           return jarFileURLConnection.getRequestProperty(key);
  251       }
  252   
  253       /**
  254        * Adds a general request property specified by a
  255        * key-value pair.  This method will not overwrite
  256        * existing values associated with the same key.
  257        *
  258        * @param   key     the keyword by which the request is known
  259        *                  (e.g., "<code>accept</code>").
  260        * @param   value   the value associated with it.
  261        */
  262       public void addRequestProperty(String key, String value) {
  263           jarFileURLConnection.addRequestProperty(key, value);
  264       }
  265   
  266       /**
  267        * Returns an unmodifiable Map of general request
  268        * properties for this connection. The Map keys
  269        * are Strings that represent the request-header
  270        * field names. Each Map value is a unmodifiable List
  271        * of Strings that represents the corresponding
  272        * field values.
  273        *
  274        * @return  a Map of the general request properties for this connection.
  275        */
  276       public Map<String,List<String>> getRequestProperties() {
  277           return jarFileURLConnection.getRequestProperties();
  278       }
  279   
  280       /**
  281        * Set the value of the <code>allowUserInteraction</code> field of
  282        * this <code>URLConnection</code>.
  283        *
  284        * @param   allowuserinteraction   the new value.
  285        * @see     java.net.URLConnection#allowUserInteraction
  286        */
  287       public void setAllowUserInteraction(boolean allowuserinteraction) {
  288           jarFileURLConnection.setAllowUserInteraction(allowuserinteraction);
  289       }
  290   
  291       /**
  292        * Returns the value of the <code>allowUserInteraction</code> field for
  293        * this object.
  294        *
  295        * @return  the value of the <code>allowUserInteraction</code> field for
  296        *          this object.
  297        * @see     java.net.URLConnection#allowUserInteraction
  298        */
  299       public boolean getAllowUserInteraction() {
  300           return jarFileURLConnection.getAllowUserInteraction();
  301       }
  302   
  303       /*
  304        * cache control
  305        */
  306   
  307       /**
  308        * Sets the value of the <code>useCaches</code> field of this
  309        * <code>URLConnection</code> to the specified value.
  310        * <p>
  311        * Some protocols do caching of documents.  Occasionally, it is important
  312        * to be able to "tunnel through" and ignore the caches (e.g., the
  313        * "reload" button in a browser).  If the UseCaches flag on a connection
  314        * is true, the connection is allowed to use whatever caches it can.
  315        *  If false, caches are to be ignored.
  316        *  The default value comes from DefaultUseCaches, which defaults to
  317        * true.
  318        *
  319        * @see     java.net.URLConnection#useCaches
  320        */
  321       public void setUseCaches(boolean usecaches) {
  322           jarFileURLConnection.setUseCaches(usecaches);
  323       }
  324   
  325       /**
  326        * Returns the value of this <code>URLConnection</code>'s
  327        * <code>useCaches</code> field.
  328        *
  329        * @return  the value of this <code>URLConnection</code>'s
  330        *          <code>useCaches</code> field.
  331        * @see     java.net.URLConnection#useCaches
  332        */
  333       public boolean getUseCaches() {
  334           return jarFileURLConnection.getUseCaches();
  335       }
  336   
  337       /**
  338        * Sets the value of the <code>ifModifiedSince</code> field of
  339        * this <code>URLConnection</code> to the specified value.
  340        *
  341        * @param   value   the new value.
  342        * @see     java.net.URLConnection#ifModifiedSince
  343        */
  344       public void setIfModifiedSince(long ifmodifiedsince) {
  345           jarFileURLConnection.setIfModifiedSince(ifmodifiedsince);
  346       }
  347   
  348      /**
  349        * Sets the default value of the <code>useCaches</code> field to the
  350        * specified value.
  351        *
  352        * @param   defaultusecaches   the new value.
  353        * @see     java.net.URLConnection#useCaches
  354        */
  355       public void setDefaultUseCaches(boolean defaultusecaches) {
  356           jarFileURLConnection.setDefaultUseCaches(defaultusecaches);
  357       }
  358   
  359      /**
  360        * Returns the default value of a <code>URLConnection</code>'s
  361        * <code>useCaches</code> flag.
  362        * <p>
  363        * Ths default is "sticky", being a part of the static state of all
  364        * URLConnections.  This flag applies to the next, and all following
  365        * URLConnections that are created.
  366        *
  367        * @return  the default value of a <code>URLConnection</code>'s
  368        *          <code>useCaches</code> flag.
  369        * @see     java.net.URLConnection#useCaches
  370        */
  371       public boolean getDefaultUseCaches() {
  372           return jarFileURLConnection.getDefaultUseCaches();
  373       }
  374   }

Save This Page
Home » openjdk-7 » sun.net.www.protocol » jar » [javadoc | source]