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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [net/] [URL.java] - Blame information for rev 791

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* URL.java -- Uniform Resource Locator Class
2
   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
package java.net;
40
 
41
import gnu.classpath.SystemProperties;
42
import gnu.java.net.URLParseError;
43
 
44
import java.io.IOException;
45
import java.io.InputStream;
46
import java.io.ObjectInputStream;
47
import java.io.ObjectOutputStream;
48
import java.io.Serializable;
49
import java.security.AccessController;
50
import java.security.PrivilegedAction;
51
import java.util.HashMap;
52
import java.util.StringTokenizer;
53
 
54
 
55
/*
56
 * Written using on-line Java Platform 1.2 API Specification, as well
57
 * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
58
 * Status:  Believed complete and correct.
59
 */
60
 
61
/**
62
  * This final class represents an Internet Uniform Resource Locator (URL).
63
  * For details on the syntax of URL's and what they can be used for,
64
  * refer to RFC 1738, available from <a
65
  * href="http://ds.internic.net/rfcs/rfc1738.txt">
66
  * http://ds.internic.net/rfcs/rfc1738.txt</a>
67
  * <p>
68
  * There are a great many protocols supported by URL's such as "http",
69
  * "ftp", and "file".  This object can handle any arbitrary URL for which
70
  * a URLStreamHandler object can be written.  Default protocol handlers
71
  * are provided for the "http" and "ftp" protocols.  Additional protocols
72
  * handler implementations may be provided in the future.  In any case,
73
  * an application or applet can install its own protocol handlers that
74
  * can be "chained" with other protocol hanlders in the system to extend
75
  * the base functionality provided with this class. (Note, however, that
76
  * unsigned applets cannot access properties by default or install their
77
  * own protocol handlers).
78
  * <p>
79
  * This chaining is done via the system property java.protocol.handler.pkgs
80
  * If this property is set, it is assumed to be a "|" separated list of
81
  * package names in which to attempt locating protocol handlers.  The
82
  * protocol handler is searched for by appending the string
83
  * ".&lt;protocol&gt;.Handler" to each packed in the list until a hander is
84
  * found. If a protocol handler is not found in this list of packages, or if
85
  * the property does not exist, then the default protocol handler of
86
  * "gnu.java.net.&lt;protocol&gt;.Handler" is tried.  If this is
87
  * unsuccessful, a MalformedURLException is thrown.
88
  * <p>
89
  * All of the constructor methods of URL attempt to load a protocol
90
  * handler and so any needed protocol handlers must be installed when
91
  * the URL is constructed.
92
  * <p>
93
  * Here is an example of how URL searches for protocol handlers.  Assume
94
  * the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the
95
  * URL is "news://comp.lang.java.programmer".  URL would looking the
96
  * following places for protocol handlers:
97
  * <p><pre>
98
  * com.foo.news.Handler
99
  * com.bar.news.Handler
100
  * gnu.java.net.news.Handler
101
  * </pre><p>
102
  * If the protocol handler is not found in any of those locations, a
103
  * MalformedURLException would be thrown.
104
  * <p>
105
  * Please note that a protocol handler must be a subclass of
106
  * URLStreamHandler.
107
  * <p>
108
  * Normally, this class caches protocol handlers.  Once it finds a handler
109
  * for a particular protocol, it never tries to look up a new handler
110
  * again.  However, if the system property
111
  * gnu.java.net.nocache_protocol_handlers is set, then this
112
  * caching behavior is disabled.  This property is specific to this
113
  * implementation.  Sun's JDK may or may not do protocol caching, but it
114
  * almost certainly does not examine this property.
115
  * <p>
116
  * Please also note that an application can install its own factory for
117
  * loading protocol handlers (see setURLStreamHandlerFactory).  If this is
118
  * done, then the above information is superseded and the behavior of this
119
  * class in loading protocol handlers is dependent on that factory.
120
  *
121
  * @author Aaron M. Renn (arenn@urbanophile.com)
122
  * @author Warren Levy (warrenl@cygnus.com)
123
  *
124
  * @see URLStreamHandler
125
  */
126
public final class URL implements Serializable
127
{
128
  private static final String DEFAULT_SEARCH_PATH =
129
    "gnu.java.net.protocol|gnu.inet";
130
 
131
  // Cached System ClassLoader
132
  private static ClassLoader systemClassLoader;
133
 
134
  /**
135
   * The name of the protocol for this URL.
136
   * The protocol is always stored in lower case.
137
   */
138
  private String protocol;
139
 
140
  /**
141
   * The "authority" portion of the URL.
142
   */
143
  private String authority;
144
 
145
  /**
146
   * The hostname or IP address of this protocol.
147
   * This includes a possible user. For example <code>joe@some.host.net</code>.
148
   */
149
  private String host;
150
 
151
  /**
152
   * The user information necessary to establish the connection.
153
   */
154
  private String userInfo;
155
 
156
  /**
157
   * The port number of this protocol or -1 if the port number used is
158
   * the default for this protocol.
159
   */
160
  private int port = -1; // Initialize for constructor using context.
161
 
162
  /**
163
   * The "file" portion of the URL. It is defined as <code>path[?query]</code>.
164
   */
165
  private String file;
166
 
167
  /**
168
   * The anchor portion of the URL.
169
   */
170
  private String ref;
171
 
172
  /**
173
   * This is the hashCode for this URL
174
   */
175
  private int hashCode;
176
 
177
  /**
178
   * The protocol handler in use for this URL
179
   */
180
  transient URLStreamHandler ph;
181
 
182
  /**
183
   * If an application installs its own protocol handler factory, this is
184
   * where we keep track of it.
185
   */
186
  private static URLStreamHandlerFactory factory;
187
  private static final long serialVersionUID = -7627629688361524110L;
188
 
189
  /**
190
   * This a table where we cache protocol handlers to avoid the overhead
191
   * of looking them up each time.
192
   */
193
  private static HashMap<String, URLStreamHandler> ph_cache
194
    = new HashMap<String, URLStreamHandler>();
195
 
196
  /**
197
   * Whether or not to cache protocol handlers.
198
   */
199
  private static boolean cache_handlers;
200
 
201
  static
202
    {
203
      String s = SystemProperties.getProperty("gnu.java.net.nocache_protocol_handlers");
204
 
205
      if (s == null)
206
        cache_handlers = true;
207
      else
208
        cache_handlers = false;
209
    }
210
 
211
  /**
212
   * Constructs a URL and loads a protocol handler for the values passed as
213
   * arguments.
214
   *
215
   * @param protocol The protocol for this URL ("http", "ftp", etc)
216
   * @param host The hostname or IP address to connect to
217
   * @param port The port number to use, or -1 to use the protocol's
218
   * default port
219
   * @param file The "file" portion of the URL.
220
   *
221
   * @exception MalformedURLException If a protocol handler cannot be loaded or
222
   * a parse error occurs.
223
   */
224
  public URL(String protocol, String host, int port, String file)
225
    throws MalformedURLException
226
  {
227
    this(protocol, host, port, file, null);
228
  }
229
 
230
  /**
231
   * Constructs a URL and loads a protocol handler for the values passed in
232
   * as arugments.  Uses the default port for the protocol.
233
   *
234
   * @param protocol The protocol for this URL ("http", "ftp", etc)
235
   * @param host The hostname or IP address for this URL
236
   * @param file The "file" portion of this URL.
237
   *
238
   * @exception MalformedURLException If a protocol handler cannot be loaded or
239
   * a parse error occurs.
240
   */
241
  public URL(String protocol, String host, String file)
242
    throws MalformedURLException
243
  {
244
    this(protocol, host, -1, file, null);
245
  }
246
 
247
  /**
248
   * This method initializes a new instance of <code>URL</code> with the
249
   * specified protocol, host, port, and file.  Additionally, this method
250
   * allows the caller to specify a protocol handler to use instead of
251
   * the default.  If this handler is specified, the caller must have
252
   * the "specifyStreamHandler" permission (see <code>NetPermission</code>)
253
   * or a <code>SecurityException</code> will be thrown.
254
   *
255
   * @param protocol The protocol for this URL ("http", "ftp", etc)
256
   * @param host The hostname or IP address to connect to
257
   * @param port The port number to use, or -1 to use the protocol's default
258
   * port
259
   * @param file The "file" portion of the URL.
260
   * @param ph The protocol handler to use with this URL.
261
   *
262
   * @exception MalformedURLException If no protocol handler can be loaded
263
   * for the specified protocol.
264
   * @exception SecurityException If the <code>SecurityManager</code> exists
265
   * and does not allow the caller to specify its own protocol handler.
266
   *
267
   * @since 1.2
268
   */
269
  public URL(String protocol, String host, int port, String file,
270
             URLStreamHandler ph) throws MalformedURLException
271
  {
272
    if (protocol == null)
273
      throw new MalformedURLException("null protocol");
274
    protocol = protocol.toLowerCase();
275
    this.protocol = protocol;
276
 
277
    if (ph != null)
278
      {
279
        SecurityManager s = System.getSecurityManager();
280
        if (s != null)
281
          s.checkPermission(new NetPermission("specifyStreamHandler"));
282
 
283
        this.ph = ph;
284
      }
285
    else
286
      this.ph = getURLStreamHandler(protocol);
287
 
288
    if (this.ph == null)
289
      throw new MalformedURLException("Protocol handler not found: "
290
                                      + protocol);
291
 
292
    this.host = host;
293
    this.port = port;
294
    this.authority = (host != null) ? host : "";
295
    if (port >= 0 && host != null)
296
        this.authority += ":" + port;
297
 
298
    int hashAt = file.indexOf('#');
299
    if (hashAt < 0)
300
      {
301
        this.file = file;
302
        this.ref = null;
303
      }
304
    else
305
      {
306
        this.file = file.substring(0, hashAt);
307
        this.ref = file.substring(hashAt + 1);
308
      }
309
    hashCode = hashCode(); // Used for serialization.
310
  }
311
 
312
  /**
313
   * Initializes a URL from a complete string specification such as
314
   * "http://www.urbanophile.com/arenn/".  First the protocol name is parsed
315
   * out of the string.  Then a handler is located for that protocol and
316
   * the parseURL() method of that protocol handler is used to parse the
317
   * remaining fields.
318
   *
319
   * @param spec The complete String representation of a URL
320
   *
321
   * @exception MalformedURLException If a protocol handler cannot be found
322
   * or the URL cannot be parsed
323
   */
324
  public URL(String spec) throws MalformedURLException
325
  {
326
    this((URL) null, spec != null ? spec : "", (URLStreamHandler) null,
327
         false);
328
  }
329
 
330
  /**
331
   * This method parses a String representation of a URL within the
332
   * context of an existing URL.  Principally this means that any
333
   * fields not present the URL are inheritied from the context URL.
334
   * This allows relative URL's to be easily constructed.  If the
335
   * context argument is null, then a complete URL must be specified
336
   * in the URL string.  If the protocol parsed out of the URL is
337
   * different from the context URL's protocol, then then URL String
338
   * is also expected to be a complete URL.
339
   *
340
   * @param context The context on which to parse the specification
341
   * @param spec The string to parse an URL
342
   *
343
   * @exception MalformedURLException If a protocol handler cannot be found
344
   * for the URL cannot be parsed
345
   */
346
  public URL(URL context, String spec) throws MalformedURLException
347
  {
348
    this(context, spec,
349
         (context == null) ? (URLStreamHandler) null : context.ph,
350
         false);
351
  }
352
 
353
  /**
354
   * Creates an URL from given arguments
355
   * This method parses a String representation of a URL within the
356
   * context of an existing URL.  Principally this means that any fields
357
   * not present the URL are inheritied from the context URL.  This allows
358
   * relative URL's to be easily constructed.  If the context argument is
359
   * null, then a complete URL must be specified in the URL string.
360
   * If the protocol parsed out of the URL is different
361
   * from the context URL's protocol, then then URL String is also
362
   * expected to be a complete URL.
363
   * <p>
364
   * Additionally, this method allows the caller to specify a protocol handler
365
   * to use instead of  the default.  If this handler is specified, the caller
366
   * must have the "specifyStreamHandler" permission
367
   * (see <code>NetPermission</code>) or a <code>SecurityException</code>
368
   * will be thrown.
369
   *
370
   * @param context The context in which to parse the specification
371
   * @param spec The string to parse as an URL
372
   * @param ph The stream handler for the URL
373
   *
374
   * @exception MalformedURLException If a protocol handler cannot be found
375
   * or the URL cannot be parsed
376
   * @exception SecurityException If the <code>SecurityManager</code> exists
377
   * and does not allow the caller to specify its own protocol handler.
378
   *
379
   * @since 1.2
380
   */
381
  public URL(URL context, String spec, URLStreamHandler ph)
382
    throws MalformedURLException
383
  {
384
    this(context, spec, ph, true);
385
  }
386
 
387
  /**
388
   * Private constructor called by all other constructors taking
389
   * a context and spec.
390
   *
391
   * @param context The context in which to parse the specification
392
   * @param spec The string to parse as an URL
393
   * @param ph The stream handler for the URL
394
   * @param phFromUser Whether or not the user supplied the URLStreamHandler
395
   *
396
   */
397
  private URL(URL context, String spec, URLStreamHandler ph,
398
              boolean phFromUser)
399
    throws MalformedURLException
400
  {
401
    /* A protocol is defined by the doc as the substring before a ':'
402
     * as long as the ':' occurs before any '/'.
403
     *
404
     * If context is null, then spec must be an absolute URL.
405
     *
406
     * The relative URL need not specify all the components of a URL.
407
     * If the protocol, host name, or port number is missing, the value
408
     * is inherited from the context.  A bare file component is appended
409
     * to the context's file.  The optional anchor is not inherited.
410
     */
411
 
412
    // If this is an absolute URL, then ignore context completely.
413
    // An absolute URL must have chars prior to "://" but cannot have a colon
414
    // right after the "://".  The second colon is for an optional port value
415
    // and implies that the host from the context is used if available.
416
    int colon;
417
    int slash = spec.indexOf('/');
418
    if ((colon = spec.indexOf("://", 1)) > 0
419
        && ((colon < slash || slash < 0))
420
        && ! spec.regionMatches(colon, "://:", 0, 4))
421
      {
422
        context = null;
423
        if (! phFromUser)
424
          ph = null;
425
      }
426
 
427
    boolean protocolSpecified = false;
428
 
429
    if ((colon = spec.indexOf(':')) > 0
430
        && (colon < slash || slash < 0))
431
      {
432
        // Protocol may have been specified in spec string.
433
        protocolSpecified = true;
434
        protocol = spec.substring(0, colon).toLowerCase();
435
        if (context != null)
436
          {
437
            if (context.protocol.equals(protocol))
438
              {
439
                // The 1.2 doc specifically says these are copied to the new URL.
440
                host = context.host;
441
                port = context.port;
442
                userInfo = context.userInfo;
443
                authority = context.authority;
444
              }
445
            else
446
              {
447
                // There was a colon in the spec.  Check to see if
448
                // what precedes it is a valid protocol.  If it was
449
                // not, assume that it is relative to the context.
450
                URLStreamHandler specPh = getURLStreamHandler(protocol.trim());
451
                if (null == specPh)
452
                    protocolSpecified = false;
453
              }
454
          }
455
      }
456
 
457
    if (!protocolSpecified)
458
      {
459
        if (context != null)
460
          {
461
            // Protocol NOT specified in spec string.
462
            // Use context fields (except ref) as a foundation for relative URLs.
463
            colon = -1;
464
            protocol = context.protocol;
465
            host = context.host;
466
            port = context.port;
467
            userInfo = context.userInfo;
468
            if (spec.indexOf(":/", 1) < 0)
469
              {
470
                file = context.file;
471
                if (file == null || file.length() == 0)
472
                  file = "/";
473
              }
474
            authority = context.authority;
475
          }
476
        else // Protocol NOT specified in spec. and no context available.
477
          throw new MalformedURLException("Absolute URL required with null"
478
                                          + " context: " + spec);
479
      }
480
 
481
    protocol = protocol.trim();
482
 
483
    if (ph != null)
484
      {
485
        SecurityManager s = System.getSecurityManager();
486
        if (s != null && phFromUser)
487
          s.checkPermission(new NetPermission("specifyStreamHandler"));
488
 
489
        this.ph = ph;
490
      }
491
    else
492
      this.ph = getURLStreamHandler(protocol);
493
 
494
    if (this.ph == null)
495
      throw new MalformedURLException("Protocol handler not found: "
496
                                      + protocol);
497
 
498
    // JDK 1.2 doc for parseURL specifically states that any '#' ref
499
    // is to be excluded by passing the 'limit' as the indexOf the '#'
500
    // if one exists, otherwise pass the end of the string.
501
    int hashAt = spec.indexOf('#', colon + 1);
502
 
503
    try
504
      {
505
        this.ph.parseURL(this, spec, colon + 1,
506
                         hashAt < 0 ? spec.length() : hashAt);
507
      }
508
    catch (URLParseError e)
509
      {
510
        MalformedURLException mue = new MalformedURLException(e.getMessage());
511
        mue.initCause(e);
512
        throw mue;
513
      }
514
    catch (RuntimeException e)
515
      {
516
        // This isn't documented, but the JDK also catches
517
        // RuntimeExceptions here.
518
        MalformedURLException mue = new MalformedURLException(e.getMessage());
519
        mue.initCause(e);
520
        throw mue;
521
      }
522
 
523
    if (hashAt >= 0)
524
      ref = spec.substring(hashAt + 1);
525
 
526
    hashCode = hashCode(); // Used for serialization.
527
  }
528
 
529
  /**
530
   * Test another URL for equality with this one.  This will be true only if
531
   * the argument is non-null and all of the fields in the URL's match
532
   * exactly (ie, protocol, host, port, file, and ref).  Overrides
533
   * Object.equals(), implemented by calling the equals method of the handler.
534
   *
535
   * @param obj The URL to compare with
536
   *
537
   * @return true if the URL is equal, false otherwise
538
   */
539
  public boolean equals(Object obj)
540
  {
541
    if (! (obj instanceof URL))
542
      return false;
543
 
544
    return ph.equals(this, (URL) obj);
545
  }
546
 
547
  /**
548
   * Returns the contents of this URL as an object by first opening a
549
   * connection, then calling the getContent() method against the connection
550
   *
551
   * @return A content object for this URL
552
   * @exception IOException If opening the connection or getting the
553
   * content fails.
554
   *
555
   * @since 1.3
556
   */
557
  public Object getContent() throws IOException
558
  {
559
    return openConnection().getContent();
560
  }
561
 
562
  /**
563
   * Gets the contents of this URL
564
   *
565
   * @param classes The allow classes for the content object.
566
   *
567
   * @return a context object for this URL.
568
   *
569
   * @exception IOException If an error occurs
570
   */
571
  public Object getContent(Class[] classes) throws IOException
572
  {
573
    return openConnection().getContent(classes);
574
  }
575
 
576
  /**
577
   * Returns the file portion of the URL.
578
   * Defined as <code>path[?query]</code>.
579
   * Returns the empty string if there is no file portion.
580
   *
581
   * @return The filename specified in this URL, or an empty string if empty.
582
   */
583
  public String getFile()
584
  {
585
    return file == null ? "" : file;
586
  }
587
 
588
  /**
589
   * Returns the path of the URL. This is the part of the file before any '?'
590
   * character.
591
   *
592
   * @return The path specified in this URL, or null if empty.
593
   *
594
   * @since 1.3
595
   */
596
  public String getPath()
597
  {
598
    // The spec says we need to return an empty string, but some
599
    // applications depends on receiving null when the path is empty.
600
    if (file == null)
601
      return null;
602
    int quest = file.indexOf('?');
603
    return quest < 0 ? getFile() : file.substring(0, quest);
604
  }
605
 
606
  /**
607
   * Returns the authority of the URL
608
   *
609
   * @return The authority specified in this URL.
610
   *
611
   * @since 1.3
612
   */
613
  public String getAuthority()
614
  {
615
    return authority;
616
  }
617
 
618
  /**
619
   * Returns the host of the URL
620
   *
621
   * @return The host specified in this URL.
622
   */
623
  public String getHost()
624
  {
625
    int at = (host == null) ? -1 : host.indexOf('@');
626
    return at < 0 ? host : host.substring(at + 1, host.length());
627
  }
628
 
629
  /**
630
   * Returns the port number of this URL or -1 if the default port number is
631
   * being used.
632
   *
633
   * @return The port number
634
   *
635
   * @see #getDefaultPort()
636
   */
637
  public int getPort()
638
  {
639
    return port;
640
  }
641
 
642
  /**
643
   * Returns the default port of the URL. If the StreamHandler for the URL
644
   * protocol does not define a default port it returns -1.
645
   *
646
   * @return The default port of the current protocol.
647
   */
648
  public int getDefaultPort()
649
  {
650
    return ph.getDefaultPort();
651
  }
652
 
653
  /**
654
   * Returns the protocol of the URL
655
   *
656
   * @return The specified protocol.
657
   */
658
  public String getProtocol()
659
  {
660
    return protocol;
661
  }
662
 
663
  /**
664
   * Returns the ref (sometimes called the "# reference" or "anchor") portion
665
   * of the URL.
666
   *
667
   * @return The ref
668
   */
669
  public String getRef()
670
  {
671
    return ref;
672
  }
673
 
674
  /**
675
   * Returns the user information of the URL. This is the part of the host
676
   * name before the '@'.
677
   *
678
   * @return the user at a particular host or null when no user defined.
679
   */
680
  public String getUserInfo()
681
  {
682
    if (userInfo != null)
683
      return userInfo;
684
    int at = (host == null) ? -1 : host.indexOf('@');
685
    return at < 0 ? null : host.substring(0, at);
686
  }
687
 
688
  /**
689
   * Returns the query of the URL. This is the part of the file before the
690
   * '?'.
691
   *
692
   * @return the query part of the file, or null when there is no query part.
693
   */
694
  public String getQuery()
695
  {
696
    int quest = (file == null) ? -1 : file.indexOf('?');
697
    return quest < 0 ? null : file.substring(quest + 1, file.length());
698
  }
699
 
700
  /**
701
   * Returns a hashcode computed by the URLStreamHandler of this URL
702
   *
703
   * @return The hashcode for this URL.
704
   */
705
  public int hashCode()
706
  {
707
    if (hashCode != 0)
708
      return hashCode; // Use cached value if available.
709
    else
710
      return ph.hashCode(this);
711
  }
712
 
713
  /**
714
   * Returns a URLConnection object that represents a connection to the remote
715
   * object referred to by the URL. The URLConnection is created by calling the
716
   * openConnection() method of the protocol handler
717
   *
718
   * @return A URLConnection for this URL
719
   *
720
   * @exception IOException If an error occurs
721
   */
722
  public URLConnection openConnection() throws IOException
723
  {
724
    return ph.openConnection(this);
725
  }
726
 
727
  /**
728
   * Opens a connection to this URL and returns an InputStream for reading
729
   * from that connection
730
   *
731
   * @return An <code>InputStream</code> for this URL.
732
   *
733
   * @exception IOException If an error occurs
734
   */
735
  public InputStream openStream() throws IOException
736
  {
737
    return openConnection().getInputStream();
738
  }
739
 
740
  /**
741
   * Tests whether or not another URL refers to the same "file" as this one.
742
   * This will be true if and only if the passed object is not null, is a
743
   * URL, and matches all fields but the ref (ie, protocol, host, port,
744
   * and file);
745
   *
746
   * @param url The URL object to test with
747
   *
748
   * @return true if URL matches this URL's file, false otherwise
749
   */
750
  public boolean sameFile(URL url)
751
  {
752
    return ph.sameFile(this, url);
753
  }
754
 
755
  /**
756
   * Sets the specified fields of the URL. This is not a public method so
757
   * that only URLStreamHandlers can modify URL fields. This might be called
758
   * by the <code>parseURL()</code> method in that class. URLs are otherwise
759
   * constant. If the given protocol does not exist, it will keep the previously
760
   * set protocol.
761
   *
762
   * @param protocol The protocol name for this URL
763
   * @param host The hostname or IP address for this URL
764
   * @param port The port number of this URL
765
   * @param file The "file" portion of this URL.
766
   * @param ref The anchor portion of this URL.
767
   */
768
  protected void set(String protocol, String host, int port, String file,
769
                     String ref)
770
  {
771
    URLStreamHandler protocolHandler = null;
772
    protocol = protocol.toLowerCase();
773
    if (! this.protocol.equals(protocol))
774
      protocolHandler = getURLStreamHandler(protocol);
775
 
776
    // It is an hidden feature of the JDK. If the protocol does not exist,
777
    // we keep the previously initialized protocol.
778
    if (protocolHandler != null)
779
      {
780
        this.ph = protocolHandler;
781
        this.protocol = protocol;
782
      }
783
    this.authority = "";
784
    this.port = port;
785
    this.host = host;
786
    this.file = file;
787
    this.ref = ref;
788
 
789
    if (host != null)
790
      this.authority += host;
791
    if (port >= 0)
792
      this.authority += ":" + port;
793
 
794
    hashCode = hashCode(); // Used for serialization.
795
  }
796
 
797
  /**
798
   * Sets the specified fields of the URL. This is not a public method so
799
   * that only URLStreamHandlers can modify URL fields. URLs are otherwise
800
   * constant. If the given protocol does not exist, it will keep the previously
801
   * set protocol.
802
   *
803
   * @param protocol The protocol name for this URL.
804
   * @param host The hostname or IP address for this URL.
805
   * @param port The port number of this URL.
806
   * @param authority The authority of this URL.
807
   * @param userInfo The user and password (if needed) of this URL.
808
   * @param path The "path" portion of this URL.
809
   * @param query The query of this URL.
810
   * @param ref The anchor portion of this URL.
811
   *
812
   * @since 1.3
813
   */
814
  protected void set(String protocol, String host, int port, String authority,
815
                     String userInfo, String path, String query, String ref)
816
  {
817
    URLStreamHandler protocolHandler = null;
818
    protocol = protocol.toLowerCase();
819
    if (! this.protocol.equals(protocol))
820
      protocolHandler = getURLStreamHandler(protocol);
821
 
822
    // It is an hidden feature of the JDK. If the protocol does not exist,
823
    // we keep the previously initialized protocol.
824
    if (protocolHandler != null)
825
      {
826
        this.ph = protocolHandler;
827
        this.protocol = protocol;
828
      }
829
    this.host = host;
830
    this.userInfo = userInfo;
831
    this.port = port;
832
    this.authority = authority;
833
    if (query == null)
834
      this.file = path;
835
    else
836
      this.file = path + "?" + query;
837
    this.ref = ref;
838
    hashCode = hashCode(); // Used for serialization.
839
  }
840
 
841
  /**
842
   * Sets the URLStreamHandlerFactory for this class.  This factory is
843
   * responsible for returning the appropriate protocol handler for
844
   * a given URL.
845
   *
846
   * @param fac The URLStreamHandlerFactory class to use
847
   *
848
   * @exception Error If the factory is alread set.
849
   * @exception SecurityException If a security manager exists and its
850
   * checkSetFactory method doesn't allow the operation
851
   */
852
  public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
853
  {
854
    if (factory != null)
855
      throw new Error("URLStreamHandlerFactory already set");
856
 
857
    // Throw an exception if an extant security mgr precludes
858
    // setting the factory.
859
    SecurityManager s = System.getSecurityManager();
860
    if (s != null)
861
      s.checkSetFactory();
862
    factory = fac;
863
  }
864
 
865
  /**
866
   * Returns a String representing this URL.  The String returned is
867
   * created by calling the protocol handler's toExternalForm() method.
868
   *
869
   * @return A string for this URL
870
   */
871
  public String toExternalForm()
872
  {
873
    // Identical to toString().
874
    return ph.toExternalForm(this);
875
  }
876
 
877
  /**
878
   * Returns a String representing this URL.  Identical to toExternalForm().
879
   * The value returned is created by the protocol handler's
880
   * toExternalForm method.  Overrides Object.toString()
881
   *
882
   * @return A string for this URL
883
   */
884
  public String toString()
885
  {
886
    // Identical to toExternalForm().
887
    return ph.toExternalForm(this);
888
  }
889
 
890
  /**
891
   * This internal method is used in two different constructors to load
892
   * a protocol handler for this URL.
893
   *
894
   * @param protocol The protocol to load a handler for
895
   *
896
   * @return A URLStreamHandler for this protocol, or null when not found.
897
   */
898
  private static synchronized URLStreamHandler getURLStreamHandler(String protocol)
899
  {
900
    URLStreamHandler ph = null;
901
 
902
    // First, see if a protocol handler is in our cache.
903
    if (cache_handlers)
904
      {
905
        if ((ph = ph_cache.get(protocol)) != null)
906
          return ph;
907
      }
908
 
909
    // If a non-default factory has been set, use it to find the protocol.
910
    if (factory != null)
911
      {
912
        ph = factory.createURLStreamHandler(protocol);
913
      }
914
 
915
    // Non-default factory may have returned null or a factory wasn't set.
916
    // Use the default search algorithm to find a handler for this protocol.
917
    if (ph == null)
918
      {
919
        // Get the list of packages to check and append our default handler
920
        // to it, along with the JDK specified default as a last resort.
921
        // Except in very unusual environments the JDK specified one shouldn't
922
        // ever be needed (or available).
923
        String ph_search_path =
924
          SystemProperties.getProperty("java.protocol.handler.pkgs");
925
 
926
        // Tack our default package on at the ends.
927
        if (ph_search_path != null)
928
          ph_search_path += "|" + DEFAULT_SEARCH_PATH;
929
        else
930
          ph_search_path = DEFAULT_SEARCH_PATH;
931
 
932
        // Finally loop through our search path looking for a match.
933
        StringTokenizer pkgPrefix = new StringTokenizer(ph_search_path, "|");
934
 
935
        // Cache the systemClassLoader
936
        if (systemClassLoader == null)
937
          {
938
            systemClassLoader = AccessController.doPrivileged
939
              (new PrivilegedAction<ClassLoader>() {
940
                  public ClassLoader run()
941
                  {
942
                    return ClassLoader.getSystemClassLoader();
943
                  }
944
                });
945
          }
946
 
947
        do
948
          {
949
            try
950
              {
951
                // Try to get a class from the system/application
952
                // classloader, initialize it, make an instance
953
                // and try to cast it to a URLStreamHandler.
954
                String clsName =
955
                  (pkgPrefix.nextToken() + "." + protocol + ".Handler");
956
                Class c = Class.forName(clsName, true, systemClassLoader);
957
                ph = (URLStreamHandler) c.newInstance();
958
              }
959
            catch (ThreadDeath death)
960
              {
961
                throw death;
962
              }
963
            catch (Throwable t)
964
              {
965
                // Ignored.
966
              }
967
          }
968
         while (ph == null && pkgPrefix.hasMoreTokens());
969
      }
970
 
971
    // Update the hashtable with the new protocol handler.
972
    if (ph != null && cache_handlers)
973
      ph_cache.put(protocol, ph);
974
    else
975
      ph = null;
976
 
977
    return ph;
978
  }
979
 
980
  private void readObject(ObjectInputStream ois)
981
    throws IOException, ClassNotFoundException
982
  {
983
    ois.defaultReadObject();
984
    this.ph = getURLStreamHandler(protocol);
985
    if (this.ph == null)
986
      throw new IOException("Handler for protocol " + protocol + " not found");
987
  }
988
 
989
  private void writeObject(ObjectOutputStream oos) throws IOException
990
  {
991
    oos.defaultWriteObject();
992
  }
993
 
994
  /**
995
   * Returns the equivalent <code>URI</code> object for this <code>URL</code>.
996
   * This is the same as calling <code>new URI(this.toString())</code>.
997
   * RFC2396-compliant URLs are guaranteed a successful conversion to
998
   * a <code>URI</code> instance.  However, there are some values which
999
   * form valid URLs, but which do not also form RFC2396-compliant URIs.
1000
   *
1001
   * @throws URISyntaxException if this URL is not RFC2396-compliant,
1002
   *         and thus can not be successfully converted to a URI.
1003
   */
1004
  public URI toURI()
1005
    throws URISyntaxException
1006
  {
1007
    return new URI(toString());
1008
  }
1009
 
1010
}

powered by: WebSVN 2.1.0

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