OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [java/] [net/] [URLConnection.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* URLConnection.java -- Abstract superclass for reading from URL's
2
   Copyright (C) 1998, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package java.net;
40
 
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.io.OutputStream;
44
import java.security.AllPermission;
45
import java.security.Permission;
46
import java.text.ParsePosition;
47
import java.text.SimpleDateFormat;
48
import java.util.Collections;
49
import java.util.Date;
50
import java.util.Hashtable;
51
import java.util.Locale;
52
import java.util.Map;
53
import java.util.StringTokenizer;
54
import gnu.gcj.io.MimeTypes;
55
 
56
 
57
/**
58
 * Written using on-line Java Platform 1.2 API Specification, as well
59
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
60
 * Status:  One guessContentTypeFrom... methods not implemented.
61
 *    getContent method assumes content type from response; see comment there.
62
 */
63
/**
64
 * This class models a connection that retrieves the information pointed
65
 * to by a URL object.  This is typically a connection to a remote node
66
 * on the network, but could be a simple disk read.
67
 * <p>
68
 * A URLConnection object is normally created by calling the openConnection()
69
 * method of a URL object.  This method is somewhat misnamed because it does
70
 * not actually open the connection.  Instead, it return an unconnected
71
 * instance of this object.  The caller then has the opportunity to set
72
 * various connection options prior to calling the actual connect() method.
73
 * <p>
74
 * After the connection has been opened, there are a number of methods in
75
 * this class that access various attributes of the data, typically
76
 * represented by headers sent in advance of the actual data itself.
77
 * <p>
78
 * Also of note are the getInputStream and getContent() methods which allow
79
 * the caller to retrieve the actual data from the connection.  Note that
80
 * for some types of connections, writing is also allowed.  The setDoOutput()
81
 * method must be called prior to connecing in order to enable this, then
82
 * the getOutputStream method called after the connection in order to
83
 * obtain a stream to write the output to.
84
 * <p>
85
 * The getContent() method is of particular note.  This method returns an
86
 * Object that encapsulates the data returned.  There is no way do determine
87
 * the type of object that will be returned in advance.  This is determined
88
 * by the actual content handlers as described in the description of that
89
 * method.
90
 *
91
 * @author Aaron M. Renn (arenn@urbanophile.com)
92
 * @author Warren Levy (warrenl@cygnus.com)
93
 */
94
public abstract class URLConnection
95
{
96
  /**
97
   * This is an object that maps filenames to MIME types.  The interface
98
   * to do this is implemented by this class, so just create an empty
99
   * instance and store it here.
100
   */
101
  private static FileNameMap fileNameMap;
102
 
103
  /**
104
   * This is the ContentHandlerFactory set by the caller, if any
105
   */
106
  private static ContentHandlerFactory factory;
107
 
108
  /**
109
   * This is the default value that will be used to determine whether or
110
   * not user interaction should be allowed.
111
   */
112
  private static boolean defaultAllowUserInteraction;
113
 
114
  /**
115
   * This is the default flag indicating whether or not to use caches to
116
   * store the data returned from a server
117
   */
118
  private static boolean defaultUseCaches = true;
119
 
120
  private static ContentHandlerFactory defaultFactory
121
    = new gnu.java.net.DefaultContentHandlerFactory();
122
 
123
  /**
124
   * This variable determines whether or not interaction is allowed with
125
   * the user.  For example, to prompt for a username and password.
126
   */
127
  protected boolean allowUserInteraction;
128
 
129
  /**
130
   * Indicates whether or not a connection has been established to the
131
   * destination specified in the URL
132
   */
133
  protected boolean connected;
134
 
135
  /**
136
   * Indicates whether or not input can be read from this URL
137
   */
138
  protected boolean doInput = true;
139
 
140
  /**
141
   * Indicates whether or not output can be sent to this URL
142
   */
143
  protected boolean doOutput;
144
 
145
  /**
146
   * If this flag is set, the protocol is allowed to cache data whenever
147
   * it can (caching is not guaranteed). If it is not set, the protocol
148
   * must a get a fresh copy of the data.
149
   * <p>
150
   * This field is set by the setUseCaches method and returned by the
151
   * getUseCaches method.
152
   *
153
   * Its default value is that determined by the last invocation of
154
   * setDefaultUseCaches
155
   */
156
  protected boolean useCaches;
157
 
158
  /**
159
   * If this value is non-zero, then the connection will only attempt to
160
   * fetch the document pointed to by the URL if the document has been
161
   * modified more recently than the date set in this variable.  That date
162
   * should be specified as the number of seconds since 1/1/1970 GMT.
163
   */
164
  protected long ifModifiedSince;
165
 
166
  /**
167
   * This is the URL associated with this connection
168
   */
169
  protected URL url;
170
 
171
  private static Hashtable handlers = new Hashtable();
172
  private static SimpleDateFormat[] dateFormats;
173
  private static boolean dateformats_initialized;
174
 
175
  /* Cached ParsePosition, used when parsing dates. */
176
  private ParsePosition position;
177
 
178
  /**
179
   * Creates a URL connection to a given URL. A real connection is not made.
180
   * Use #connect to do this.
181
   *
182
   * @param url The Object to create the URL connection to
183
   *
184
   * @see URLConnection#connect()
185
   */
186
  protected URLConnection(URL url)
187
  {
188
    // Set up all our instance variables
189
    this.url = url;
190
    allowUserInteraction = defaultAllowUserInteraction;
191
    useCaches = defaultUseCaches;
192
  }
193
 
194
  /**
195
   * Establishes the actual connection to the URL associated with this
196
   * connection object
197
   *
198
   * @exception IOException if an error occurs
199
   */
200
  public abstract void connect() throws IOException;
201
 
202
  /**
203
   * Returns the URL object associated with this connection
204
   *
205
   * @return The URL for this connection.
206
   */
207
  public URL getURL()
208
  {
209
    return url;
210
  }
211
 
212
  /**
213
   * Returns the value of the content-length header field or -1 if the value
214
   * is not known or not present.
215
   *
216
   * @return The content-length field
217
   */
218
  public int getContentLength()
219
  {
220
    return getHeaderFieldInt("content-length", -1);
221
  }
222
 
223
  /**
224
   * Returns the the content-type of the data pointed to by the URL.  This
225
   * method first tries looking for a content-type header.  If that is not
226
   * present, it attempts to use the file name to determine the content's
227
   * MIME type.  If that is unsuccessful, the method returns null.  The caller
228
   * may then still attempt to determine the MIME type by a call to
229
   * guessContentTypeFromStream()
230
   *
231
   * @return The content MIME type
232
   */
233
  public String getContentType()
234
  {
235
    return getHeaderField("content-type");
236
  }
237
 
238
  /**
239
   * Returns the value of the content-encoding field or null if it is not
240
   * known or not present.
241
   *
242
   * @return The content-encoding field
243
   */
244
  public String getContentEncoding()
245
  {
246
    return getHeaderField("content-encoding");
247
  }
248
 
249
  /**
250
   * Returns the value of the expires header or 0 if not known or present.
251
   * If populated, the return value is number of seconds since midnight
252
   * on 1/1/1970 GMT.
253
   *
254
   * @return The expiration time.
255
   */
256
  public long getExpiration()
257
  {
258
    return getHeaderFieldDate("expires", 0L);
259
  }
260
 
261
  /**
262
   * Returns the date of the document pointed to by the URL as reported in
263
   * the date field of the header or 0 if the value is not present or not
264
   * known. If populated, the return value is number of seconds since
265
   * midnight on 1/1/1970 GMT.
266
   *
267
   * @return The document date
268
   */
269
  public long getDate()
270
  {
271
    return getHeaderFieldDate("date", 0L);
272
  }
273
 
274
  /**
275
   * Returns the value of the last-modified header field or 0 if not known known
276
   * or not present.  If populated, the return value is the number of seconds
277
   * since midnight on 1/1/1970.
278
   *
279
   * @return The last modified time
280
   */
281
  public long getLastModified()
282
  {
283
    return getHeaderFieldDate("last-modified", 0L);
284
  }
285
 
286
  /**
287
   * Return a String representing the header value at the specified index.
288
   * This allows the caller to walk the list of header fields.  The analogous
289
   * getHeaderFieldKey(int) method allows access to the corresponding key
290
   * for this header field
291
   *
292
   * @param index The index into the header field list to retrieve the value for
293
   *
294
   * @return The header value or null if index is past the end of the headers
295
   */
296
  public String getHeaderField(int index)
297
  {
298
    // Subclasses for specific protocols override this.
299
    return null;
300
  }
301
 
302
  /**
303
   * Returns a String representing the value of the header field having
304
   * the named key.  Returns null if the header field does not exist.
305
   *
306
   * @param name The key of the header field
307
   *
308
   * @return The value of the header field as a String
309
   */
310
  public String getHeaderField(String name)
311
  {
312
    // Subclasses for specific protocols override this.
313
    return null;
314
  }
315
 
316
  /**
317
   * Returns a map of all sent header fields
318
   *
319
   * @return all header fields
320
   *
321
   * @since 1.4
322
   */
323
  public Map getHeaderFields()
324
  {
325
    // Subclasses for specific protocols override this.
326
    return Collections.EMPTY_MAP;
327
  }
328
 
329
  /**
330
   * Returns the value of the named header field as an int.  If the field
331
   * is not present or cannot be parsed as an integer, the default value
332
   * will be returned.
333
   *
334
   * @param name The header field key to lookup
335
   * @param defaultValue The defaule value if the header field is not found
336
   * or can't be parsed.
337
   *
338
   * @return The value of the header field or the default value if the field
339
   * is missing or malformed
340
   */
341
  public int getHeaderFieldInt(String name, int defaultValue)
342
  {
343
    String value = getHeaderField(name);
344
 
345
    if (value == null)
346
      return defaultValue;
347
 
348
    try
349
      {
350
        return Integer.parseInt(value);
351
      }
352
    catch (NumberFormatException e)
353
      {
354
        return defaultValue;
355
      }
356
  }
357
 
358
  /**
359
   * Returns the value of the named header field as a date.  This date will
360
   * be the number of seconds since midnight 1/1/1970 GMT or the default
361
   * value if the field is not present or cannot be converted to a date.
362
   *
363
   * @param name The name of the header field
364
   * @param defaultValue The default date if the header field is not found
365
   * or can't be converted.
366
   *
367
   * @return Returns the date value of the header filed or the default value
368
   * if the field is missing or malformed
369
   */
370
  public long getHeaderFieldDate(String name, long defaultValue)
371
  {
372
    if (! dateformats_initialized)
373
      initializeDateFormats();
374
 
375
    if (position == null)
376
      position = new ParsePosition(0);
377
 
378
    long result = defaultValue;
379
    String str = getHeaderField(name);
380
 
381
    if (str != null)
382
      {
383
        for (int i = 0; i < dateFormats.length; i++)
384
          {
385
            SimpleDateFormat df = dateFormats[i];
386
            position.setIndex(0);
387
            position.setErrorIndex(0);
388
            Date date = df.parse(str, position);
389
            if (date != null)
390
              return date.getTime();
391
          }
392
      }
393
 
394
    return result;
395
  }
396
 
397
  /**
398
   * Returns a String representing the header key at the specified index.
399
   * This allows the caller to walk the list of header fields.  The analogous
400
   * getHeaderField(int) method allows access to the corresponding value for
401
   * this tag.
402
   *
403
   * @param index The index into the header field list to retrieve the key for.
404
   *
405
   * @return The header field key or null if index is past the end
406
   * of the headers.
407
   */
408
  public String getHeaderFieldKey(int index)
409
  {
410
    // Subclasses for specific protocols override this.
411
    return null;
412
  }
413
 
414
  /**
415
   * This method returns the content of the document pointed to by the
416
   * URL as an Object.  The type of object depends on the MIME type of
417
   * the object and particular content hander loaded.  Most text type
418
   * content handlers will return a subclass of
419
   * <code>InputStream</code>.  Images usually return a class that
420
   * implements <code>ImageProducer</code>.  There is not guarantee
421
   * what type of object will be returned, however.
422
   *
423
   * <p>This class first determines the MIME type of the content, then
424
   * creates a ContentHandler object to process the input.  If the
425
   * <code>ContentHandlerFactory</code> is set, then that object is
426
   * called to load a content handler, otherwise a class called
427
   * gnu.java.net.content.&lt;content_type&gt; is tried.  If this
428
   * handler does not exist, the method will simple return the
429
   * <code>InputStream</code> returned by
430
   * <code>getInputStream()</code>.  Note that the default
431
   * implementation of <code>getInputStream()</code> throws a
432
   * <code>UnknownServiceException</code> so subclasses are encouraged
433
   * to override this method.</p>
434
   *
435
   * @return the content
436
   *
437
   * @exception IOException If an error with the connection occurs.
438
   * @exception UnknownServiceException If the protocol does not support the
439
   * content type at all.
440
   */
441
  public Object getContent() throws IOException
442
  {
443
    if (!connected)
444
      connect();
445
 
446
    // FIXME: Doc indicates that other criteria should be applied as
447
    // heuristics to determine the true content type, e.g. see 
448
    // guessContentTypeFromName() and guessContentTypeFromStream methods
449
    // as well as FileNameMap class & fileNameMap field & get/set methods.
450
    String type = getContentType();
451
    ContentHandler ch = getContentHandler(type);
452
 
453
    if (ch != null)
454
      return ch.getContent(this);
455
 
456
    return getInputStream();
457
  }
458
 
459
  /**
460
   * Retrieves the content of this URLConnection
461
   *
462
   * @param classes The allowed classes for the content
463
   *
464
   * @return the content
465
   *
466
   * @exception IOException If an error occurs
467
   * @exception UnknownServiceException If the protocol does not support the
468
   * content type
469
   */
470
  public Object getContent(Class[] classes) throws IOException
471
  {
472
    // FIXME: implement this
473
    return getContent();
474
  }
475
 
476
  /**
477
   * This method returns a <code>Permission</code> object representing the
478
   * permissions required to access this URL.  This method returns
479
   * <code>java.security.AllPermission</code> by default.  Subclasses should
480
   * override it to return a more specific permission.  For example, an
481
   * HTTP URL should return an instance of <code>SocketPermission</code>
482
   * for the appropriate host and port.
483
   * <p>
484
   * Note that because of items such as HTTP redirects, the permission
485
   * object returned might be different before and after connecting.
486
   *
487
   * @return A Permission object
488
   *
489
   * @exception IOException If the computation of the permission requires
490
   * network or file I/O and an exception occurs while computing it
491
   */
492
  public Permission getPermission() throws IOException
493
  {
494
    // Subclasses may override this.
495
    return new AllPermission();
496
  }
497
 
498
  /**
499
   * Returns an InputStream for this connection.  As this default
500
   * implementation returns null, subclasses should override this method
501
   *
502
   * @return An InputStream for this connection
503
   *
504
   * @exception IOException If an error occurs
505
   * @exception UnknownServiceException If the protocol does not support input
506
   */
507
  public InputStream getInputStream() throws IOException
508
  {
509
    // Subclasses for specific protocols override this.
510
    throw new UnknownServiceException("Protocol " + url.getProtocol()
511
                                      + " does not support input.");
512
  }
513
 
514
  /**
515
   * Returns an OutputStream for this connection.  As this default
516
   * implementation returns null, subclasses should override this method
517
   *
518
   * @return An OutputStream for this connection
519
   *
520
   * @exception IOException If an error occurs
521
   * @exception UnknownServiceException If the protocol does not support output
522
   */
523
  public OutputStream getOutputStream() throws IOException
524
  {
525
    // Subclasses for specific protocols override this.
526
    throw new UnknownServiceException("Protocol " + url.getProtocol()
527
                                      + " does not support output.");
528
  }
529
 
530
  /**
531
   * The methods prints the value of this object as a String by calling the
532
   * toString() method of its associated URL.  Overrides Object.toString()
533
   *
534
   * @return A String representation of this object
535
   */
536
  public String toString()
537
  {
538
    return this.getClass().getName() + ":" + url.toString();
539
  }
540
 
541
  /**
542
   * Sets the value of a flag indicating whether or not input is going
543
   * to be done for this connection.  This default to true unless the
544
   * doOutput flag is set to false, in which case this defaults to false.
545
   *
546
   * @param input <code>true</code> if input is to be done,
547
   * <code>false</code> otherwise
548
   *
549
   * @exception IllegalStateException If already connected
550
   */
551
  public void setDoInput(boolean input)
552
  {
553
    if (connected)
554
      throw new IllegalStateException("Already connected");
555
 
556
    doInput = input;
557
  }
558
 
559
  /**
560
   * Returns the value of a flag indicating whether or not input is going
561
   * to be done for this connection.  This default to true unless the
562
   * doOutput flag is set to false, in which case this defaults to false.
563
   *
564
   * @return true if input is to be done, false otherwise
565
   */
566
  public boolean getDoInput()
567
  {
568
    return doInput;
569
  }
570
 
571
  /**
572
   * Sets a boolean flag indicating whether or not output will be done
573
   * on this connection.  The default value is false, so this method can
574
   * be used to override the default
575
   *
576
   * @param output ture if output is to be done, false otherwise
577
   *
578
   * @exception IllegalStateException If already connected
579
   */
580
  public void setDoOutput(boolean output)
581
  {
582
    if (connected)
583
      throw new IllegalStateException("Already connected");
584
 
585
    doOutput = output;
586
  }
587
 
588
  /**
589
   * Returns a boolean flag indicating whether or not output will be done
590
   * on this connection.  This defaults to false.
591
   *
592
   * @return true if output is to be done, false otherwise
593
   */
594
  public boolean getDoOutput()
595
  {
596
    return doOutput;
597
  }
598
 
599
  /**
600
   * Sets a boolean flag indicating whether or not user interaction is
601
   * allowed for this connection.  (For example, in order to prompt for
602
   * username and password info.
603
   *
604
   * @param allow true if user interaction should be allowed, false otherwise.
605
   *
606
   * @exception IllegalStateException If already connected
607
   */
608
  public void setAllowUserInteraction(boolean allow)
609
  {
610
    allowUserInteraction = allow;
611
  }
612
 
613
  /**
614
   * Returns a boolean flag indicating whether or not user interaction is
615
   * allowed for this connection.  (For example, in order to prompt for
616
   * username and password info.
617
   *
618
   * @return true if user interaction is allowed, false otherwise
619
   */
620
  public boolean getAllowUserInteraction()
621
  {
622
    return allowUserInteraction;
623
  }
624
 
625
  /**
626
   * Sets the default flag for whether or not interaction with a user
627
   * is allowed.  This will be used for all connections unless overridden
628
   *
629
   * @param allow true to allow user interaction, false otherwise
630
   */
631
  public static void setDefaultAllowUserInteraction(boolean allow)
632
  {
633
    defaultAllowUserInteraction = allow;
634
  }
635
 
636
  /**
637
   * Returns the default flag for whether or not interaction with a user
638
   * is allowed.  This will be used for all connections unless overridden
639
   *
640
   * @return true if user interaction is allowed, false otherwise
641
   */
642
  public static boolean getDefaultAllowUserInteraction()
643
  {
644
    return defaultAllowUserInteraction;
645
  }
646
 
647
  /**
648
   * Sets a boolean flag indicating whether or not caching will be used
649
   * (if possible) to store data downloaded via the connection.
650
   *
651
   * @param usecaches The new value
652
   *
653
   * @exception IllegalStateException If already connected
654
   */
655
  public void setUseCaches(boolean usecaches)
656
  {
657
    if (connected)
658
      throw new IllegalStateException("Already connected");
659
 
660
    useCaches = usecaches;
661
  }
662
 
663
  /**
664
   * Returns a boolean flag indicating whether or not caching will be used
665
   * (if possible) to store data downloaded via the connection.
666
   *
667
   * @return true if caching should be used if possible, false otherwise
668
   */
669
  public boolean getUseCaches()
670
  {
671
    return useCaches;
672
  }
673
 
674
  /**
675
   * Sets the ifModified since instance variable.  If this value is non
676
   * zero and the underlying protocol supports it, the actual document will
677
   * not be fetched unless it has been modified since this time.  The value
678
   * passed should  be 0 if this feature is to be disabled or the time expressed
679
   * as the number of seconds since midnight 1/1/1970 GMT otherwise.
680
   *
681
   * @param ifmodifiedsince The new value in milliseconds
682
   * since January 1, 1970 GMT
683
   *
684
   * @exception IllegalStateException If already connected
685
   */
686
  public void setIfModifiedSince(long ifmodifiedsince)
687
  {
688
    if (connected)
689
      throw new IllegalStateException("Already connected");
690
 
691
    ifModifiedSince = ifmodifiedsince;
692
  }
693
 
694
  /**
695
   * Returns the ifModified since instance variable.  If this value is non
696
   * zero and the underlying protocol supports it, the actual document will
697
   * not be fetched unless it has been modified since this time.  The value
698
   * returned will be 0 if this feature is disabled or the time expressed
699
   * as the number of seconds since midnight 1/1/1970 GMT otherwise
700
   *
701
   * @return The ifModifiedSince value
702
   */
703
  public long getIfModifiedSince()
704
  {
705
    return ifModifiedSince;
706
  }
707
 
708
  /**
709
   * Returns the default value used to determine whether or not caching
710
   * of documents will be done when possible.
711
   *
712
   * @return true if caches will be used, false otherwise
713
   */
714
  public boolean getDefaultUseCaches()
715
  {
716
    return defaultUseCaches;
717
  }
718
 
719
  /**
720
   * Sets the default value used to determine whether or not caching
721
   * of documents will be done when possible.
722
   *
723
   * @param use true to use caches if possible by default, false otherwise
724
   */
725
  public void setDefaultUseCaches(boolean use)
726
  {
727
    defaultUseCaches = use;
728
  }
729
 
730
  /**
731
   * Sets the value of the named request property
732
   *
733
   * @param key The name of the property
734
   * @param value The value of the property
735
   *
736
   * @exception IllegalStateException If already connected
737
   * @exception NullPointerException If key is null
738
   *
739
   * @see URLConnection#getRequestProperty(String key)
740
   * @see URLConnection#addRequestProperty(String key, String value)
741
   *
742
   * @since 1.4
743
   */
744
  public void setRequestProperty(String key, String value)
745
  {
746
    if (connected)
747
      throw new IllegalStateException("Already connected");
748
 
749
    if (key == null)
750
      throw new NullPointerException("key is null");
751
 
752
    // Do nothing unless overridden by subclasses that support setting
753
    // header fields in the request.
754
  }
755
 
756
  /**
757
   * Adds a new request property by a key/value pair.
758
   * This method does not overwrite existing properties with the same key.
759
   *
760
   * @param key Key of the property to add
761
   * @param value Value of the Property to add
762
   *
763
   * @exception IllegalStateException If already connected
764
   * @exception NullPointerException If key is null
765
   *
766
   * @see URLConnection#getRequestProperty(String key)
767
   * @see URLConnection#setRequestProperty(String key, String value)
768
   *
769
   * @since 1.4
770
   */
771
  public void addRequestProperty(String key, String value)
772
  {
773
    if (connected)
774
      throw new IllegalStateException("Already connected");
775
 
776
    if (key == null)
777
      throw new NullPointerException("key is null");
778
 
779
    // Do nothing unless overridden by subclasses that support adding
780
    // header fields in the request.
781
  }
782
 
783
  /**
784
   * Returns the value of the named request property.
785
   *
786
   * @param key The name of the property
787
   *
788
   * @return Value of the property
789
   *
790
   * @exception IllegalStateException If already connected
791
   *
792
   * @see URLConnection#setRequestProperty(String key, String value)
793
   * @see URLConnection#addRequestProperty(String key, String value)
794
   */
795
  public String getRequestProperty(String key)
796
  {
797
    if (connected)
798
      throw new IllegalStateException("Already connected");
799
 
800
    // Overridden by subclasses that support reading header fields from the
801
    // request.
802
    return null;
803
  }
804
 
805
  /**
806
   * Returns an unmodifiable Map containing the request properties.
807
   *
808
   * @return The map of properties
809
   *
810
   * @exception IllegalStateException If already connected
811
   *
812
   * @since 1.4
813
   */
814
  public Map getRequestProperties()
815
  {
816
    if (connected)
817
      throw new IllegalStateException("Already connected");
818
 
819
    // Overridden by subclasses that support reading header fields from the
820
    // request.
821
    return Collections.EMPTY_MAP;
822
  }
823
 
824
  /**
825
   * Sets the default value of a request property.  This will be used
826
   * for all connections unless the value of the property is manually
827
   * overridden.
828
   *
829
   * @param key The request property name the default is being set for
830
   * @param value The value to set the default to
831
   *
832
   * @deprecated 1.3 The method setRequestProperty should be used instead.
833
   * This method does nothing now.
834
   *
835
   * @see URLConnection#setRequestProperty(String key, String value)
836
   */
837
  public static void setDefaultRequestProperty(String key, String value)
838
  {
839
    // This method does nothing since JDK 1.3.
840
  }
841
 
842
  /**
843
   * Returns the default value of a request property.  This will be used
844
   * for all connections unless the value of the property is manually
845
   * overridden.
846
   *
847
   * @param key The request property to return the default value of
848
   *
849
   * @return The value of the default property or null if not available
850
   *
851
   * @deprecated 1.3 The method getRequestProperty should be used instead.
852
   * This method does nothing now.
853
   *
854
   * @see URLConnection#getRequestProperty(String key)
855
   */
856
  public static String getDefaultRequestProperty(String key)
857
  {
858
    // This method does nothing since JDK 1.3.
859
    return null;
860
  }
861
 
862
  /**
863
   * Sets the ContentHandlerFactory for an application.  This can be called
864
   * once and only once.  If it is called again, then an Error is thrown.
865
   * Unlike for other set factory methods, this one does not do a security
866
   * check prior to setting the factory.
867
   *
868
   * @param factory The ContentHandlerFactory for this application
869
   *
870
   * @exception Error If the factory has already been defined
871
   * @exception SecurityException If a security manager exists and its
872
   * checkSetFactory method doesn't allow the operation
873
   */
874
  public static synchronized void setContentHandlerFactory(ContentHandlerFactory factory)
875
  {
876
    if (URLConnection.factory != null)
877
      throw new Error("ContentHandlerFactory already set");
878
 
879
    // Throw an exception if an extant security mgr precludes
880
    // setting the factory.
881
    SecurityManager s = System.getSecurityManager();
882
    if (s != null)
883
      s.checkSetFactory();
884
 
885
    URLConnection.factory = factory;
886
  }
887
 
888
  /**
889
   * Returns the MIME type of a file based on the name of the file.  This
890
   * works by searching for the file's extension in a list of file extensions
891
   * and returning the MIME type associated with it.  If no type is found,
892
   * then a MIME type of "application/octet-stream" will be returned.
893
   *
894
   * @param filename The filename to determine the MIME type for
895
   *
896
   * @return The MIME type String
897
   *
898
   * @specnote public since JDK 1.4
899
   */
900
  public static String guessContentTypeFromName(String filename)
901
  {
902
    return getFileNameMap().getContentTypeFor(filename.toLowerCase());
903
  }
904
 
905
  /**
906
   * Returns the MIME type of a stream based on the first few characters
907
   * at the beginning of the stream.  This routine can be used to determine
908
   * the MIME type if a server is believed to be returning an incorrect
909
   * MIME type.  This method returns "application/octet-stream" if it
910
   * cannot determine the MIME type.
911
   * <p>
912
   * NOTE: Overriding MIME types sent from the server can be obnoxious
913
   * to user's.  See Internet Exploder 4 if you don't believe me.
914
   *
915
   * @param is The InputStream to determine the MIME type from
916
   *
917
   * @return The MIME type
918
   *
919
   * @exception IOException If an error occurs
920
   */
921
  public static String guessContentTypeFromStream(InputStream is)
922
    throws IOException
923
  {
924
    is.mark(1024);
925
    // FIXME: Implement this. Use system mimetype informations (like "file").
926
    is.reset();
927
    return "application/octet-stream";
928
  }
929
 
930
  /**
931
   * This method returns the <code>FileNameMap</code> object being used
932
   * to decode MIME types by file extension.
933
   *
934
   * @return The <code>FileNameMap</code>.
935
   *
936
   * @since 1.2
937
   */
938
  public static synchronized FileNameMap getFileNameMap()
939
  {
940
    // Delayed initialization.
941
    if (fileNameMap == null)
942
      fileNameMap = new MimeTypeMapper();
943
 
944
    return fileNameMap;
945
  }
946
 
947
  /**
948
   * This method sets the <code>FileNameMap</code> object being used
949
   * to decode MIME types by file extension.
950
   *
951
   * @param map The <code>FileNameMap</code>.
952
   *
953
   * @exception SecurityException If a security manager exists and its
954
   * checkSetFactory method doesn't allow the operation
955
   *
956
   * @since 1.2
957
   */
958
  public static synchronized void setFileNameMap(FileNameMap map)
959
  {
960
    // Throw an exception if an extant security manager precludes
961
    // setting the factory.
962
    SecurityManager s = System.getSecurityManager();
963
    if (s != null)
964
      s.checkSetFactory();
965
 
966
    fileNameMap = map;
967
  }
968
 
969
  private ContentHandler getContentHandler(String contentType)
970
  {
971
    // No content type so just handle it as the default.
972
    if (contentType == null || contentType.equals(""))
973
      return null;
974
 
975
    ContentHandler handler = null;
976
 
977
    // See if a handler has been cached for this content type.
978
    // For efficiency, if a content type has been searched for but not
979
    // found, it will be in the hash table but as the contentType String
980
    // instead of a ContentHandler.
981
    {
982
      Object cachedHandler;
983
      if ((cachedHandler = handlers.get(contentType)) != null)
984
        {
985
          if (cachedHandler instanceof ContentHandler)
986
            return (ContentHandler)cachedHandler;
987
          else
988
            return null;
989
        }
990
    }
991
 
992
    // If a non-default factory has been set, use it.
993
    if (factory != null)
994
      handler = factory.createContentHandler(contentType);
995
 
996
    // Now try default factory. Using this factory to instantiate built-in
997
    // content handlers is preferable  
998
    if (handler == null)
999
      handler = defaultFactory.createContentHandler(contentType);
1000
 
1001
    // User-set factory has not returned a handler. Use the default search 
1002
    // algorithm.
1003
    if (handler == null)
1004
      {
1005
        // Get the list of packages to check and append our default handler
1006
        // to it, along with the JDK specified default as a last resort.
1007
        // Except in very unusual environments the JDK specified one shouldn't
1008
        // ever be needed (or available).
1009
        String propVal = System.getProperty("java.content.handler.pkgs");
1010
        propVal = (propVal == null) ? "" : (propVal + "|");
1011
        propVal = propVal + "gnu.java.net.content|sun.net.www.content";
1012
 
1013
        // Replace the '/' character in the content type with '.' and
1014
        // all other non-alphabetic, non-numeric characters with '_'.
1015
        char[] cArray = contentType.toCharArray();
1016
        for (int i = 0; i < cArray.length; i++)
1017
          {
1018
            if (cArray[i] == '/')
1019
              cArray[i] = '.';
1020
            else if (! ((cArray[i] >= 'A' && cArray[i] <= 'Z') ||
1021
                        (cArray[i] >= 'a' && cArray[i] <= 'z') ||
1022
                        (cArray[i] >= '0' && cArray[i] <= '9')))
1023
              cArray[i] = '_';
1024
          }
1025
        String contentClass = new String(cArray);
1026
 
1027
        // See if a class of this content type exists in any of the packages.
1028
        StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
1029
        do
1030
          {
1031
            String facName = pkgPrefix.nextToken() + "." + contentClass;
1032
            try
1033
              {
1034
                handler =
1035
                  (ContentHandler) Class.forName(facName).newInstance();
1036
              }
1037
            catch (Exception e)
1038
              {
1039
                // Can't instantiate; handler still null, go on to next element.
1040
              }
1041
          } while ((handler == null ||
1042
                    ! (handler instanceof ContentHandler)) &&
1043
                   pkgPrefix.hasMoreTokens());
1044
      }
1045
 
1046
    // Update the hashtable with the new content handler.
1047
    if (handler instanceof ContentHandler)
1048
      {
1049
        handlers.put(contentType, handler);
1050
        return handler;
1051
      }
1052
 
1053
    // For efficiency on subsequent searches, put a dummy entry in the hash
1054
    // table for content types that don't have a non-default ContentHandler.
1055
    handlers.put(contentType, contentType);
1056
    return null;
1057
  }
1058
 
1059
  // We don't put these in a static initializer, because it creates problems
1060
  // with initializer co-dependency: SimpleDateFormat's constructors eventually 
1061
  // depend on URLConnection (via the java.text.*Symbols classes).
1062
  private static synchronized void initializeDateFormats()
1063
  {
1064
    if (dateformats_initialized)
1065
      return;
1066
 
1067
    Locale locale = new Locale("En", "Us", "Unix");
1068
    dateFormats = new SimpleDateFormat[3];
1069
    dateFormats[0] =
1070
      new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
1071
    dateFormats[1] =
1072
      new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
1073
    dateFormats[2] = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
1074
    dateformats_initialized = true;
1075
  }
1076
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.