001: /*
002: * @(#)JarURLConnection.java 1.28 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.protocol.jar;
029:
030: import java.io.InputStream;
031: import java.io.IOException;
032: import java.io.FileNotFoundException;
033: import java.io.BufferedInputStream;
034: import java.net.URL;
035: import java.net.URLConnection;
036: import java.net.MalformedURLException;
037: import java.net.UnknownServiceException;
038: import java.util.jar.JarEntry;
039: import java.util.jar.JarFile;
040: import java.security.Permission;
041:
042: /**
043: * @author Benjamin Renaud
044: * @since JDK1.2
045: */
046: public class JarURLConnection extends java.net.JarURLConnection {
047:
048: private static final boolean debug = false;
049:
050: /* the Jar file factory. It handles both retrieval and caching.
051: */
052: private static JarFileFactory factory = new JarFileFactory();
053:
054: /* the url for the Jar file */
055: private URL jarFileURL;
056:
057: /* the url connection for the JAR file */
058: private URLConnection jarFileURLConnection;
059:
060: /* the entry name, if any */
061: private String entryName;
062:
063: /* the JarEntry */
064: private JarEntry jarEntry;
065:
066: /* the jar file corresponding to this connection */
067: private JarFile jarFile;
068:
069: /* the content type for this connection */
070: private String contentType;
071:
072: public JarURLConnection(URL url, Handler handler)
073: throws MalformedURLException, IOException {
074: super (url);
075:
076: jarFileURL = getJarFileURL();
077: jarFileURLConnection = jarFileURL.openConnection();
078: entryName = getEntryName();
079: }
080:
081: public JarFile getJarFile() throws IOException {
082: connect();
083: return jarFile;
084: }
085:
086: public JarEntry getJarEntry() throws IOException {
087: connect();
088: return jarEntry;
089: }
090:
091: public Permission getPermission() throws IOException {
092: return jarFileURLConnection.getPermission();
093: }
094:
095: public void connect() throws IOException {
096: if (!connected) {
097: /* the factory call will do the security checks */
098: jarFile = factory.get(jarFileURL, getUseCaches());
099:
100: /* we also ask the factory the permission that was required
101: * to get the jarFile, and set it as our permission.
102: */
103: jarFileURLConnection = factory.getConnection(jarFile);
104:
105: if ((entryName != null)) {
106: jarEntry = (JarEntry) jarFile.getEntry(entryName);
107: if (jarEntry == null) {
108: throw new FileNotFoundException("JAR entry "
109: + entryName + " not found in "
110: + jarFile.getName());
111: }
112: }
113: connected = true;
114: }
115: }
116:
117: public InputStream getInputStream() throws IOException {
118: connect();
119:
120: InputStream result = null;
121:
122: if (entryName == null) {
123: throw new IOException("no entry name specified");
124: } else {
125: if (jarEntry == null) {
126: throw new FileNotFoundException("JAR entry "
127: + entryName + " not found in "
128: + jarFile.getName());
129: }
130: result = jarFile.getInputStream(jarEntry);
131: }
132: return result;
133: }
134:
135: public int getContentLength() {
136: int result = -1;
137: try {
138: connect();
139: if (jarEntry == null) {
140: /* if the URL referes to an archive */
141: result = jarFileURLConnection.getContentLength();
142: } else {
143: /* if the URL referes to an archive entry */
144: result = (int) getJarEntry().getSize();
145: }
146: } catch (IOException e) {
147: }
148: return result;
149: }
150:
151: public Object getContent() throws IOException {
152: Object result = null;
153:
154: connect();
155: if (entryName == null) {
156: result = jarFile;
157: } else {
158: result = super .getContent();
159: }
160: return result;
161: }
162:
163: public String getContentType() {
164: if (contentType == null) {
165: if (entryName == null) {
166: contentType = "x-java/jar";
167: } else {
168: try {
169: connect();
170: InputStream in = jarFile.getInputStream(jarEntry);
171: contentType = guessContentTypeFromStream(new BufferedInputStream(
172: in));
173: in.close();
174: } catch (IOException e) {
175: // don't do anything
176: }
177: }
178: if (contentType == null) {
179: contentType = guessContentTypeFromName(entryName);
180: }
181: if (contentType == null) {
182: contentType = "content/unknown";
183: }
184: }
185: return contentType;
186: }
187:
188: public String getHeaderField(String name) {
189: return jarFileURLConnection.getHeaderField(name);
190: }
191:
192: /**
193: * Sets the general request property.
194: *
195: * @param key the keyword by which the request is known
196: * (e.g., "<code>accept</code>").
197: * @param value the value associated with it.
198: */
199: public void setRequestProperty(String key, String value) {
200: jarFileURLConnection.setRequestProperty(key, value);
201: }
202:
203: /**
204: * Returns the value of the named general request property for this
205: * connection.
206: *
207: * @return the value of the named general request property for this
208: * connection.
209: */
210: public String getRequestProperty(String key) {
211: return jarFileURLConnection.getRequestProperty(key);
212: }
213:
214: /**
215: * Set the value of the <code>allowUserInteraction</code> field of
216: * this <code>URLConnection</code>.
217: *
218: * @param allowuserinteraction the new value.
219: * @see java.net.URLConnection#allowUserInteraction
220: */
221: public void setAllowUserInteraction(boolean allowuserinteraction) {
222: jarFileURLConnection
223: .setAllowUserInteraction(allowuserinteraction);
224: }
225:
226: /**
227: * Returns the value of the <code>allowUserInteraction</code> field for
228: * this object.
229: *
230: * @return the value of the <code>allowUserInteraction</code> field for
231: * this object.
232: * @see java.net.URLConnection#allowUserInteraction
233: */
234: public boolean getAllowUserInteraction() {
235: return jarFileURLConnection.getAllowUserInteraction();
236: }
237:
238: /*
239: * cache control
240: */
241:
242: /**
243: * Sets the value of the <code>useCaches</code> field of this
244: * <code>URLConnection</code> to the specified value.
245: * <p>
246: * Some protocols do caching of documents. Occasionally, it is important
247: * to be able to "tunnel through" and ignore the caches (e.g., the
248: * "reload" button in a browser). If the UseCaches flag on a connection
249: * is true, the connection is allowed to use whatever caches it can.
250: * If false, caches are to be ignored.
251: * The default value comes from DefaultUseCaches, which defaults to
252: * true.
253: *
254: * @see java.net.URLConnection#useCaches
255: */
256: public void setUseCaches(boolean usecaches) {
257: jarFileURLConnection.setUseCaches(usecaches);
258: }
259:
260: /**
261: * Returns the value of this <code>URLConnection</code>'s
262: * <code>useCaches</code> field.
263: *
264: * @return the value of this <code>URLConnection</code>'s
265: * <code>useCaches</code> field.
266: * @see java.net.URLConnection#useCaches
267: */
268: public boolean getUseCaches() {
269: return jarFileURLConnection.getUseCaches();
270: }
271:
272: /**
273: * Sets the value of the <code>ifModifiedSince</code> field of
274: * this <code>URLConnection</code> to the specified value.
275: *
276: * @param value the new value.
277: * @see java.net.URLConnection#ifModifiedSince
278: */
279: public void setIfModifiedSince(long ifmodifiedsince) {
280: jarFileURLConnection.setIfModifiedSince(ifmodifiedsince);
281: }
282:
283: /**
284: * Sets the default value of the <code>useCaches</code> field to the
285: * specified value.
286: *
287: * @param defaultusecaches the new value.
288: * @see java.net.URLConnection#useCaches
289: */
290: public void setDefaultUseCaches(boolean defaultusecaches) {
291: jarFileURLConnection.setDefaultUseCaches(defaultusecaches);
292: }
293:
294: /**
295: * Returns the default value of a <code>URLConnection</code>'s
296: * <code>useCaches</code> flag.
297: * <p>
298: * Ths default is "sticky", being a part of the static state of all
299: * URLConnections. This flag applies to the next, and all following
300: * URLConnections that are created.
301: *
302: * @return the default value of a <code>URLConnection</code>'s
303: * <code>useCaches</code> flag.
304: * @see java.net.URLConnection#useCaches
305: */
306: public boolean getDefaultUseCaches() {
307: return jarFileURLConnection.getDefaultUseCaches();
308: }
309: }
|