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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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