KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > net > URLConnection


1 /*
2  * @(#)URLConnection.java 1.102 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.net;
9
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12 import java.io.OutputStream JavaDoc;
13 import java.util.Hashtable JavaDoc;
14 import java.util.Date JavaDoc;
15 import java.util.StringTokenizer JavaDoc;
16 import java.util.Collections JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.List JavaDoc;
19 import java.security.Permission JavaDoc;
20 import java.security.AccessController JavaDoc;
21 import sun.security.util.SecurityConstants;
22
23 /**
24  * The abstract class <code>URLConnection</code> is the superclass
25  * of all classes that represent a communications link between the
26  * application and a URL. Instances of this class can be used both to
27  * read from and to write to the resource referenced by the URL. In
28  * general, creating a connection to a URL is a multistep process:
29  * <p>
30  * <center><table border=2 summary="Describes the process of creating a connection to a URL: openConnection() and connect() over time.">
31  * <tr><th><code>openConnection()</code></th>
32  * <th><code>connect()</code></th></tr>
33  * <tr><td>Manipulate parameters that affect the connection to the remote
34  * resource.</td>
35  * <td>Interact with the resource; query header fields and
36  * contents.</td></tr>
37  * </table>
38  * ----------------------------&gt;
39  * <br>time</center>
40  *
41  * <ol>
42  * <li>The connection object is created by invoking the
43  * <code>openConnection</code> method on a URL.
44  * <li>The setup parameters and general request properties are manipulated.
45  * <li>The actual connection to the remote object is made, using the
46  * <code>connect</code> method.
47  * <li>The remote object becomes available. The header fields and the contents
48  * of the remote object can be accessed.
49  * </ol>
50  * <p>
51  * The setup parameters are modified using the following methods:
52  * <ul>
53  * <li><code>setAllowUserInteraction</code>
54  * <li><code>setDoInput</code>
55  * <li><code>setDoOutput</code>
56  * <li><code>setIfModifiedSince</code>
57  * <li><code>setUseCaches</code>
58  * </ul>
59  * <p>
60  * and the general request properties are modified using the method:
61  * <ul>
62  * <li><code>setRequestProperty</code>
63  * </ul>
64  * <p>
65  * Default values for the <code>AllowUserInteraction</code> and
66  * <code>UseCaches</code> parameters can be set using the methods
67  * <code>setDefaultAllowUserInteraction</code> and
68  * <code>setDefaultUseCaches</code>.
69  * <p>
70  * Each of the above <code>set</code> methods has a corresponding
71  * <code>get</code> method to retrieve the value of the parameter or
72  * general request property. The specific parameters and general
73  * request properties that are applicable are protocol specific.
74  * <p>
75  * The following methods are used to access the header fields and
76  * the contents after the connection is made to the remote object:
77  * <ul>
78  * <li><code>getContent</code>
79  * <li><code>getHeaderField</code>
80  * <li><code>getInputStream</code>
81  * <li><code>getOutputStream</code>
82  * </ul>
83  * <p>
84  * Certain header fields are accessed frequently. The methods:
85  * <ul>
86  * <li><code>getContentEncoding</code>
87  * <li><code>getContentLength</code>
88  * <li><code>getContentType</code>
89  * <li><code>getDate</code>
90  * <li><code>getExpiration</code>
91  * <li><code>getLastModifed</code>
92  * </ul>
93  * <p>
94  * provide convenient access to these fields. The
95  * <code>getContentType</code> method is used by the
96  * <code>getContent</code> method to determine the type of the remote
97  * object; subclasses may find it convenient to override the
98  * <code>getContentType</code> method.
99  * <p>
100  * In the common case, all of the pre-connection parameters and
101  * general request properties can be ignored: the pre-connection
102  * parameters and request properties default to sensible values. For
103  * most clients of this interface, there are only two interesting
104  * methods: <code>getInputStream</code> and <code>getContent</code>,
105  * which are mirrored in the <code>URL</code> class by convenience methods.
106  * <p>
107  * More information on the request properties and header fields of
108  * an <code>http</code> connection can be found at:
109  * <blockquote><pre>
110  * <a HREF="http://www.ietf.org/rfc/rfc2068.txt">http://www.ietf.org/rfc/rfc2068.txt</a>
111  * </pre></blockquote>
112  *
113  * Note about <code>fileNameMap</code>: In versions prior to JDK 1.1.6,
114  * field <code>fileNameMap</code> of <code>URLConnection</code> was public.
115  * In JDK 1.1.6 and later, <code>fileNameMap</code> is private; accessor
116  * and mutator methods {@link #getFileNameMap() getFileNameMap} and
117  * {@link #setFileNameMap(java.net.FileNameMap) setFileNameMap} are added
118  * to access it. This change is also described on the <a HREF=
119  * "http://java.sun.com/products/jdk/1.2/compatibility.html#incompatibilities1.2">
120  * Compatibility</a> page.
121  *
122  * Invoking the <tt>close()</tt> methods on the <tt>InputStream</tt> or <tt>OutputStream</tt> of an
123  * <tt>URLConnection</tt> after a request may free network resources associated with this
124  * instance, unless particular protocol specifications specify different behaviours
125  * for it.
126  *
127  * @author James Gosling
128  * @version 1.102, 05/18/04
129  * @see java.net.URL#openConnection()
130  * @see java.net.URLConnection#connect()
131  * @see java.net.URLConnection#getContent()
132  * @see java.net.URLConnection#getContentEncoding()
133  * @see java.net.URLConnection#getContentLength()
134  * @see java.net.URLConnection#getContentType()
135  * @see java.net.URLConnection#getDate()
136  * @see java.net.URLConnection#getExpiration()
137  * @see java.net.URLConnection#getHeaderField(int)
138  * @see java.net.URLConnection#getHeaderField(java.lang.String)
139  * @see java.net.URLConnection#getInputStream()
140  * @see java.net.URLConnection#getLastModified()
141  * @see java.net.URLConnection#getOutputStream()
142  * @see java.net.URLConnection#setAllowUserInteraction(boolean)
143  * @see java.net.URLConnection#setDefaultUseCaches(boolean)
144  * @see java.net.URLConnection#setDoInput(boolean)
145  * @see java.net.URLConnection#setDoOutput(boolean)
146  * @see java.net.URLConnection#setIfModifiedSince(long)
147  * @see java.net.URLConnection#setRequestProperty(java.lang.String, java.lang.String)
148  * @see java.net.URLConnection#setUseCaches(boolean)
149  * @since JDK1.0
150  */

151 public abstract class URLConnection {
152
153    /**
154      * The URL represents the remote object on the World Wide Web to
155      * which this connection is opened.
156      * <p>
157      * The value of this field can be accessed by the
158      * <code>getURL</code> method.
159      * <p>
160      * The default value of this variable is the value of the URL
161      * argument in the <code>URLConnection</code> constructor.
162      *
163      * @see java.net.URLConnection#getURL()
164      * @see java.net.URLConnection#url
165      */

166     protected URL JavaDoc url;
167
168    /**
169      * This variable is set by the <code>setDoInput</code> method. Its
170      * value is returned by the <code>getDoInput</code> method.
171      * <p>
172      * A URL connection can be used for input and/or output. Setting the
173      * <code>doInput</code> flag to <code>true</code> indicates that
174      * the application intends to read data from the URL connection.
175      * <p>
176      * The default value of this field is <code>true</code>.
177      *
178      * @see java.net.URLConnection#getDoInput()
179      * @see java.net.URLConnection#setDoInput(boolean)
180      */

181     protected boolean doInput = true;
182
183    /**
184      * This variable is set by the <code>setDoOutput</code> method. Its
185      * value is returned by the <code>getDoOutput</code> method.
186      * <p>
187      * A URL connection can be used for input and/or output. Setting the
188      * <code>doOutput</code> flag to <code>true</code> indicates
189      * that the application intends to write data to the URL connection.
190      * <p>
191      * The default value of this field is <code>false</code>.
192      *
193      * @see java.net.URLConnection#getDoOutput()
194      * @see java.net.URLConnection#setDoOutput(boolean)
195      */

196     protected boolean doOutput = false;
197
198     private static boolean defaultAllowUserInteraction = false;
199
200    /**
201      * If <code>true</code>, this <code>URL</code> is being examined in
202      * a context in which it makes sense to allow user interactions such
203      * as popping up an authentication dialog. If <code>false</code>,
204      * then no user interaction is allowed.
205      * <p>
206      * The value of this field can be set by the
207      * <code>setAllowUserInteraction</code> method.
208      * Its value is returned by the
209      * <code>getAllowUserInteraction</code> method.
210      * Its default value is the value of the argument in the last invocation
211      * of the <code>setDefaultAllowUserInteraction</code> method.
212      *
213      * @see java.net.URLConnection#getAllowUserInteraction()
214      * @see java.net.URLConnection#setAllowUserInteraction(boolean)
215      * @see java.net.URLConnection#setDefaultAllowUserInteraction(boolean)
216      */

217     protected boolean allowUserInteraction = defaultAllowUserInteraction;
218
219     private static boolean defaultUseCaches = true;
220
221    /**
222      * If <code>true</code>, the protocol is allowed to use caching
223      * whenever it can. If <code>false</code>, the protocol must always
224      * try to get a fresh copy of the object.
225      * <p>
226      * This field is set by the <code>setUseCaches</code> method. Its
227      * value is returned by the <code>getUseCaches</code> method.
228      * <p>
229      * Its default value is the value given in the last invocation of the
230      * <code>setDefaultUseCaches</code> method.
231      *
232      * @see java.net.URLConnection#setUseCaches(boolean)
233      * @see java.net.URLConnection#getUseCaches()
234      * @see java.net.URLConnection#setDefaultUseCaches(boolean)
235      */

236     protected boolean useCaches = defaultUseCaches;
237
238    /**
239      * Some protocols support skipping the fetching of the object unless
240      * the object has been modified more recently than a certain time.
241      * <p>
242      * A nonzero value gives a time as the number of milliseconds since
243      * January 1, 1970, GMT. The object is fetched only if it has been
244      * modified more recently than that time.
245      * <p>
246      * This variable is set by the <code>setIfModifiedSince</code>
247      * method. Its value is returned by the
248      * <code>getIfModifiedSince</code> method.
249      * <p>
250      * The default value of this field is <code>0</code>, indicating
251      * that the fetching must always occur.
252      *
253      * @see java.net.URLConnection#getIfModifiedSince()
254      * @see java.net.URLConnection#setIfModifiedSince(long)
255      */

256     protected long ifModifiedSince = 0;
257
258    /**
259      * If <code>false</code>, this connection object has not created a
260      * communications link to the specified URL. If <code>true</code>,
261      * the communications link has been established.
262      */

263     protected boolean connected = false;
264
265     /**
266      * @since 1.5
267      */

268     private int connectTimeout;
269     private int readTimeout;
270
271    /**
272     * @since JDK1.1
273     */

274     private static FileNameMap JavaDoc fileNameMap;
275
276     /**
277      * @since 1.2.2
278      */

279     private static boolean fileNameMapLoaded = false;
280
281     /**
282      * Loads filename map (a mimetable) from a data file. It will
283      * first try to load the user-specific table, defined
284      * by &quot;content.types.user.table&quot; property. If that fails,
285      * it tries to load the default built-in table at
286      * lib/content-types.properties under java home.
287      *
288      * @return the FileNameMap
289      * @since 1.2
290      * @see #setFileNameMap(java.net.FileNameMap)
291      */

292     public static synchronized FileNameMap JavaDoc getFileNameMap() {
293     if ((fileNameMap == null) && !fileNameMapLoaded) {
294         fileNameMap = sun.net.www.MimeTable.loadTable();
295         fileNameMapLoaded = true;
296     }
297
298     return new FileNameMap JavaDoc() {
299         private FileNameMap JavaDoc map = fileNameMap;
300         public String JavaDoc getContentTypeFor(String JavaDoc fileName) {
301         return map.getContentTypeFor(fileName);
302         }
303     };
304     }
305
306     /**
307      * Sets the FileNameMap.
308      * <p>
309      * If there is a security manager, this method first calls
310      * the security manager's <code>checkSetFactory</code> method
311      * to ensure the operation is allowed.
312      * This could result in a SecurityException.
313      *
314      * @param map the FileNameMap to be set
315      * @exception SecurityException if a security manager exists and its
316      * <code>checkSetFactory</code> method doesn't allow the operation.
317      * @see SecurityManager#checkSetFactory
318      * @see #getFileNameMap()
319      * @since 1.2
320      */

321     public static void setFileNameMap(FileNameMap JavaDoc map) {
322     SecurityManager JavaDoc sm = System.getSecurityManager();
323     if (sm != null) sm.checkSetFactory();
324     fileNameMap = map;
325     }
326
327     /**
328      * Opens a communications link to the resource referenced by this
329      * URL, if such a connection has not already been established.
330      * <p>
331      * If the <code>connect</code> method is called when the connection
332      * has already been opened (indicated by the <code>connected</code>
333      * field having the value <code>true</code>), the call is ignored.
334      * <p>
335      * URLConnection objects go through two phases: first they are
336      * created, then they are connected. After being created, and
337      * before being connected, various options can be specified
338      * (e.g., doInput and UseCaches). After connecting, it is an
339      * error to try to set them. Operations that depend on being
340      * connected, like getContentLength, will implicitly perform the
341      * connection, if necessary.
342      *
343      * @throws SocketTimeoutException if the timeout expires before
344      * the connection can be established
345      * @exception IOException if an I/O error occurs while opening the
346      * connection.
347      * @see java.net.URLConnection#connected
348      * @see #getConnectTimeout()
349      * @see #setConnectTimeout(int)
350      */

351     abstract public void connect() throws IOException JavaDoc;
352
353     /**
354      * Sets a specified timeout value, in milliseconds, to be used
355      * when opening a communications link to the resource referenced
356      * by this URLConnection. If the timeout expires before the
357      * connection can be established, a
358      * java.net.SocketTimeoutException is raised. A timeout of zero is
359      * interpreted as an infinite timeout.
360
361      * <p> Some non-standard implmentation of this method may ignore
362      * the specified timeout. To see the connect timeout set, please
363      * call getConnectTimeout().
364      *
365      * @param timeout an <code>int</code> that specifies the connect
366      * timeout value in milliseconds
367      * @throws IllegalArgumentException if the timeout parameter is negative
368      *
369      * @see #getConnectTimeout()
370      * @see #connect()
371      * @since 1.5
372      */

373     public void setConnectTimeout(int timeout) {
374     if (timeout < 0) {
375         throw new IllegalArgumentException JavaDoc("timeout can not be negative");
376     }
377     connectTimeout = timeout;
378     }
379
380     /**
381      * Returns setting for connect timeout.
382      * <p>
383      * 0 return implies that the option is disabled
384      * (i.e., timeout of infinity).
385      *
386      * @return an <code>int</code> that indicates the connect timeout
387      * value in milliseconds
388      * @see #setConnectTimeout(int)
389      * @see #connect()
390      * @since 1.5
391      */

392     public int getConnectTimeout() {
393     return connectTimeout;
394     }
395
396     /**
397      * Sets the read timeout to a specified timeout, in
398      * milliseconds. A non-zero value specifies the timeout when
399      * reading from Input stream when a connection is established to a
400      * resource. If the timeout expires before there is data available
401      * for read, a java.net.SocketTimeoutException is raised. A
402      * timeout of zero is interpreted as an infinite timeout.
403      *
404      *<p> Some non-standard implementation of this method ignores the
405      * specified timeout. To see the read timeout set, please call
406      * getReadTimeout().
407      *
408      * @param timeout an <code>int</code> that specifies the timeout
409      * value to be used in milliseconds
410      * @throws IllegalArgumentException if the timeout parameter is negative
411      *
412      * @see #getReadTimeout()
413      * @see InputStream#read()
414      * @since 1.5
415      */

416     public void setReadTimeout(int timeout) {
417     if (timeout < 0) {
418         throw new IllegalArgumentException JavaDoc("timeout can not be negative");
419     }
420     readTimeout = timeout;
421     }
422
423     /**
424      * Returns setting for read timeout. 0 return implies that the
425      * option is disabled (i.e., timeout of infinity).
426      *
427      * @return an <code>int</code> that indicates the read timeout
428      * value in milliseconds
429      *
430      * @see #setReadTimeout(int)
431      * @see InputStream#read()
432      * @since 1.5
433      */

434     public int getReadTimeout() {
435     return readTimeout;
436     }
437
438     /**
439      * Constructs a URL connection to the specified URL. A connection to
440      * the object referenced by the URL is not created.
441      *
442      * @param url the specified URL.
443      */

444     protected URLConnection(URL JavaDoc url) {
445     this.url = url;
446     }
447
448     /**
449      * Returns the value of this <code>URLConnection</code>'s <code>URL</code>
450      * field.
451      *
452      * @return the value of this <code>URLConnection</code>'s <code>URL</code>
453      * field.
454      * @see java.net.URLConnection#url
455      */

456     public URL JavaDoc getURL() {
457     return url;
458     }
459
460     /**
461      * Returns the value of the <code>content-length</code> header field.
462      *
463      * @return the content length of the resource that this connection's URL
464      * references, or <code>-1</code> if the content length is
465      * not known.
466      */

467     public int getContentLength() {
468     return getHeaderFieldInt("content-length", -1);
469     }
470
471     /**
472      * Returns the value of the <code>content-type</code> header field.
473      *
474      * @return the content type of the resource that the URL references,
475      * or <code>null</code> if not known.
476      * @see java.net.URLConnection#getHeaderField(java.lang.String)
477      */

478     public String JavaDoc getContentType() {
479     return getHeaderField("content-type");
480     }
481
482     /**
483      * Returns the value of the <code>content-encoding</code> header field.
484      *
485      * @return the content encoding of the resource that the URL references,
486      * or <code>null</code> if not known.
487      * @see java.net.URLConnection#getHeaderField(java.lang.String)
488      */

489     public String JavaDoc getContentEncoding() {
490     return getHeaderField("content-encoding");
491     }
492
493     /**
494      * Returns the value of the <code>expires</code> header field.
495      *
496      * @return the expiration date of the resource that this URL references,
497      * or 0 if not known. The value is the number of milliseconds since
498      * January 1, 1970 GMT.
499      * @see java.net.URLConnection#getHeaderField(java.lang.String)
500      */

501     public long getExpiration() {
502     return getHeaderFieldDate("expires", 0);
503     }
504
505     /**
506      * Returns the value of the <code>date</code> header field.
507      *
508      * @return the sending date of the resource that the URL references,
509      * or <code>0</code> if not known. The value returned is the
510      * number of milliseconds since January 1, 1970 GMT.
511      * @see java.net.URLConnection#getHeaderField(java.lang.String)
512      */

513     public long getDate() {
514     return getHeaderFieldDate("date", 0);
515     }
516
517     /**
518      * Returns the value of the <code>last-modified</code> header field.
519      * The result is the number of milliseconds since January 1, 1970 GMT.
520      *
521      * @return the date the resource referenced by this
522      * <code>URLConnection</code> was last modified, or 0 if not known.
523      * @see java.net.URLConnection#getHeaderField(java.lang.String)
524      */

525     public long getLastModified() {
526     return getHeaderFieldDate("last-modified", 0);
527     }
528
529     /**
530      * Returns the value of the named header field.
531      * <p>
532      * If called on a connection that sets the same header multiple times
533      * with possibly different values, only the last value is returned.
534      *
535      *
536      * @param name the name of a header field.
537      * @return the value of the named header field, or <code>null</code>
538      * if there is no such field in the header.
539      */

540     public String JavaDoc getHeaderField(String JavaDoc name) {
541     return null;
542     }
543
544     /**
545      * Returns an unmodifiable Map of the header fields.
546      * The Map keys are Strings that represent the
547      * response-header field names. Each Map value is an
548      * unmodifiable List of Strings that represents
549      * the corresponding field values.
550      *
551      * @return a Map of header fields
552      * @since 1.4
553      */

554     public Map JavaDoc<String JavaDoc,List JavaDoc<String JavaDoc>> getHeaderFields() {
555         return Collections.EMPTY_MAP;
556     }
557
558     /**
559      * Returns the value of the named field parsed as a number.
560      * <p>
561      * This form of <code>getHeaderField</code> exists because some
562      * connection types (e.g., <code>http-ng</code>) have pre-parsed
563      * headers. Classes for that connection type can override this method
564      * and short-circuit the parsing.
565      *
566      * @param name the name of the header field.
567      * @param Default the default value.
568      * @return the value of the named field, parsed as an integer. The
569      * <code>Default</code> value is returned if the field is
570      * missing or malformed.
571      */

572     public int getHeaderFieldInt(String JavaDoc name, int Default) {
573     String JavaDoc value = getHeaderField(name);
574     try {
575         return Integer.parseInt(value);
576     } catch (Exception JavaDoc e) { }
577     return Default;
578     }
579
580     /**
581      * Returns the value of the named field parsed as date.
582      * The result is the number of milliseconds since January 1, 1970 GMT
583      * represented by the named field.
584      * <p>
585      * This form of <code>getHeaderField</code> exists because some
586      * connection types (e.g., <code>http-ng</code>) have pre-parsed
587      * headers. Classes for that connection type can override this method
588      * and short-circuit the parsing.
589      *
590      * @param name the name of the header field.
591      * @param Default a default value.
592      * @return the value of the field, parsed as a date. The value of the
593      * <code>Default</code> argument is returned if the field is
594      * missing or malformed.
595      */

596     public long getHeaderFieldDate(String JavaDoc name, long Default) {
597     String JavaDoc value = getHeaderField(name);
598     try {
599         return Date.parse(value);
600     } catch (Exception JavaDoc e) { }
601     return Default;
602     }
603
604     /**
605      * Returns the key for the <code>n</code><sup>th</sup> header field.
606      * It returns <code>null</code> if there are fewer than <code>n+1</code> fields.
607      *
608      * @param n an index, where n>=0
609      * @return the key for the <code>n</code><sup>th</sup> header field,
610      * or <code>null</code> if there are fewer than <code>n+1</code>
611      * fields.
612      */

613     public String JavaDoc getHeaderFieldKey(int n) {
614     return null;
615     }
616
617     /**
618      * Returns the value for the <code>n</code><sup>th</sup> header field.
619      * It returns <code>null</code> if there are fewer than
620      * <code>n+1</code>fields.
621      * <p>
622      * This method can be used in conjunction with the
623      * {@link #getHeaderFieldKey(int) getHeaderFieldKey} method to iterate through all
624      * the headers in the message.
625      *
626      * @param n an index, where n>=0
627      * @return the value of the <code>n</code><sup>th</sup> header field
628      * or <code>null</code> if there are fewer than <code>n+1</code> fields
629      * @see java.net.URLConnection#getHeaderFieldKey(int)
630      */

631     public String JavaDoc getHeaderField(int n) {
632     return null;
633     }
634
635     /**
636      * Retrieves the contents of this URL connection.
637      * <p>
638      * This method first determines the content type of the object by
639      * calling the <code>getContentType</code> method. If this is
640      * the first time that the application has seen that specific content
641      * type, a content handler for that content type is created:
642      * <ol>
643      * <li>If the application has set up a content handler factory instance
644      * using the <code>setContentHandlerFactory</code> method, the
645      * <code>createContentHandler</code> method of that instance is called
646      * with the content type as an argument; the result is a content
647      * handler for that content type.
648      * <li>If no content handler factory has yet been set up, or if the
649      * factory's <code>createContentHandler</code> method returns
650      * <code>null</code>, then the application loads the class named:
651      * <blockquote><pre>
652      * sun.net.www.content.&lt;<i>contentType</i>&gt;
653      * </pre></blockquote>
654      * where &lt;<i>contentType</i>&gt; is formed by taking the
655      * content-type string, replacing all slash characters with a
656      * <code>period</code> ('.'), and all other non-alphanumeric characters
657      * with the underscore character '<code>_</code>'. The alphanumeric
658      * characters are specifically the 26 uppercase ASCII letters
659      * '<code>A</code>' through '<code>Z</code>', the 26 lowercase ASCII
660      * letters '<code>a</code>' through '<code>z</code>', and the 10 ASCII
661      * digits '<code>0</code>' through '<code>9</code>'. If the specified
662      * class does not exist, or is not a subclass of
663      * <code>ContentHandler</code>, then an
664      * <code>UnknownServiceException</code> is thrown.
665      * </ol>
666      *
667      * @return the object fetched. The <code>instanceof</code> operator
668      * should be used to determine the specific kind of object
669      * returned.
670      * @exception IOException if an I/O error occurs while
671      * getting the content.
672      * @exception UnknownServiceException if the protocol does not support
673      * the content type.
674      * @see java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
675      * @see java.net.URLConnection#getContentType()
676      * @see java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
677      */

678     public Object JavaDoc getContent() throws IOException JavaDoc {
679         // Must call getInputStream before GetHeaderField gets called
680
// so that FileNotFoundException has a chance to be thrown up
681
// from here without being caught.
682
getInputStream();
683     return getContentHandler().getContent(this);
684     }
685
686     /**
687      * Retrieves the contents of this URL connection.
688      *
689      * @param classes the <code>Class</code> array
690      * indicating the requested types
691      * @return the object fetched that is the first match of the type
692      * specified in the classes array. null if none of
693      * the requested types are supported.
694      * The <code>instanceof</code> operator should be used to
695      * determine the specific kind of object returned.
696      * @exception IOException if an I/O error occurs while
697      * getting the content.
698      * @exception UnknownServiceException if the protocol does not support
699      * the content type.
700      * @see java.net.URLConnection#getContent()
701      * @see java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
702      * @see java.net.URLConnection#getContent(java.lang.Class[])
703      * @see java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
704      */

705     public Object JavaDoc getContent(Class JavaDoc[] classes) throws IOException JavaDoc {
706         // Must call getInputStream before GetHeaderField gets called
707
// so that FileNotFoundException has a chance to be thrown up
708
// from here without being caught.
709
getInputStream();
710     return getContentHandler().getContent(this, classes);
711     }
712
713     /**
714      * Returns a permission object representing the permission
715      * necessary to make the connection represented by this
716      * object. This method returns null if no permission is
717      * required to make the connection. By default, this method
718      * returns <code>java.security.AllPermission</code>. Subclasses
719      * should override this method and return the permission
720      * that best represents the permission required to make a
721      * a connection to the URL. For example, a <code>URLConnection</code>
722      * representing a <code>file:</code> URL would return a
723      * <code>java.io.FilePermission</code> object.
724      *
725      * <p>The permission returned may dependent upon the state of the
726      * connection. For example, the permission before connecting may be
727      * different from that after connecting. For example, an HTTP
728      * sever, say foo.com, may redirect the connection to a different
729      * host, say bar.com. Before connecting the permission returned by
730      * the connection will represent the permission needed to connect
731      * to foo.com, while the permission returned after connecting will
732      * be to bar.com.
733      *
734      * <p>Permissions are generally used for two purposes: to protect
735      * caches of objects obtained through URLConnections, and to check
736      * the right of a recipient to learn about a particular URL. In
737      * the first case, the permission should be obtained
738      * <em>after</em> the object has been obtained. For example, in an
739      * HTTP connection, this will represent the permission to connect
740      * to the host from which the data was ultimately fetched. In the
741      * second case, the permission should be obtained and tested
742      * <em>before</em> connecting.
743      *
744      * @return the permission object representing the permission
745      * necessary to make the connection represented by this
746      * URLConnection.
747      *
748      * @exception IOException if the computation of the permission
749      * requires network or file I/O and an exception occurs while
750      * computing it.
751      */

752     public Permission JavaDoc getPermission() throws IOException JavaDoc {
753     return SecurityConstants.ALL_PERMISSION;
754     }
755
756     /**
757      * Returns an input stream that reads from this open connection.
758      *
759      * A SocketTimeoutException can be thrown when reading from the
760      * returned input stream if the read timeout expires before data
761      * is available for read.
762      *
763      * @return an input stream that reads from this open connection.
764      * @exception IOException if an I/O error occurs while
765      * creating the input stream.
766      * @exception UnknownServiceException if the protocol does not support
767      * input.
768      * @see #setReadTimeout(int)
769      * @see #getReadTimeout()
770      */

771     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
772     throw new UnknownServiceException JavaDoc("protocol doesn't support input");
773     }
774
775     /**
776      * Returns an output stream that writes to this connection.
777      *
778      * @return an output stream that writes to this connection.
779      * @exception IOException if an I/O error occurs while
780      * creating the output stream.
781      * @exception UnknownServiceException if the protocol does not support
782      * output.
783      */

784     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
785     throw new UnknownServiceException JavaDoc("protocol doesn't support output");
786     }
787
788     /**
789      * Returns a <code>String</code> representation of this URL connection.
790      *
791      * @return a string representation of this <code>URLConnection</code>.
792      */

793     public String JavaDoc toString() {
794     return this.getClass().getName() + ":" + url;
795     }
796
797     /**
798      * Sets the value of the <code>doInput</code> field for this
799      * <code>URLConnection</code> to the specified value.
800      * <p>
801      * A URL connection can be used for input and/or output. Set the DoInput
802      * flag to true if you intend to use the URL connection for input,
803      * false if not. The default is true.
804      *
805      * @param doinput the new value.
806      * @throws IllegalStateException if already connected
807      * @see java.net.URLConnection#doInput
808      * @see #getDoInput()
809      */

810     public void setDoInput(boolean doinput) {
811     if (connected)
812         throw new IllegalStateException JavaDoc("Already connected");
813     doInput = doinput;
814     }
815
816     /**
817      * Returns the value of this <code>URLConnection</code>'s
818      * <code>doInput</code> flag.
819      *
820      * @return the value of this <code>URLConnection</code>'s
821      * <code>doInput</code> flag.
822      * @see #setDoInput(boolean)
823      */

824     public boolean getDoInput() {
825     return doInput;
826     }
827
828     /**
829      * Sets the value of the <code>doOutput</code> field for this
830      * <code>URLConnection</code> to the specified value.
831      * <p>
832      * A URL connection can be used for input and/or output. Set the DoOutput
833      * flag to true if you intend to use the URL connection for output,
834      * false if not. The default is false.
835      *
836      * @param dooutput the new value.
837      * @throws IllegalStateException if already connected
838      * @see #getDoOutput()
839      */

840     public void setDoOutput(boolean dooutput) {
841     if (connected)
842         throw new IllegalStateException JavaDoc("Already connected");
843     doOutput = dooutput;
844     }
845
846     /**
847      * Returns the value of this <code>URLConnection</code>'s
848      * <code>doOutput</code> flag.
849      *
850      * @return the value of this <code>URLConnection</code>'s
851      * <code>doOutput</code> flag.
852      * @see #setDoOutput(boolean)
853      */

854     public boolean getDoOutput() {
855     return doOutput;
856     }
857
858     /**
859      * Set the value of the <code>allowUserInteraction</code> field of
860      * this <code>URLConnection</code>.
861      *
862      * @param allowuserinteraction the new value.
863      * @throws IllegalStateException if already connected
864      * @see #getAllowUserInteraction()
865      */

866     public void setAllowUserInteraction(boolean allowuserinteraction) {
867     if (connected)
868         throw new IllegalStateException JavaDoc("Already connected");
869     allowUserInteraction = allowuserinteraction;
870     }
871
872     /**
873      * Returns the value of the <code>allowUserInteraction</code> field for
874      * this object.
875      *
876      * @return the value of the <code>allowUserInteraction</code> field for
877      * this object.
878      * @see #setAllowUserInteraction(boolean)
879      */

880     public boolean getAllowUserInteraction() {
881     return allowUserInteraction;
882     }
883
884     /**
885      * Sets the default value of the
886      * <code>allowUserInteraction</code> field for all future
887      * <code>URLConnection</code> objects to the specified value.
888      *
889      * @param defaultallowuserinteraction the new value.
890      * @see #getDefaultAllowUserInteraction()
891      */

892     public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) {
893     defaultAllowUserInteraction = defaultallowuserinteraction;
894     }
895
896     /**
897      * Returns the default value of the <code>allowUserInteraction</code>
898      * field.
899      * <p>
900      * Ths default is "sticky", being a part of the static state of all
901      * URLConnections. This flag applies to the next, and all following
902      * URLConnections that are created.
903      *
904      * @return the default value of the <code>allowUserInteraction</code>
905      * field.
906      * @see #setDefaultAllowUserInteraction(boolean)
907      */

908     public static boolean getDefaultAllowUserInteraction() {
909     return defaultAllowUserInteraction;
910     }
911
912     /**
913      * Sets the value of the <code>useCaches</code> field of this
914      * <code>URLConnection</code> to the specified value.
915      * <p>
916      * Some protocols do caching of documents. Occasionally, it is important
917      * to be able to "tunnel through" and ignore the caches (e.g., the
918      * "reload" button in a browser). If the UseCaches flag on a connection
919      * is true, the connection is allowed to use whatever caches it can.
920      * If false, caches are to be ignored.
921      * The default value comes from DefaultUseCaches, which defaults to
922      * true.
923      *
924      * @param usecaches a <code>boolean</code> indicating whether
925      * or not to allow caching
926      * @throws IllegalStateException if already connected
927      * @see #getUseCaches()
928      */

929     public void setUseCaches(boolean usecaches) {
930     if (connected)
931         throw new IllegalStateException JavaDoc("Already connected");
932     useCaches = usecaches;
933     }
934
935     /**
936      * Returns the value of this <code>URLConnection</code>'s
937      * <code>useCaches</code> field.
938      *
939      * @return the value of this <code>URLConnection</code>'s
940      * <code>useCaches</code> field.
941      * @see #setUseCaches(boolean)
942      */

943     public boolean getUseCaches() {
944     return useCaches;
945     }
946
947     /**
948      * Sets the value of the <code>ifModifiedSince</code> field of
949      * this <code>URLConnection</code> to the specified value.
950      *
951      * @param ifmodifiedsince the new value.
952      * @throws IllegalStateException if already connected
953      * @see #getIfModifiedSince()
954      */

955     public void setIfModifiedSince(long ifmodifiedsince) {
956     if (connected)
957         throw new IllegalStateException JavaDoc("Already connected");
958     ifModifiedSince = ifmodifiedsince;
959     }
960
961     /**
962      * Returns the value of this object's <code>ifModifiedSince</code> field.
963      *
964      * @return the value of this object's <code>ifModifiedSince</code> field.
965      * @see #setIfModifiedSince(long)
966      */

967     public long getIfModifiedSince() {
968     return ifModifiedSince;
969     }
970
971    /**
972      * Returns the default value of a <code>URLConnection</code>'s
973      * <code>useCaches</code> flag.
974      * <p>
975      * Ths default is "sticky", being a part of the static state of all
976      * URLConnections. This flag applies to the next, and all following
977      * URLConnections that are created.
978      *
979      * @return the default value of a <code>URLConnection</code>'s
980      * <code>useCaches</code> flag.
981      * @see #setDefaultUseCaches(boolean)
982      */

983     public boolean getDefaultUseCaches() {
984     return defaultUseCaches;
985     }
986
987    /**
988      * Sets the default value of the <code>useCaches</code> field to the
989      * specified value.
990      *
991      * @param defaultusecaches the new value.
992      * @see #getDefaultUseCaches()
993      */

994     public void setDefaultUseCaches(boolean defaultusecaches) {
995     defaultUseCaches = defaultusecaches;
996     }
997
998     /**
999      * Sets the general request property. If a property with the key already
1000     * exists, overwrite its value with the new value.
1001     *
1002     * <p> NOTE: HTTP requires all request properties which can
1003     * legally have multiple instances with the same key
1004     * to use a comma-seperated list syntax which enables multiple
1005     * properties to be appended into a single property.
1006     *
1007     * @param key the keyword by which the request is known
1008     * (e.g., "<code>accept</code>").
1009     * @param value the value associated with it.
1010     * @throws IllegalStateException if already connected
1011     * @throws NullPointerException if key is <CODE>null</CODE>
1012     * @see #getRequestProperty(java.lang.String)
1013     */

1014    public void setRequestProperty(String JavaDoc key, String JavaDoc value) {
1015    if (connected)
1016        throw new IllegalStateException JavaDoc("Already connected");
1017    if (key == null)
1018        throw new NullPointerException JavaDoc ("key is null");
1019    }
1020
1021    /**