From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001
From: upstream source tree
+ * To make use of this feature, a programmer must create a subclass
+ * that knows how to obtain the necessary info. An example
+ * would be a class that popped up a dialog box to prompt the user.
+ * After creating an instance of that subclass, the static
+ *
+ * This class can also be used for receiving data from the network.
+ *
+ * Note that for all method below where the buffer length passed by the
+ * caller cannot exceed the actually length of the byte array passed as
+ * the buffer, if this condition is not true, then the method silently
+ * reduces the length value to maximum allowable value.
+ *
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aarom M. Renn (arenn@urbanophile.com) (Documentation comments)
+ * @date April 28, 1999.
+ */
+public final class DatagramPacket
+{
+ /**
+ * The data buffer to send
+ */
+ private byte[] buffer;
+
+ /**
+ * This is the offset into the buffer to start sending from or receiving to.
+ */
+ private int offset;
+
+ /**
+ * The length of the data buffer to send.
+ */
+ int length;
+
+ /**
+ * The maximal length of the buffer.
+ */
+ int maxlen;
+
+ /**
+ * The address to which the packet should be sent or from which it
+ * was received.
+ */
+ private InetAddress address;
+
+ /**
+ * The port to which the packet should be sent or from which it was
+ * was received.
+ */
+ private int port;
+
+ /**
+ * This method initializes a new instance of
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ *
+ * Status: Believed complete and correct.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ */
+public abstract class DatagramSocketImpl implements SocketOptions
+{
+ /**
+ * The local port to which this socket is bound
+ */
+ protected int localPort;
+
+ /**
+ * The FileDescriptor object for this object.
+ */
+ protected FileDescriptor fd;
+
+ /**
+ * Default, no-argument constructor for subclasses to call.
+ */
+ public DatagramSocketImpl()
+ {
+ }
+
+ /**
+ * This method binds the socket to the specified local port and address.
+ *
+ * @param lport The port number to bind to
+ * @param laddr The address to bind to
+ *
+ * @exception SocketException If an error occurs
+ */
+ protected abstract void bind(int lport, InetAddress laddr)
+ throws SocketException;
+
+ /**
+ * This methods closes the socket
+ */
+ protected abstract void close();
+
+ /**
+ * Creates a new datagram socket.
+ *
+ * @exception SocketException If an error occurs
+ */
+ protected abstract void create() throws SocketException;
+
+ /**
+ * Takes a peek at the next packet received in order to retrieve the
+ * address of the sender
+ *
+ * @param i The This class fulfills the function of the C style functions gethostname(),
+ * gethostbyname(), and gethostbyaddr(). It resolves Internet DNS names
+ * into their corresponding numeric addresses and vice versa. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden. This method cannot be abstract for backward compatibility reasons. By
+ * default it always throws {@link UnsupportedOperationException} unless
+ * overridden.
+ * jar:<standard URL pointing to jar filei>!/file/within/jarfile
+ * for example:
+ *
+ * jar:http://www.urbanophile.com/java/foo.jar!/com/urbanophile/bar.class
+ *
+ * That example URL points to the file /com/urbanophile/bar.class in the
+ * remote JAR file http://www.urbanophile.com/java/foo.jar. The HTTP
+ * protocol is used only as an example. Any supported remote protocol
+ * can be used.
+ *
+ * This class currently works by retrieving the entire jar file into a
+ * local cache file, then performing standard jar operations on it.
+ * (At least this is true for the default protocol implementation).
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Kresten Krab Thorup (krab@gnu.org)
+ * @date Aug 10, 1999.
+ *
+ * @since 1.2
+ */
+public abstract class JarURLConnection extends URLConnection
+{
+ /**
+ * This is the actual URL that points the remote jar file. This is parsed
+ * out of the jar URL by the constructor.
+ */
+ private final URL jarFileURL;
+
+ /**
+ * The connection to the jar file itself. A JarURLConnection
+ * can represent an entry in a jar file or an entire jar file. In
+ * either case this describes just the jar file itself.
+ */
+ protected URLConnection jarFileURLConnection;
+
+ /**
+ * This is the jar file "entry name" or portion after the "!/" in the
+ * URL which represents the pathname inside the actual jar file.
+ */
+ private final String entryName;
+
+ /**
+ * Creates a JarURLConnection from an URL object
+ *
+ * @param url The URL object for this connection.
+ *
+ * @exception MalformedURLException If url is invalid
+ *
+ * @specnote This constructor is protected since JDK 1.4
+ */
+ protected JarURLConnection(URL url) throws MalformedURLException
+ {
+ super(url);
+
+ if (! url.getProtocol().equals("jar"))
+ throw new MalformedURLException(url + ": Not jar protocol.");
+
+ String spec = url.getFile();
+ int bang = spec.indexOf("!/");
+ if (bang == -1)
+ throw new MalformedURLException(url + ": No `!/' in spec.");
+
+ // Extract the url for the jar itself.
+ jarFileURL = new URL(spec.substring(0, bang));
+
+ // Get the name of the entry, if any.
+ entryName = spec.length() == (bang + 2) ? null : spec.substring(bang + 2);
+ }
+
+ /**
+ * This method returns the "real" URL where the JarFile is located.
+ * //****Is this right?*****
+ *
+ * @return The remote URL
+ */
+ public URL getJarFileURL()
+ {
+ return jarFileURL;
+ }
+
+ /**
+ * Returns the "entry name" portion of the jar URL. This is the portion
+ * after the "!/" in the jar URL that represents the pathname inside the
+ * actual jar file.
+ *
+ * @return The entry name.
+ */
+ public String getEntryName()
+ {
+ return entryName;
+ }
+
+ /**
+ * Returns the entry in this jar file specified by the URL.
+ *
+ * @return The jar entry
+ *
+ * @exception IOException If an error occurs
+ */
+ public JarEntry getJarEntry() throws IOException
+ {
+ if (entryName == null)
+ return null;
+ JarFile jarFile = getJarFile();
+ return jarFile != null ? jarFile.getJarEntry(entryName) : null;
+ }
+
+ /**
+ * Returns a read-only JarFile object for the remote jar file
+ *
+ * @return The JarFile object
+ *
+ * @exception IOException If an error occurs
+ */
+ public abstract JarFile getJarFile() throws IOException;
+
+ /**
+ * Returns an array of Certificate objects for the jar file entry specified
+ * by this URL or null if there are none
+ *
+ * @return A Certificate array
+ *
+ * @exception IOException If an error occurs
+ */
+ public Certificate[] getCertificates() throws IOException
+ {
+ JarEntry entry = getJarEntry();
+
+ return entry != null ? entry.getCertificates() : null;
+ }
+
+ /**
+ * Returns the main Attributes for the jar file specified in the URL or
+ * null if there are none
+ *
+ * @return The main Attributes for the JAR file for this connection
+ *
+ * @exception IOException If an error occurs
+ */
+ public Attributes getMainAttributes() throws IOException
+ {
+ Manifest manifest = getManifest();
+
+ return manifest != null ? manifest.getMainAttributes() : null;
+ }
+
+ /**
+ * Returns the Attributes for the Jar entry specified by the URL or null
+ * if none
+ *
+ * @return The Attributes object for this connection if the URL for it points
+ * to a JAR file entry, null otherwise
+ *
+ * @exception IOException If an error occurs
+ */
+ public Attributes getAttributes() throws IOException
+ {
+ JarEntry entry = getJarEntry();
+
+ return entry != null ? entry.getAttributes() : null;
+ }
+
+ /**
+ * Returns a Manifest object for this jar file, or null if there is no
+ * manifest.
+ *
+ * @return The Manifest for this connection, or null if none
+ *
+ * @exception IOException If an error occurs
+ */
+ public Manifest getManifest() throws IOException
+ {
+ JarFile file = getJarFile();
+
+ return file != null ? file.getManifest() : null;
+ }
+}
diff --git a/libjava/classpath/java/net/MalformedURLException.java b/libjava/classpath/java/net/MalformedURLException.java
new file mode 100644
index 000000000..27e201886
--- /dev/null
+++ b/libjava/classpath/java/net/MalformedURLException.java
@@ -0,0 +1,74 @@
+/* MalformedURLException.java -- A URL was not in a valid format
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+
+
+/**
+ * This exception indicates that a URL passed to an object was not in a
+ * valid format.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @status updated to 1.4
+ */
+public class MalformedURLException extends IOException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -182787522200415866L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public MalformedURLException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message a message describing the error that occurred
+ */
+ public MalformedURLException(String message)
+ {
+ super(message);
+ }
+} // class MalformedURLException
diff --git a/libjava/classpath/java/net/MimeTypeMapper.java b/libjava/classpath/java/net/MimeTypeMapper.java
new file mode 100644
index 000000000..3e4379291
--- /dev/null
+++ b/libjava/classpath/java/net/MimeTypeMapper.java
@@ -0,0 +1,346 @@
+/* MimeTypeMapper.java -- A class for mapping file names to MIME types
+ Copyright (C) 1998 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.classpath.SystemProperties;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+
+/**
+ * This non-public class is used to implement the FileNameMap interface
+ * which defines a mechanism for mapping filenames to MIME types.
+ *
+ * @version 0.5
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+class MimeTypeMapper implements FileNameMap
+{
+ /**
+ * This array of strings is used to identify a MIME type based on a file
+ * extension. This is list is based on the Apache mime.types file.
+ */
+ protected static final String[][] mime_strings =
+ {
+ { "ai", "application/postscript" }
+ , { "aif", "audio/x-aiff" }
+ , { "aifc", "audio/x-aiff" }
+ , { "aiff", "audio/x-aiff" }
+ , { "asc", "text/plain" }
+ , { "au", "audio/basic" }
+ , { "avi", "video/x-msvideo" }
+ , { "bcpio", "application/x-bcpio" }
+ , { "bin", "application/octet-stream" }
+ , { "bmp", "image/bmp" }
+ , { "bz2", "application/x-bzip2" }
+ , { "cdf", "application/x-netcdf" }
+ , { "chrt", "application/x-kchart" }
+ , { "class", "application/octet-stream" }
+ , { "cpio", "application/x-cpio" }
+ , { "cpt", "application/mac-compactpro" }
+ , { "csh", "application/x-csh" }
+ , { "css", "text/css" }
+ , { "dcr", "application/x-director" }
+ , { "dir", "application/x-director" }
+ , { "djv", "image/vnd.djvu" }
+ , { "djvu", "image/vnd.djvu" }
+ , { "dll", "application/octet-stream" }
+ , { "dms", "application/octet-stream" }
+ , { "doc", "application/msword" }
+ , { "dvi", "application/x-dvi" }
+ , { "dxr", "application/x-director" }
+ , { "eps", "application/postscript" }
+ , { "etx", "text/x-setext" }
+ , { "exe", "application/octet-stream" }
+ , { "ez", "application/andrew-inset" }
+ , { "gif", "image/gif" }
+ , { "gtar", "application/x-gtar" }
+ , { "gz", "application/x-gzip" }
+ , { "hdf", "application/x-hdf" }
+ , { "hqx", "application/mac-binhex40" }
+ , { "htm", "text/html" }
+ , { "html", "text/html" }
+ , { "ice", "x-conference/x-cooltalk" }
+ , { "ief", "image/ief" }
+ , { "iges", "model/iges" }
+ , { "igs", "model/iges" }
+ , { "img", "application/octet-stream" }
+ , { "iso", "application/octet-stream" }
+ , { "jpe", "image/jpeg" }
+ , { "jpeg", "image/jpeg" }
+ , { "jpg", "image/jpeg" }
+ , { "js", "application/x-javascript" }
+ , { "kar", "audio/midi" }
+ , { "kil", "application/x-killustrator" }
+ , { "kpr", "application/x-kpresenter" }
+ , { "kpt", "application/x-kpresenter" }
+ , { "ksp", "application/x-kspread" }
+ , { "kwd", "application/x-kword" }
+ , { "kwt", "application/x-kword" }
+ , { "latex", "application/x-latex" }
+ , { "lha", "application/octet-stream" }
+ , { "lzh", "application/octet-stream" }
+ , { "m3u", "audio/x-mpegurl" }
+ , { "man", "application/x-troff-man" }
+ , { "me", "application/x-troff-me" }
+ , { "mesh", "model/mesh" }
+ , { "mid", "audio/midi" }
+ , { "midi", "audio/midi" }
+ , { "mif", "application/vnd.mif" }
+ , { "mov", "video/quicktime" }
+ , { "movie", "video/x-sgi-movie" }
+ , { "mp2", "audio/mpeg" }
+ , { "mp3", "audio/mpeg" }
+ , { "mpe", "video/mpeg" }
+ , { "mpeg", "video/mpeg" }
+ , { "mpg", "video/mpeg" }
+ , { "mpga", "audio/mpeg" }
+ , { "ms", "application/x-troff-ms" }
+ , { "msh", "model/mesh" }
+ , { "mxu", "video/vnd.mpegurl" }
+ , { "nc", "application/x-netcdf" }
+ , { "ogg", "application/ogg" }
+ , { "pbm", "image/x-portable-bitmap" }
+ , { "pdb", "chemical/x-pdb" }
+ , { "pdf", "application/pdf" }
+ , { "pgm", "image/x-portable-graymap" }
+ , { "pgn", "application/x-chess-pgn" }
+ , { "png", "image/png" }
+ , { "pnm", "image/x-portable-anymap" }
+ , { "ppm", "image/x-portable-pixmap" }
+ , { "ppt", "application/vnd.ms-powerpoint" }
+ , { "ps", "application/postscript" }
+ , { "qt", "video/quicktime" }
+ , { "ra", "audio/x-realaudio" }
+ , { "ram", "audio/x-pn-realaudio" }
+ , { "ras", "image/x-cmu-raster" }
+ , { "rgb", "image/x-rgb" }
+ , { "rm", "audio/x-pn-realaudio" }
+ , { "roff", "application/x-troff" }
+ , { "rpm", "application/x-rpm" }
+ , { "rtf", "text/rtf" }
+ , { "rtx", "text/richtext" }
+ , { "sgm", "text/sgml" }
+ , { "sgml", "text/sgml" }
+ , { "sh", "application/x-sh" }
+ , { "shar", "application/x-shar" }
+ , { "silo", "model/mesh" }
+ , { "sit", "application/x-stuffit" }
+ , { "skd", "application/x-koan" }
+ , { "skm", "application/x-koan" }
+ , { "skp", "application/x-koan" }
+ , { "skt", "application/x-koan" }
+ , { "smi", "application/smil" }
+ , { "smil", "application/smil" }
+ , { "snd", "audio/basic" }
+ , { "so", "application/octet-stream" }
+ , { "spl", "application/x-futuresplash" }
+ , { "src", "application/x-wais-source" }
+ , { "stc", "application/vnd.sun.xml.calc.template" }
+ , { "std", "application/vnd.sun.xml.draw.template" }
+ , { "sti", "application/vnd.sun.xml.impress.template" }
+ , { "stw", "application/vnd.sun.xml.writer.template" }
+ , { "sv4cpio", "application/x-sv4cpio" }
+ , { "sv4crc", "application/x-sv4crc" }
+ , { "swf", "application/x-shockwave-flash" }
+ , { "sxc", "application/vnd.sun.xml.calc" }
+ , { "sxd", "application/vnd.sun.xml.draw" }
+ , { "sxg", "application/vnd.sun.xml.writer.global" }
+ , { "sxi", "application/vnd.sun.xml.impress" }
+ , { "sxm", "application/vnd.sun.xml.math" }
+ , { "sxw", "application/vnd.sun.xml.writer" }
+ , { "t", "application/x-troff" }
+ , { "tar", "application/x-tar" }
+ , { "tcl", "application/x-tcl" }
+ , { "tex", "application/x-tex" }
+ , { "texi", "application/x-texinfo" }
+ , { "texinfo", "application/x-texinfo" }
+ , { "tgz", "application/x-gzip" }
+ , { "tif", "image/tiff" }
+ , { "tiff", "image/tiff" }
+ , { "torrent", "application/x-bittorrent" }
+ , { "tr", "application/x-troff" }
+ , { "tsv", "text/tab-separated-values" }
+ , { "txt", "text/plain" }
+ , { "ustar", "application/x-ustar" }
+ , { "vcd", "application/x-cdlink" }
+ , { "vrml", "model/vrml" }
+ , { "wav", "audio/x-wav" }
+ , { "wbmp", "image/vnd.wap.wbmp" }
+ , { "wbxml", "application/vnd.wap.wbxml" }
+ , { "wml", "text/vnd.wap.wml" }
+ , { "wmlc", "application/vnd.wap.wmlc" }
+ , { "wmls", "text/vnd.wap.wmlscript" }
+ , { "wmlsc", "application/vnd.wap.wmlscriptc" }
+ , { "wrl", "model/vrml" }
+ , { "xbm", "image/x-xbitmap" }
+ , { "xht", "application/xhtml+xml" }
+ , { "xhtml", "application/xhtml+xml" }
+ , { "xls", "application/vnd.ms-excel" }
+ , { "xml", "text/xml" }
+ , { "xpm", "image/x-xpixmap" }
+ , { "xsl", "text/xml" }
+ , { "xwd", "image/x-xwindowdump" }
+ , { "xyz", "chemical/x-xyz" }
+ , { "zip", "application/zip" }
+ };
+
+ /**
+ * The MIME types above are put into this Hashtable for faster lookup.
+ */
+ private Hashtable
+ * Please note that applets are not allowed to use multicast sockets
+ *
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com) (Documentation comments)
+ * @since 1.1
+ * @date May 18, 1999.
+ */
+public class MulticastSocket extends DatagramSocket
+{
+ /**
+ * Create a MulticastSocket that this not bound to any address
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation
+ */
+ public MulticastSocket() throws IOException
+ {
+ this(new InetSocketAddress(0));
+ }
+
+ /**
+ * Create a multicast socket bound to the specified port
+ *
+ * @param port The port to bind to
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation
+ */
+ public MulticastSocket(int port) throws IOException
+ {
+ this(new InetSocketAddress(port));
+ }
+
+ /**
+ * Create a multicast socket bound to the specified SocketAddress.
+ *
+ * @param address The SocketAddress the multicast socket will be bound to
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation
+ *
+ * @since 1.4
+ */
+ public MulticastSocket(SocketAddress address) throws IOException
+ {
+ super((SocketAddress) null);
+ setReuseAddress(true);
+ if (address != null)
+ bind(address);
+ }
+
+ /**
+ * Returns the interface being used for multicast packets
+ *
+ * @return The multicast interface
+ *
+ * @exception SocketException If an error occurs
+ */
+ public InetAddress getInterface() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ return (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
+ }
+
+ /**
+ * Returns the current value of the "Time to Live" option. This is the
+ * number of hops a packet can make before it "expires". This method id
+ * deprecated. Use
+ * where # and : are literal characters,
+ * and those parts enclosed in square brackets are optional.
+ *
+ * There are two main types of URI. An opaque URI is one
+ * which just consists of the above three parts, and is not further
+ * defined. An example of such a URI would be mailto: URI.
+ * In contrast, hierarchical URIs give further definition
+ * to the scheme-specific part, so as represent some part of a hierarchical
+ * structure.
+ *
+ *
+ * with / and ? being literal characters.
+ * When server-based, the authority section is further subdivided into:
+ *
+ *
+ * with @ and : as literal characters.
+ * Authority sections that are not server-based are said to be registry-based.
+ *
+ * Hierarchical URIs can be either relative or absolute. Absolute URIs
+ * always start with a `/', while relative URIs don't
+ * specify a scheme. Opaque URIs are always absolute.
+ *
+ * Each part of the URI may have one of three states: undefined, empty
+ * or containing some content. The former two of these are represented
+ * by
+ * The characters that can be used within a valid URI are restricted.
+ * There are two main classes of characters which can't be used as is
+ * within the URI:
+ *
+ * The set of valid characters differs depending on the section of the URI:
+ *
+ * These definitions reference the following sets of characters:
+ *
+ * The constructors and accessor methods allow the use and retrieval of
+ * URI components which contain non-US-ASCII characters directly.
+ * They are only escaped when the
+ * Returns the string content of the specified group of the supplied
+ * matcher. The returned value is modified according to the following:
+ *
+ * This method is used for matching against all parts of the URI
+ * that may be either undefined or empty (i.e. all those but the
+ * scheme-specific part and the path). In each case, the preceding
+ * group is the content of the original group, along with some
+ * additional distinguishing feature. For example, the preceding
+ * group for the query includes the preceding question mark,
+ * while that of the fragment includes the hash symbol. The presence
+ * of these features enables disambiguation between the two cases
+ * of a completely unspecified value and a simple non-existant value.
+ * The scheme differs in that it will never return an empty string;
+ * the delimiter follows the scheme rather than preceding it, so
+ * it becomes part of the following section. The same is true
+ * of the user information.
+ *
+ * Returns a normalized version of the URI. If the URI is opaque,
+ * or its path is already in normal form, then this URI is simply
+ * returned. Otherwise, the following transformation of the path
+ * element takes place:
+ *
+ * The resulting URI will be free of `.' and `..' segments, barring those
+ * that were prepended or which couldn't be paired, respectively.
+ *
+ * Normalize the given path. The following transformation takes place:
+ *
+ * The resulting URI will be free of `.' and `..' segments, barring those
+ * that were prepended or which couldn't be paired, respectively.
+ *
+ * Relativizes the given URI against this URI. The following
+ * algorithm is used:
+ *
+ * Compares the URI with the given object for equality. If the
+ * object is not a setDefault
method of this class is called to set up
+ * that instance as the object to use on subsequent calls to obtain
+ * authorization.
+ *
+ * @since 1.2
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @status Believed to be JDK 1.4 complete
+ */
+public abstract class Authenticator
+{
+ /*
+ * Class Variables
+ */
+
+ /**
+ * This is the default Authenticator object to use for password requests
+ */
+ private static Authenticator defaultAuthenticator;
+
+ /*
+ * Instance Variables
+ */
+
+ /**
+ * The hostname of the site requesting authentication
+ */
+ private String host;
+
+ /**
+ * InternetAddress of the site requesting authentication
+ */
+ private InetAddress addr;
+
+ /**
+ * The port number of the site requesting authentication
+ */
+ private int port;
+
+ /**
+ * The protocol name of the site requesting authentication
+ */
+ private String protocol;
+
+ /**
+ * The prompt to display to the user when requesting authentication info
+ */
+ private String prompt;
+
+ /**
+ * The authentication scheme in use
+ */
+ private String scheme;
+
+ /*
+ * Class Methods
+ */
+
+ /**
+ * This method sets the default Authenticator
object (an
+ * instance of a subclass of Authenticator
) to use when
+ * prompting the user for
+ * information. Note that this method checks to see if the caller is
+ * allowed to set this value (the "setDefaultAuthenticator" permission)
+ * and throws a SecurityException
if it is not.
+ *
+ * @param defAuth The new default Authenticator
object to use
+ *
+ * @exception SecurityException If the caller does not have permission
+ * to perform this operation
+ */
+ public static void setDefault(Authenticator defAuth)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetPermission("setDefaultAuthenticator"));
+
+ defaultAuthenticator = defAuth;
+ }
+
+ /**
+ * This method is called whenever a username and password for a given
+ * network operation is required. First, a security check is made to see
+ * if the caller has the "requestPasswordAuthentication"
+ * permission. If not, the method thows an exception. If there is no
+ * default Authenticator
object, the method then returns
+ * null
. Otherwise, the default authenticators's instance
+ * variables are initialized and it's getPasswordAuthentication
+ * method is called to get the actual authentication information to return.
+ *
+ * @param addr The address requesting authentication
+ * @param port The port requesting authentication
+ * @param protocol The protocol requesting authentication
+ * @param prompt The prompt to display to the user when requesting
+ * authentication info
+ * @param scheme The authentication scheme in use
+ *
+ * @return A PasswordAuthentication
object with the user's
+ * authentication info.
+ *
+ * @exception SecurityException If the caller does not have permission to
+ * perform this operation
+ */
+ public static PasswordAuthentication requestPasswordAuthentication(InetAddress addr,
+ int port,
+ String protocol,
+ String prompt,
+ String scheme)
+ throws SecurityException
+ {
+ return requestPasswordAuthentication(null, addr, port, protocol, prompt,
+ scheme);
+ }
+
+ /**
+ * This method is called whenever a username and password for a given
+ * network operation is required. First, a security check is made to see
+ * if the caller has the "requestPasswordAuthentication"
+ * permission. If not, the method thows an exception. If there is no
+ * default Authenticator
object, the method then returns
+ * null
. Otherwise, the default authenticators's instance
+ * variables are initialized and it's getPasswordAuthentication
+ * method is called to get the actual authentication information to return.
+ * This method is the preferred one as it can be used with hostname
+ * when addr is unknown.
+ *
+ * @param host The hostname requesting authentication
+ * @param addr The address requesting authentication
+ * @param port The port requesting authentication
+ * @param protocol The protocol requesting authentication
+ * @param prompt The prompt to display to the user when requesting
+ * authentication info
+ * @param scheme The authentication scheme in use
+ *
+ * @return A PasswordAuthentication
object with the user's
+ * authentication info.
+ *
+ * @exception SecurityException If the caller does not have permission to
+ * perform this operation
+ *
+ * @since 1.4
+ */
+ public static PasswordAuthentication requestPasswordAuthentication(String host,
+ InetAddress addr,
+ int port,
+ String protocol,
+ String prompt,
+ String scheme)
+ throws SecurityException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(new NetPermission("requestPasswordAuthentication"));
+
+ if (defaultAuthenticator == null)
+ return null;
+
+ defaultAuthenticator.host = host;
+ defaultAuthenticator.addr = addr;
+ defaultAuthenticator.port = port;
+ defaultAuthenticator.protocol = protocol;
+ defaultAuthenticator.prompt = prompt;
+ defaultAuthenticator.scheme = scheme;
+
+ return defaultAuthenticator.getPasswordAuthentication();
+ }
+
+ /*
+ * Constructors
+ */
+
+ /**
+ * Default, no-argument constructor for subclasses to call.
+ */
+ public Authenticator()
+ {
+ }
+
+ /*
+ * Instance Methods
+ */
+
+ /**
+ * This method returns the address of the site that is requesting
+ * authentication.
+ *
+ * @return The requesting site's address
+ */
+ protected final InetAddress getRequestingSite()
+ {
+ return addr;
+ }
+
+ /**
+ * Returns the hostname of the host or proxy requesting authorization,
+ * or null
if not available.
+ *
+ * @return The name of the host requesting authentication, or
+ * null
if it is not available.
+ *
+ * @since 1.4
+ */
+ protected final String getRequestingHost()
+ {
+ return host;
+ }
+
+ /**
+ * This method returns the port of the site that is requesting
+ * authentication.
+ *
+ * @return The requesting port
+ */
+ protected final int getRequestingPort()
+ {
+ return port;
+ }
+
+ /**
+ * This method returns the requesting protocol of the operation that is
+ * requesting authentication
+ *
+ * @return The requesting protocol
+ */
+ protected final String getRequestingProtocol()
+ {
+ return protocol;
+ }
+
+ /**
+ * Returns the prompt that should be used when requesting authentication
+ * information from the user
+ *
+ * @return The user prompt
+ */
+ protected final String getRequestingPrompt()
+ {
+ return prompt;
+ }
+
+ /**
+ * This method returns the authentication scheme in use
+ *
+ * @return The authentication scheme
+ */
+ protected final String getRequestingScheme()
+ {
+ return scheme;
+ }
+
+ /**
+ * This method is called whenever a request for authentication is made. It
+ * can call the other getXXX methods to determine the information relevant
+ * to this request. Subclasses should override this method, which returns
+ * null
by default.
+ *
+ * @return The PasswordAuthentication
information
+ */
+ protected PasswordAuthentication getPasswordAuthentication()
+ {
+ return null;
+ }
+} // class Authenticator
diff --git a/libjava/classpath/java/net/BindException.java b/libjava/classpath/java/net/BindException.java
new file mode 100644
index 000000000..cfb509a70
--- /dev/null
+++ b/libjava/classpath/java/net/BindException.java
@@ -0,0 +1,74 @@
+/* BindException.java -- An exception occurred while binding to a socket
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This exception indicates that an error occurred while attempting to bind
+ * socket to a particular port.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class BindException extends SocketException
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -5945005768251722951L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public BindException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message, such as the
+ * text from strerror(3).
+ *
+ * @param message a message describing the error that occurred
+ */
+ public BindException(String message)
+ {
+ super(message);
+ }
+} // class BindException
diff --git a/libjava/classpath/java/net/ConnectException.java b/libjava/classpath/java/net/ConnectException.java
new file mode 100644
index 000000000..c115d2fe0
--- /dev/null
+++ b/libjava/classpath/java/net/ConnectException.java
@@ -0,0 +1,75 @@
+/* ConnectException.java -- An exception occurred while connecting to a host
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This exception indicates that an error occurred while attempting to
+ * connect to a remote host. Often this indicates that the remote host
+ * refused the connection (ie, is not listening on the target socket).
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class ConnectException extends SocketException
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = 3831404271622369215L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public ConnectException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message, such as the
+ * text from strerror(3).
+ *
+ * @param message a message describing the error that occurred
+ */
+ public ConnectException(String message)
+ {
+ super(message);
+ }
+} // class ConnectException
diff --git a/libjava/classpath/java/net/ContentHandler.java b/libjava/classpath/java/net/ContentHandler.java
new file mode 100644
index 000000000..fed8f3de4
--- /dev/null
+++ b/libjava/classpath/java/net/ContentHandler.java
@@ -0,0 +1,126 @@
+/* ContentHandler.java -- Abstract class for handling content from URL's
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This is an abstract class that is the superclass for classes that read
+ * objects from URL's. Calling the getContent()
method in the
+ * URL
class or the URLConnection
class will cause
+ * an instance of a subclass of ContentHandler
to be created for
+ * the MIME type of the object being downloaded from the URL. Thus, this
+ * class is seldom needed by applications/applets directly, but only
+ * indirectly through methods in other classes.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public abstract class ContentHandler
+{
+ /*
+ * Constructors
+ */
+
+ /**
+ * Default, no-argument constructor.
+ */
+ public ContentHandler()
+ {
+ }
+
+ /*
+ * Instance Methods
+ */
+
+ /**
+ * This method reads from the InputStream
of the passed in URL
+ * connection and uses the data downloaded to create an Object
+ * represening the content. For example, if the URL is pointing to a GIF
+ * file, this method might return an Image
object. This method
+ * must be implemented by subclasses.
+ *
+ * @param urlc A URLConnection
object to read data from.
+ *
+ * @return An object representing the data read
+ *
+ * @exception IOException If an error occurs
+ */
+ public abstract Object getContent(URLConnection urlc)
+ throws IOException;
+
+ /**
+ * This method reads from the InputStream
of the passed in URL
+ * connection and uses the data downloaded to create an Object
+ * represening the content. For example, if the URL is pointing to a GIF
+ * file, this method might return an Image
object. This method
+ * must be implemented by subclasses. This method uses the list of
+ * supplied classes as candidate types. If the data read doesn't match
+ * any of the supplied type, null
is returned.
+ *
+ * @param urlc A URLConnection
object to read data from.
+ * @param classes An array of types of objects that are candidate types
+ * for the data to be read.
+ *
+ * @return An object representing the data read, or null
+ * if the data does not match any of the candidate types.
+ *
+ * @exception IOException If an error occurs
+ *
+ * @since 1.3
+ */
+ public Object getContent(URLConnection urlc, Class[] classes)
+ throws IOException
+ {
+ Object obj = getContent(urlc);
+
+ for (int i = 0; i < classes.length; i++)
+ {
+ if (classes[i].isInstance(obj))
+ return obj;
+ }
+
+ return null;
+ }
+} // class ContentHandler
diff --git a/libjava/classpath/java/net/ContentHandlerFactory.java b/libjava/classpath/java/net/ContentHandlerFactory.java
new file mode 100644
index 000000000..51a92cf15
--- /dev/null
+++ b/libjava/classpath/java/net/ContentHandlerFactory.java
@@ -0,0 +1,65 @@
+/* ContentHandlerFactory.java -- Interface for creating content handlers
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+/**
+ * This interface maps MIME types to ContentHandler
objects.
+ * It consists of one method that, when passed a MIME type, returns a
+ * handler for that type.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public interface ContentHandlerFactory
+{
+ /**
+ * This method is passed a MIME type as a string and is responsible for
+ * returning the appropriate ContentHandler
object.
+ *
+ * @param mimeType The MIME type to map to a ContentHandler
+ *
+ * @return The ContentHandler
for the passed in MIME type
+ */
+ ContentHandler createContentHandler(String mimeType);
+} // interface ContentHandlerFactory
diff --git a/libjava/classpath/java/net/DatagramPacket.java b/libjava/classpath/java/net/DatagramPacket.java
new file mode 100644
index 000000000..e642f889c
--- /dev/null
+++ b/libjava/classpath/java/net/DatagramPacket.java
@@ -0,0 +1,391 @@
+/* DatagramPacket.java -- Class to model a packet to be sent via UDP
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This class models a packet of data that is to be sent across the network
+ * using a connectionless protocol such as UDP. It contains the data
+ * to be send, as well as the destination address and port. Note that
+ * datagram packets can arrive in any order and are not guaranteed to be
+ * delivered at all.
+ * DatagramPacket
+ * which has the specified buffer, offset, and length.
+ *
+ * @param buf The buffer for holding the incoming datagram.
+ * @param offset The offset into the buffer to start writing.
+ * @param length The maximum number of bytes to read.
+ *
+ * @since 1.2
+ */
+ public DatagramPacket(byte[] buf, int offset, int length)
+ {
+ setData(buf, offset, length);
+ address = null;
+ port = -1;
+ }
+
+ /**
+ * Initializes a new instance of DatagramPacket
for
+ * receiving packets from the network.
+ *
+ * @param buf A buffer for storing the returned packet data
+ * @param length The length of the buffer (must be <= buf.length)
+ */
+ public DatagramPacket(byte[] buf, int length)
+ {
+ this(buf, 0, length);
+ }
+
+ /**
+ * Initializes a new instance of DatagramPacket
for
+ * transmitting packets across the network.
+ *
+ * @param buf A buffer containing the data to send
+ * @param offset The offset into the buffer to start writing from.
+ * @param length The length of the buffer (must be <= buf.length)
+ * @param address The address to send to
+ * @param port The port to send to
+ *
+ * @since 1.2
+ */
+ public DatagramPacket(byte[] buf, int offset, int length,
+ InetAddress address, int port)
+ {
+ setData(buf, offset, length);
+ setAddress(address);
+ setPort(port);
+ }
+
+ /**
+ * Initializes a new instance of DatagramPacket
for
+ * transmitting packets across the network.
+ *
+ * @param buf A buffer containing the data to send
+ * @param length The length of the buffer (must be <= buf.length)
+ * @param address The address to send to
+ * @param port The port to send to
+ */
+ public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
+ {
+ this(buf, 0, length, address, port);
+ }
+
+ /**
+ * Initializes a new instance of DatagramPacket
for
+ * transmitting packets across the network.
+ *
+ * @param buf A buffer containing the data to send
+ * @param offset The offset into the buffer to start writing from.
+ * @param length The length of the buffer (must be <= buf.length)
+ * @param address The socket address to send to
+ *
+ * @exception SocketException If an error occurs
+ * @exception IllegalArgumentException If address type is not supported
+ *
+ * @since 1.4
+ */
+ public DatagramPacket(byte[] buf, int offset, int length,
+ SocketAddress address) throws SocketException
+ {
+ if (! (address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+
+ InetSocketAddress tmp = (InetSocketAddress) address;
+ setData(buf, offset, length);
+ setAddress(tmp.getAddress());
+ setPort(tmp.getPort());
+ }
+
+ /**
+ * Initializes a new instance of DatagramPacket
for
+ * transmitting packets across the network.
+ *
+ * @param buf A buffer containing the data to send
+ * @param length The length of the buffer (must be <= buf.length)
+ * @param address The socket address to send to
+ *
+ * @exception SocketException If an error occurs
+ * @exception IllegalArgumentException If address type is not supported
+ *
+ * @since 1.4
+ */
+ public DatagramPacket(byte[] buf, int length, SocketAddress address)
+ throws SocketException
+ {
+ this(buf, 0, length, address);
+ }
+
+ /**
+ * Returns the address that this packet is being sent to or, if it was used
+ * to receive a packet, the address that is was received from. If the
+ * constructor that doesn not take an address was used to create this object
+ * and no packet was actually read into this object, then this method
+ * returns null
.
+ *
+ * @return The address for this packet.
+ */
+ public synchronized InetAddress getAddress()
+ {
+ return address;
+ }
+
+ /**
+ * Returns the port number this packet is being sent to or, if it was used
+ * to receive a packet, the port that it was received from. If the
+ * constructor that doesn not take an address was used to create this object
+ * and no packet was actually read into this object, then this method
+ * will return 0.
+ *
+ * @return The port number for this packet
+ */
+ public synchronized int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the data buffer for this packet
+ *
+ * @return This packet's data buffer
+ */
+ public synchronized byte[] getData()
+ {
+ return buffer;
+ }
+
+ /**
+ * This method returns the current offset value into the data buffer
+ * where data will be sent from.
+ *
+ * @return The buffer offset.
+ *
+ * @since 1.2
+ */
+ public synchronized int getOffset()
+ {
+ return offset;
+ }
+
+ /**
+ * Returns the length of the data in the buffer
+ *
+ * @return The length of the data
+ */
+ public synchronized int getLength()
+ {
+ return length;
+ }
+
+ /**
+ * This sets the address to which the data packet will be transmitted.
+ *
+ * @param address The destination address
+ *
+ * @since 1.1
+ */
+ public synchronized void setAddress(InetAddress address)
+ {
+ this.address = address;
+ }
+
+ /**
+ * This sets the port to which the data packet will be transmitted.
+ *
+ * @param port The destination port
+ *
+ * @since 1.1
+ */
+ public synchronized void setPort(int port)
+ {
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Invalid port: " + port);
+
+ this.port = port;
+ }
+
+ /**
+ * Sets the address of the remote host this package will be sent
+ *
+ * @param address The socket address of the remove host
+ *
+ * @exception IllegalArgumentException If address type is not supported
+ *
+ * @since 1.4
+ */
+ public void setSocketAddress(SocketAddress address)
+ throws IllegalArgumentException
+ {
+ if (address == null)
+ throw new IllegalArgumentException("address may not be null");
+
+ InetSocketAddress tmp = (InetSocketAddress) address;
+ this.address = tmp.getAddress();
+ this.port = tmp.getPort();
+ }
+
+ /**
+ * Gets the socket address of the host this packet
+ * will be sent to/is coming from
+ *
+ * @return The socket address of the remote host
+ *
+ * @since 1.4
+ */
+ public SocketAddress getSocketAddress()
+ {
+ return new InetSocketAddress(address, port);
+ }
+
+ /**
+ * Sets the data buffer for this packet.
+ *
+ * @param buf The new buffer for this packet
+ *
+ * @exception NullPointerException If the argument is null
+ *
+ * @since 1.1
+ */
+ public void setData(byte[] buf)
+ {
+ setData(buf, 0, buf.length);
+ }
+
+ /**
+ * This method sets the data buffer for the packet.
+ *
+ * @param buf The byte array containing the data for this packet.
+ * @param offset The offset into the buffer to start reading data from.
+ * @param length The number of bytes of data in the buffer.
+ *
+ * @exception NullPointerException If the argument is null
+ *
+ * @since 1.2
+ */
+ public synchronized void setData(byte[] buf, int offset, int length)
+ {
+ // This form of setData must be used if offset is to be changed.
+ if (buf == null)
+ throw new NullPointerException("Null buffer");
+ if (offset < 0)
+ throw new IllegalArgumentException("Invalid offset: " + offset);
+
+ buffer = buf;
+ this.offset = offset;
+ setLength(length);
+ }
+
+ /**
+ * Sets the length of the data in the buffer.
+ *
+ * @param length The new length. (Where len <= buf.length)
+ *
+ * @exception IllegalArgumentException If the length is negative or
+ * if the length is greater than the packet's data buffer length
+ *
+ * @since 1.1
+ */
+ public synchronized void setLength(int length)
+ {
+ if (length < 0)
+ throw new IllegalArgumentException("Invalid length: " + length);
+ if (offset + length > buffer.length)
+ throw new IllegalArgumentException("Potential buffer overflow - offset: "
+ + offset + " length: " + length);
+
+ this.length = length;
+ this.maxlen = length;
+ }
+}
diff --git a/libjava/classpath/java/net/DatagramSocket.java b/libjava/classpath/java/net/DatagramSocket.java
new file mode 100644
index 000000000..6ca9c42fe
--- /dev/null
+++ b/libjava/classpath/java/net/DatagramSocket.java
@@ -0,0 +1,968 @@
+/* DatagramSocket.java -- A class to model UDP sockets
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.classpath.SystemProperties;
+
+import gnu.java.net.PlainDatagramSocketImpl;
+import gnu.java.nio.DatagramChannelImpl;
+
+import java.io.IOException;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.IllegalBlockingModeException;
+
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+/**
+ * This class models a connectionless datagram socket that sends
+ * individual packets of data across the network. In the TCP/IP world,
+ * this means UDP. Datagram packets do not have guaranteed delivery,
+ * or any guarantee about the order the data will be received on the
+ * remote host.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @date May 3, 1999.
+ */
+public class DatagramSocket
+{
+ /**
+ * This is the user DatagramSocketImplFactory for this class. If this
+ * variable is null, a default factory is used.
+ */
+ private static DatagramSocketImplFactory factory;
+
+ /**
+ * This is the implementation object used by this socket.
+ */
+ private DatagramSocketImpl impl;
+
+ /**
+ * True if socket implementation was created.
+ */
+ private boolean implCreated;
+
+ /**
+ * This is the address we are "connected" to
+ */
+ private InetAddress remoteAddress;
+
+ /**
+ * This is the port we are "connected" to
+ */
+ private int remotePort = -1;
+
+ /**
+ * True if socket is bound.
+ */
+ private boolean bound;
+
+ /**
+ * Creates a DatagramSocket
from a specified
+ * DatagramSocketImpl
instance
+ *
+ * @param impl The DatagramSocketImpl
the socket will be
+ * created from
+ *
+ * @since 1.4
+ */
+ protected DatagramSocket(DatagramSocketImpl impl)
+ {
+ if (impl == null)
+ throw new NullPointerException("impl may not be null");
+
+ this.impl = impl;
+ this.remoteAddress = null;
+ this.remotePort = -1;
+ }
+
+ /**
+ * Initializes a new instance of DatagramSocket
that binds to
+ * a random port and every address on the local machine.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception SecurityException If a security manager exists and
+ * its checkListen
method doesn't allow the operation.
+ */
+ public DatagramSocket() throws SocketException
+ {
+ this(new InetSocketAddress(0));
+ }
+
+ /**
+ * Initializes a new instance of DatagramSocket
that binds to
+ * the specified port and every address on the local machine.
+ *
+ * @param port The local port number to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkListen
method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ */
+ public DatagramSocket(int port) throws SocketException
+ {
+ this(new InetSocketAddress(port));
+ }
+
+ /**
+ * Initializes a new instance of DatagramSocket
that binds to
+ * the specified local port and address.
+ *
+ * @param port The local port number to bind to.
+ * @param addr The local address to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkListen method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ */
+ public DatagramSocket(int port, InetAddress addr) throws SocketException
+ {
+ this(new InetSocketAddress(addr, port));
+ }
+
+ /**
+ * Initializes a new instance of DatagramSocket
that binds to
+ * the specified local port and address.
+ *
+ * @param address The local address and port number to bind to.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkListen
method doesn't allow the operation.
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public DatagramSocket(SocketAddress address) throws SocketException
+ {
+ String propVal = SystemProperties.getProperty("impl.prefix");
+ if (propVal == null || propVal.equals(""))
+ {
+ if (factory != null)
+ impl = factory.createDatagramSocketImpl();
+ else
+ {
+ try
+ {
+ impl = new PlainDatagramSocketImpl();
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+ }
+ else
+ try
+ {
+ impl =
+ (DatagramSocketImpl) Class.forName("java.net." + propVal
+ + "DatagramSocketImpl")
+ .newInstance();
+ }
+ catch (Exception e)
+ {
+ System.err.println("Could not instantiate class: java.net."
+ + propVal + "DatagramSocketImpl");
+ try
+ {
+ impl = new PlainDatagramSocketImpl();
+ }
+ catch (IOException ioe)
+ {
+ SocketException se = new SocketException();
+ se.initCause(ioe);
+ throw se;
+ }
+ }
+
+ if (address != null)
+ bind(address);
+ }
+
+ // This needs to be accessible from java.net.MulticastSocket
+ DatagramSocketImpl getImpl() throws SocketException
+ {
+ try
+ {
+ if (! implCreated)
+ {
+ impl.create();
+ implCreated = true;
+ }
+
+ return impl;
+ }
+ catch (IOException e)
+ {
+ SocketException se = new SocketException();
+ se.initCause(e);
+ throw se;
+ }
+ }
+
+ /**
+ * Closes this datagram socket.
+ */
+ public void close()
+ {
+ if (isClosed())
+ return;
+
+ try
+ {
+ getImpl().close();
+ }
+ catch (SocketException e)
+ {
+ // Ignore this case, just close the socket in finally clause.
+ }
+ finally
+ {
+ remoteAddress = null;
+ remotePort = -1;
+ impl = null;
+ }
+
+ try
+ {
+ if (getChannel() != null)
+ getChannel().close();
+ }
+ catch (IOException e)
+ {
+ // Do nothing.
+ }
+ }
+
+ /**
+ * This method returns the remote address to which this socket is
+ * connected. If this socket is not connected, then this method will
+ * return null
.
+ *
+ * @return The remote address.
+ *
+ * @since 1.2
+ */
+ public InetAddress getInetAddress()
+ {
+ return remoteAddress;
+ }
+
+ /**
+ * This method returns the remote port to which this socket is
+ * connected. If this socket is not connected, then this method will
+ * return -1.
+ *
+ * @return The remote port.
+ *
+ * @since 1.2
+ */
+ public int getPort()
+ {
+ return remotePort;
+ }
+
+ /**
+ * Returns the local address this datagram socket is bound to.
+ *
+ * @return The local address is the socket is bound or null
+ *
+ * @since 1.1
+ */
+ public InetAddress getLocalAddress()
+ {
+ if (! isBound())
+ return null;
+
+ InetAddress localAddr;
+
+ try
+ {
+ localAddr =
+ (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(localAddr.getHostAddress(), -1);
+ }
+ catch (SecurityException e)
+ {
+ localAddr = InetAddress.ANY_IF;
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are bound.
+ return null;
+ }
+
+ return localAddr;
+ }
+
+ /**
+ * Returns the local port this socket is bound to.
+ *
+ * @return The local port number.
+ */
+ public int getLocalPort()
+ {
+ if (isClosed())
+ return -1;
+
+ try
+ {
+ return getImpl().getLocalPort();
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are bound.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the value of the socket's SO_TIMEOUT setting. If this method
+ * returns 0 then SO_TIMEOUT is disabled.
+ *
+ * @return The current timeout in milliseconds.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.1
+ */
+ public synchronized int getSoTimeout() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_TIMEOUT);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the value of the socket's SO_TIMEOUT value. A value of 0 will
+ * disable SO_TIMEOUT. Any other value is the number of milliseconds
+ * a socket read/write will block before timing out.
+ *
+ * @param timeout The new SO_TIMEOUT value in milliseconds.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.1
+ */
+ public synchronized void setSoTimeout(int timeout) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (timeout < 0)
+ throw new IllegalArgumentException("Invalid timeout: " + timeout);
+
+ getImpl().setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
+ }
+
+ /**
+ * This method returns the value of the system level socket option
+ * SO_SNDBUF, which is used by the operating system to tune buffer
+ * sizes for data transfers.
+ *
+ * @return The send buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.2
+ */
+ public int getSendBufferSize() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_SNDBUF);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * This method sets the value for the system level socket option
+ * SO_SNDBUF to the specified value. Note that valid values for this
+ * option are specific to a given operating system.
+ *
+ * @param size The new send buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If size is 0 or negative.
+ *
+ * @since 1.2
+ */
+ public void setSendBufferSize(int size) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (size < 0)
+ throw new IllegalArgumentException("Buffer size is less than 0");
+
+ getImpl().setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
+ }
+
+ /**
+ * This method returns the value of the system level socket option
+ * SO_RCVBUF, which is used by the operating system to tune buffer
+ * sizes for data transfers.
+ *
+ * @return The receive buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.2
+ */
+ public int getReceiveBufferSize() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_RCVBUF);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * This method sets the value for the system level socket option
+ * SO_RCVBUF to the specified value. Note that valid values for this
+ * option are specific to a given operating system.
+ *
+ * @param size The new receive buffer size.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If size is 0 or negative.
+ *
+ * @since 1.2
+ */
+ public void setReceiveBufferSize(int size) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (size < 0)
+ throw new IllegalArgumentException("Buffer size is less than 0");
+
+ getImpl().setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
+ }
+
+ /**
+ * This method connects this socket to the specified address and port.
+ * When a datagram socket is connected, it will only send or receive
+ * packets to and from the host to which it is connected. A multicast
+ * socket that is connected may only send and not receive packets.
+ *
+ * @param address The address to connect this socket to.
+ * @param port The port to connect this socket to.
+ *
+ * @exception IllegalArgumentException If address or port are invalid.
+ * @exception SecurityException If the caller is not allowed to send
+ * datagrams to or receive from this address and port.
+ *
+ * @since 1.2
+ */
+ public void connect(InetAddress address, int port)
+ {
+ if (address == null)
+ throw new IllegalArgumentException("Connect address may not be null");
+
+ if ((port < 1) || (port > 65535))
+ throw new IllegalArgumentException("Port number is illegal: " + port);
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(address.getHostAddress(), port);
+
+ try
+ {
+ getImpl().connect(address, port);
+ remoteAddress = address;
+ remotePort = port;
+ }
+ catch (SocketException e)
+ {
+ // This means simply not connected or connect not implemented.
+ }
+ }
+
+ /**
+ * This method disconnects this socket from the address/port it was
+ * connected to. If the socket was not connected in the first place,
+ * this method does nothing.
+ *
+ * @since 1.2
+ */
+ public void disconnect()
+ {
+ if (! isConnected())
+ return;
+
+ try
+ {
+ getImpl().disconnect();
+ }
+ catch (SocketException e)
+ {
+ // This cannot happen as we are connected.
+ }
+ finally
+ {
+ remoteAddress = null;
+ remotePort = -1;
+ }
+ }
+
+ /**
+ * Reads a datagram packet from the socket. Note that this method
+ * will block until a packet is received from the network. On return,
+ * the passed in DatagramPacket
is populated with the data
+ * received and all the other information about the packet.
+ *
+ * @param p A DatagramPacket
for storing the data
+ *
+ * @exception IOException If an error occurs.
+ * @exception SocketTimeoutException If setSoTimeout was previously called
+ * and the timeout has expired.
+ * @exception PortUnreachableException If the socket is connected to a
+ * currently unreachable destination. Note, there is no guarantee that the
+ * exception will be thrown.
+ * @exception IllegalBlockingModeException If this socket has an associated
+ * channel, and the channel is in non-blocking mode.
+ * @exception SecurityException If a security manager exists and its
+ * checkAccept method doesn't allow the receive.
+ */
+ public synchronized void receive(DatagramPacket p) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (remoteAddress != null && remoteAddress.isMulticastAddress())
+ throw new IOException
+ ("Socket connected to a multicast address my not receive");
+
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ DatagramPacket p2 = new DatagramPacket(p.getData(), p.getOffset(), p.maxlen);
+ getImpl().receive(p2);
+ p.length = p2.length;
+ if (p2.getAddress() != null)
+ p.setAddress(p2.getAddress());
+ if (p2.getPort() != -1)
+ p.setPort(p2.getPort());
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && isConnected())
+ s.checkAccept(p.getAddress().getHostAddress(), p.getPort());
+ }
+
+ /**
+ * Sends the specified packet. The host and port to which the packet
+ * are to be sent should be set inside the packet.
+ *
+ * @param p The datagram packet to send.
+ *
+ * @exception IOException If an error occurs.
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast or checkConnect method doesn't allow the send.
+ * @exception PortUnreachableException If the socket is connected to a
+ * currently unreachable destination. Note, there is no guarantee that the
+ * exception will be thrown.
+ * @exception IllegalBlockingModeException If this socket has an associated
+ * channel, and the channel is in non-blocking mode.
+ */
+ public void send(DatagramPacket p) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ // JDK1.2: Don't do security checks if socket is connected; see jdk1.2 api.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && ! isConnected())
+ {
+ InetAddress addr = p.getAddress();
+ if (addr.isMulticastAddress())
+ s.checkMulticast(addr);
+ else
+ s.checkConnect(addr.getHostAddress(), p.getPort());
+ }
+
+ if (isConnected())
+ {
+ if (p.getAddress() != null
+ && (remoteAddress != p.getAddress() || remotePort != p.getPort()))
+ throw new IllegalArgumentException
+ ("DatagramPacket address does not match remote address");
+ }
+
+ // FIXME: if this is a subclass of MulticastSocket,
+ // use getTimeToLive for TTL val.
+ if (getChannel() != null && ! getChannel().isBlocking()
+ && ! ((DatagramChannelImpl) getChannel()).isInChannelOperation())
+ throw new IllegalBlockingModeException();
+
+ getImpl().send(p);
+ }
+
+ /**
+ * Binds the socket to the given socket address.
+ *
+ * @param address The socket address to bind to.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception SecurityException If a security manager exists and
+ * its checkListen method doesn't allow the operation.
+ * @exception IllegalArgumentException If address type is not supported.
+ *
+ * @since 1.4
+ */
+ public void bind(SocketAddress address) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (address == null)
+ address = new InetSocketAddress(InetAddress.ANY_IF, 0);
+
+ if (! (address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+
+ InetAddress addr = ((InetSocketAddress) address).getAddress();
+ int port = ((InetSocketAddress) address).getPort();
+
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Invalid port: " + port);
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkListen(port);
+
+ if (addr == null)
+ addr = InetAddress.ANY_IF;
+
+ try
+ {
+ getImpl().bind(port, addr);
+ bound = true;
+ }
+ catch (SocketException exception)
+ {
+ getImpl().close();
+ throw exception;
+ }
+ catch (RuntimeException exception)
+ {
+ getImpl().close();
+ throw exception;
+ }
+ catch (Error error)
+ {
+ getImpl().close();
+ throw error;
+ }
+ }
+
+ /**
+ * Checks if the datagram socket is closed.
+ *
+ * @return True if socket is closed, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isClosed()
+ {
+ return impl == null;
+ }
+
+ /**
+ * Returns the datagram channel assoziated with this datagram socket.
+ *
+ * @return The associated DatagramChannel
object or null
+ *
+ * @since 1.4
+ */
+ public DatagramChannel getChannel()
+ {
+ return null;
+ }
+
+ /**
+ * Connects the datagram socket to a specified socket address.
+ *
+ * @param address The socket address to connect to.
+ *
+ * @exception SocketException If an error occurs.
+ * @exception IllegalArgumentException If address type is not supported.
+ *
+ * @since 1.4
+ */
+ public void connect(SocketAddress address) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! (address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+
+ InetSocketAddress tmp = (InetSocketAddress) address;
+ connect(tmp.getAddress(), tmp.getPort());
+ }
+
+ /**
+ * Returns the binding state of the socket.
+ *
+ * @return True if socket bound, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isBound()
+ {
+ return bound;
+ }
+
+ /**
+ * Returns the connection state of the socket.
+ *
+ * @return True if socket is connected, false otherwise.
+ *
+ * @since 1.4
+ */
+ public boolean isConnected()
+ {
+ return remoteAddress != null;
+ }
+
+ /**
+ * Returns the SocketAddress of the host this socket is conneted to
+ * or null if this socket is not connected.
+ *
+ * @return The socket address of the remote host if connected or null
+ *
+ * @since 1.4
+ */
+ public SocketAddress getRemoteSocketAddress()
+ {
+ if (! isConnected())
+ return null;
+
+ return new InetSocketAddress(remoteAddress, remotePort);
+ }
+
+ /**
+ * Returns the local SocketAddress this socket is bound to.
+ *
+ * @return The local SocketAddress or null if the socket is not bound.
+ *
+ * @since 1.4
+ */
+ public SocketAddress getLocalSocketAddress()
+ {
+ if (! isBound())
+ return null;
+
+ return new InetSocketAddress(getLocalAddress(), getLocalPort());
+ }
+
+ /**
+ * Enables/Disables SO_REUSEADDR.
+ *
+ * @param on Whether or not to have SO_REUSEADDR turned on.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public void setReuseAddress(boolean on) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+ }
+
+ /**
+ * Checks if SO_REUSEADDR is enabled.
+ *
+ * @return True if SO_REUSEADDR is set on the socket, false otherwise.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public boolean getReuseAddress() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_REUSEADDR);
+
+ if (buf instanceof Boolean)
+ return ((Boolean) buf).booleanValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Enables/Disables SO_BROADCAST
+ *
+ * @param enable True if SO_BROADCAST should be enabled, false otherwise.
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public void setBroadcast(boolean enable) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(enable));
+ }
+
+ /**
+ * Checks if SO_BROADCAST is enabled
+ *
+ * @return Whether SO_BROADCAST is set
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public boolean getBroadcast() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.SO_BROADCAST);
+
+ if (buf instanceof Boolean)
+ return ((Boolean) buf).booleanValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the traffic class value
+ *
+ * @param tc The traffic class
+ *
+ * @exception SocketException If an error occurs
+ * @exception IllegalArgumentException If tc value is illegal
+ *
+ * @see DatagramSocket#getTrafficClass()
+ *
+ * @since 1.4
+ */
+ public void setTrafficClass(int tc) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (tc < 0 || tc > 255)
+ throw new IllegalArgumentException();
+
+ getImpl().setOption(SocketOptions.IP_TOS, Integer.valueOf(tc));
+ }
+
+ /**
+ * Returns the current traffic class
+ *
+ * @return The current traffic class.
+ *
+ * @see DatagramSocket#setTrafficClass(int tc)
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public int getTrafficClass() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.IP_TOS);
+
+ if (buf instanceof Integer)
+ return ((Integer) buf).intValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the datagram socket implementation factory for the application
+ *
+ * @param fac The factory to set
+ *
+ * @exception IOException If an error occurs
+ * @exception SocketException If the factory is already defined
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ */
+ public static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
+ throws IOException
+ {
+ if (factory != null)
+ throw new SocketException("DatagramSocketImplFactory already defined");
+
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkSetFactory();
+
+ factory = fac;
+ }
+}
diff --git a/libjava/classpath/java/net/DatagramSocketImpl.java b/libjava/classpath/java/net/DatagramSocketImpl.java
new file mode 100644
index 000000000..4f51f9f93
--- /dev/null
+++ b/libjava/classpath/java/net/DatagramSocketImpl.java
@@ -0,0 +1,296 @@
+/* DatagramSocketImpl.java -- Abstract class for UDP socket implementations
+ Copyright (C) 1998, 1999 2000, 2001,
+ 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+
+/**
+ * This abstract class models a datagram socket implementation. An
+ * actual implementation class would implement these methods, probably
+ * via redirecting them to native code.
+ * InetAddress
to fill in with the information
+ * about the sender if the next packet
+ *
+ * @return The port number of the sender of the packet
+ *
+ * @exception IOException If an error occurs
+ * @exception PortUnreachableException May be thrown if the socket is
+ * connected to a currently unreachable destination. Note, there is no
+ * guarantee that the exception will be thrown.
+ */
+ protected abstract int peek(InetAddress i) throws IOException;
+
+ /**
+ * Takes a peek at the next packet received. This packet is not consumed.
+ * With the next peekData/receive operation this packet will be read again.
+ *
+ * @param p The DatagramPacket
to fill in with the data sent.
+ *
+ * @return The port number of the sender of the packet.
+ *
+ * @exception IOException If an error occurs
+ * @exception PortUnreachableException May be thrown if the socket is
+ * connected to a currently unreachable destination. Note, there is no
+ * guarantee that the exception will be thrown.
+ *
+ * @since 1.4
+ */
+ protected abstract int peekData(DatagramPacket p) throws IOException;
+
+ /**
+ * Transmits the specified packet of data to the network. The destination
+ * host and port should be encoded in the packet.
+ *
+ * @param p The packet to send
+ *
+ * @exception IOException If an error occurs
+ * @exception PortUnreachableException May be thrown if the socket is
+ * connected to a currently unreachable destination. Note, there is no
+ * guarantee that the exception will be thrown.
+ */
+ protected abstract void send(DatagramPacket p) throws IOException;
+
+ /**
+ * Receives a packet of data from the network Will block until a packet
+ * arrives. The packet info in populated into the passed in
+ * DatagramPacket
object.
+ *
+ * @param p A place to store the incoming packet.
+ *
+ * @exception IOException If an error occurs
+ * @exception PortUnreachableException May be thrown if the socket is
+ * connected to a currently unreachable destination. Note, there is no
+ * guarantee that the exception will be thrown.
+ */
+ protected abstract void receive(DatagramPacket p) throws IOException;
+
+ /**
+ * Connects the socket to a host specified by address and port.
+ *
+ * @param address The InetAddress
of the host to connect to
+ * @param port The port number of the host to connect to
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ protected void connect(InetAddress address, int port)
+ throws SocketException
+ {
+ // This method has to be overwritten by real implementations
+ }
+
+ /**
+ * Disconnects the socket.
+ *
+ * @since 1.4
+ */
+ protected void disconnect()
+ {
+ // This method has to be overwritten by real implementations
+ }
+
+ /**
+ * Sets the Time to Live (TTL) setting on this socket to the specified
+ * value. Use setTimeToLive(int)
instead.
+ *
+ * @param ttl The new Time to Live value
+ *
+ * @exception IOException If an error occurs
+ * @deprecated
+ */
+ protected abstract void setTTL(byte ttl) throws IOException;
+
+ /**
+ * This method returns the current Time to Live (TTL) setting on this
+ * socket. Use getTimeToLive()
instead.
+ *
+ * @return the current time-to-live
+ *
+ * @exception IOException If an error occurs
+ *
+ * @deprecated // FIXME: when ?
+ */
+ protected abstract byte getTTL() throws IOException;
+
+ /**
+ * Sets the Time to Live (TTL) setting on this socket to the specified
+ * value.
+ *
+ * @param ttl The new Time to Live value
+ *
+ * @exception IOException If an error occurs
+ */
+ protected abstract void setTimeToLive(int ttl) throws IOException;
+
+ /**
+ * This method returns the current Time to Live (TTL) setting on this
+ * socket.
+ *
+ * @return the current time-to-live
+ *
+ * @exception IOException If an error occurs
+ */
+ protected abstract int getTimeToLive() throws IOException;
+
+ /**
+ * Causes this socket to join the specified multicast group
+ *
+ * @param inetaddr The multicast address to join with
+ *
+ * @exception IOException If an error occurs
+ */
+ protected abstract void join(InetAddress inetaddr) throws IOException;
+
+ /**
+ * Causes the socket to leave the specified multicast group.
+ *
+ * @param inetaddr The multicast address to leave
+ *
+ * @exception IOException If an error occurs
+ */
+ protected abstract void leave(InetAddress inetaddr) throws IOException;
+
+ /**
+ * Causes this socket to join the specified multicast group on a specified
+ * device
+ *
+ * @param mcastaddr The address to leave
+ * @param netIf The specified network interface to join the group at
+ *
+ * @exception IOException If an error occurs
+ *
+ * @since 1.4
+ */
+ protected abstract void joinGroup(SocketAddress mcastaddr,
+ NetworkInterface netIf)
+ throws IOException;
+
+ /**
+ * Leaves a multicast group
+ *
+ * @param mcastaddr The address to join
+ * @param netIf The specified network interface to leave the group at
+ *
+ * @exception IOException If an error occurs
+ *
+ * @since 1.4
+ */
+ protected abstract void leaveGroup(SocketAddress mcastaddr,
+ NetworkInterface netIf)
+ throws IOException;
+
+ /**
+ * Returns the FileDescriptor for this socket
+ *
+ * @return the file descriptor associated with this socket
+ */
+ protected FileDescriptor getFileDescriptor()
+ {
+ return fd;
+ }
+
+ /**
+ * Returns the local port this socket is bound to
+ *
+ * @return the local port
+ */
+ protected int getLocalPort()
+ {
+ return localPort;
+ }
+}
diff --git a/libjava/classpath/java/net/DatagramSocketImplFactory.java b/libjava/classpath/java/net/DatagramSocketImplFactory.java
new file mode 100644
index 000000000..014651aa8
--- /dev/null
+++ b/libjava/classpath/java/net/DatagramSocketImplFactory.java
@@ -0,0 +1,60 @@
+/* DatagramSocketImplFactory.java --
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/** Written using on-line Java Platform 1.4 API Specification.
+ * Status: Believed complete and correct.
+ */
+/**
+ * This interface defines one method which returns a
+ * DatagramSocketImpl
object.
+ * This should not be needed by ordinary applications.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.3
+ */
+public interface DatagramSocketImplFactory
+{
+ /**
+ * This method returns an instance of the DatagramSocketImpl object
+ *
+ * @return A DatagramSocketImpl object
+ */
+ DatagramSocketImpl createDatagramSocketImpl();
+} // interface DatagramSocketImplFactory
diff --git a/libjava/classpath/java/net/FileNameMap.java b/libjava/classpath/java/net/FileNameMap.java
new file mode 100644
index 000000000..6f1d25a6a
--- /dev/null
+++ b/libjava/classpath/java/net/FileNameMap.java
@@ -0,0 +1,65 @@
+/* FileNameMap.java -- Maps filenames to MIME types
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+/**
+ * This interface has one method which, when passed a filename, returns
+ * the MIME type associated with that filename.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ */
+public interface FileNameMap
+{
+ /**
+ * This method is passed a filename and is responsible for determining
+ * the appropriate MIME type for that file.
+ *
+ * @param filename The name of the file to generate a MIME type for.
+ *
+ * @return The MIME type for the filename passed in.
+ */
+ String getContentTypeFor(String filename);
+} // interface FileNameMap
diff --git a/libjava/classpath/java/net/HttpURLConnection.java b/libjava/classpath/java/net/HttpURLConnection.java
new file mode 100644
index 000000000..72dd67d91
--- /dev/null
+++ b/libjava/classpath/java/net/HttpURLConnection.java
@@ -0,0 +1,589 @@
+/* HttpURLConnection.java -- Subclass of communications links using
+ Hypertext Transfer Protocol.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.security.Permission;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This class provides a common abstract implementation for those
+ * URL connection classes that will connect using the HTTP protocol.
+ * In addition to the functionality provided by the URLConnection
+ * class, it defines constants for HTTP return code values and
+ * methods for setting the HTTP request method and determining whether
+ * or not to follow redirects.
+ *
+ * @since 1.1
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public abstract class HttpURLConnection extends URLConnection
+{
+ /* HTTP Success Response Codes */
+
+ /**
+ * Indicates that the client may continue with its request. This value
+ * is specified as part of RFC 2068 but was not included in Sun's JDK, so
+ * beware of using this value
+ */
+ static final int HTTP_CONTINUE = 100;
+
+ /**
+ * Indicates the request succeeded.
+ */
+ public static final int HTTP_OK = 200;
+
+ /**
+ * The requested resource has been created.
+ */
+ public static final int HTTP_CREATED = 201;
+
+ /**
+ * The request has been accepted for processing but has not completed.
+ * There is no guarantee that the requested action will actually ever
+ * be completed succesfully, but everything is ok so far.
+ */
+ public static final int HTTP_ACCEPTED = 202;
+
+ /**
+ * The meta-information returned in the header is not the actual data
+ * from the original server, but may be from a local or other copy.
+ * Normally this still indicates a successful completion.
+ */
+ public static final int HTTP_NOT_AUTHORITATIVE = 203;
+
+ /**
+ * The server performed the request, but there is no data to send
+ * back. This indicates that the user's display should not be changed.
+ */
+ public static final int HTTP_NO_CONTENT = 204;
+
+ /**
+ * The server performed the request, but there is no data to sent back,
+ * however, the user's display should be "reset" to clear out any form
+ * fields entered.
+ */
+ public static final int HTTP_RESET = 205;
+
+ /**
+ * The server completed the partial GET request for the resource.
+ */
+ public static final int HTTP_PARTIAL = 206;
+
+ /* HTTP Redirection Response Codes */
+
+ /**
+ * There is a list of choices available for the requested resource.
+ */
+ public static final int HTTP_MULT_CHOICE = 300;
+
+ /**
+ * The resource has been permanently moved to a new location.
+ */
+ public static final int HTTP_MOVED_PERM = 301;
+
+ /**
+ * The resource requested has been temporarily moved to a new location.
+ */
+ public static final int HTTP_MOVED_TEMP = 302;
+
+ /**
+ * The response to the request issued is available at another location.
+ */
+ public static final int HTTP_SEE_OTHER = 303;
+
+ /**
+ * The document has not been modified since the criteria specified in
+ * a conditional GET.
+ */
+ public static final int HTTP_NOT_MODIFIED = 304;
+
+ /**
+ * The requested resource needs to be accessed through a proxy.
+ */
+ public static final int HTTP_USE_PROXY = 305;
+
+ /* HTTP Client Error Response Codes */
+
+ /**
+ * The request was misformed or could not be understood.
+ */
+ public static final int HTTP_BAD_REQUEST = 400;
+
+ /**
+ * The request made requires user authorization. Try again with
+ * a correct authentication header.
+ */
+ public static final int HTTP_UNAUTHORIZED = 401;
+
+ /**
+ * Code reserved for future use - I hope way in the future.
+ */
+ public static final int HTTP_PAYMENT_REQUIRED = 402;
+
+ /**
+ * There is no permission to access the requested resource.
+ */
+ public static final int HTTP_FORBIDDEN = 403;
+
+ /**
+ * The requested resource was not found.
+ */
+ public static final int HTTP_NOT_FOUND = 404;
+
+ /**
+ * The specified request method is not allowed for this resource.
+ */
+ public static final int HTTP_BAD_METHOD = 405;
+
+ /**
+ * Based on the input headers sent, the resource returned in response
+ * to the request would not be acceptable to the client.
+ */
+ public static final int HTTP_NOT_ACCEPTABLE = 406;
+
+ /**
+ * The client must authenticate with a proxy prior to attempting this
+ * request.
+ */
+ public static final int HTTP_PROXY_AUTH = 407;
+
+ /**
+ * The request timed out.
+ */
+ public static final int HTTP_CLIENT_TIMEOUT = 408;
+
+ /**
+ * There is a conflict between the current state of the resource and the
+ * requested action.
+ */
+ public static final int HTTP_CONFLICT = 409;
+
+ /**
+ * The requested resource is no longer available. This ususally indicates
+ * a permanent condition.
+ */
+ public static final int HTTP_GONE = 410;
+
+ /**
+ * A Content-Length header is required for this request, but was not
+ * supplied.
+ */
+ public static final int HTTP_LENGTH_REQUIRED = 411;
+
+ /**
+ * A client specified pre-condition was not met on the server.
+ */
+ public static final int HTTP_PRECON_FAILED = 412;
+
+ /**
+ * The request sent was too large for the server to handle.
+ */
+ public static final int HTTP_ENTITY_TOO_LARGE = 413;
+
+ /**
+ * The name of the resource specified was too long.
+ */
+ public static final int HTTP_REQ_TOO_LONG = 414;
+
+ /**
+ * The request is in a format not supported by the requested resource.
+ */
+ public static final int HTTP_UNSUPPORTED_TYPE = 415;
+
+ /* HTTP Server Error Response Codes */
+
+ /**
+ * This error code indicates that some sort of server error occurred.
+ *
+ * @deprecated
+ */
+ public static final int HTTP_SERVER_ERROR = 500;
+
+ /**
+ * The server encountered an unexpected error (such as a CGI script crash)
+ * that prevents the request from being fulfilled.
+ */
+ public static final int HTTP_INTERNAL_ERROR = 500;
+
+ /**
+ * The server does not support the requested functionality.
+ * @since 1.3
+ */
+ public static final int HTTP_NOT_IMPLEMENTED = 501;
+
+ /**
+ * The proxy encountered a bad response from the server it was proxy-ing for
+ */
+ public static final int HTTP_BAD_GATEWAY = 502;
+
+ /**
+ * The HTTP service is not availalble, such as because it is overloaded
+ * and does not want additional requests.
+ */
+ public static final int HTTP_UNAVAILABLE = 503;
+
+ /**
+ * The proxy timed out getting a reply from the remote server it was
+ * proxy-ing for.
+ */
+ public static final int HTTP_GATEWAY_TIMEOUT = 504;
+
+ /**
+ * This server does not support the protocol version requested.
+ */
+ public static final int HTTP_VERSION = 505;
+
+ // Non-HTTP response static variables
+
+ /**
+ * Flag to indicate whether or not redirects should be automatically
+ * followed by default.
+ */
+ private static boolean followRedirects = true;
+
+ /**
+ * This is a list of valid request methods, separated by "|" characters.
+ */
+ private static final String valid_methods =
+ "|GET|POST|HEAD|OPTIONS|PUT|DELETE|TRACE|";
+
+ // Instance Variables
+
+ /**
+ * The requested method in use for this connection. Default is GET.
+ */
+ protected String method = "GET";
+
+ /**
+ * The response code received from the server
+ */
+ protected int responseCode = -1;
+
+ /**
+ * The response message string received from the server.
+ */
+ protected String responseMessage;
+
+ /**
+ * If this instance should follow redirect requests.
+ */
+ protected boolean instanceFollowRedirects = followRedirects;
+
+ /**
+ * Whether we already got a valid response code for this connection.
+ * Used by getResponseCode()
and
+ * getResponseMessage()
.
+ */
+ private boolean gotResponseVals;
+
+ /**
+ * Create an HttpURLConnection for the specified URL
+ *
+ * @param url The URL to create this connection for.
+ */
+ protected HttpURLConnection(URL url)
+ {
+ super(url);
+ }
+
+ /**
+ * Closes the connection to the server.
+ */
+ public abstract void disconnect();
+
+ /**
+ * Returns a boolean indicating whether or not this connection is going
+ * through a proxy
+ *
+ * @return true if through a proxy, false otherwise
+ */
+ public abstract boolean usingProxy();
+
+ /**
+ * Sets whether HTTP redirects (requests with response code 3xx) should be
+ * automatically followed by this class. True by default
+ *
+ * @param set true if redirects should be followed, false otherwis.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ */
+ public static void setFollowRedirects(boolean set)
+ {
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+
+ followRedirects = set;
+ }
+
+ /**
+ * Returns a boolean indicating whether or not HTTP redirects will
+ * automatically be followed or not.
+ *
+ * @return true if redirects will be followed, false otherwise
+ */
+ public static boolean getFollowRedirects()
+ {
+ return followRedirects;
+ }
+
+ /**
+ * Returns the value of this HttpURLConnection's instanceFollowRedirects
+ * field
+ *
+ * @return true if following redirects is enabled, false otherwise
+ */
+ public boolean getInstanceFollowRedirects()
+ {
+ return instanceFollowRedirects;
+ }
+
+ /**
+ * Sets the value of this HttpURLConnection's instanceFollowRedirects field
+ *
+ * @param follow true to enable following redirects, false otherwise
+ */
+ public void setInstanceFollowRedirects(boolean follow)
+ {
+ instanceFollowRedirects = follow;
+ }
+
+ /**
+ * Set the method for the URL request, one of:
+ * GET POST HEAD OPTIONS PUT DELETE TRACE are legal
+ *
+ * @param method the method to use
+ *
+ * @exception ProtocolException If the method cannot be reset or if the
+ * requested method isn't valid for HTTP
+ */
+ public void setRequestMethod(String method) throws ProtocolException
+ {
+ if (connected)
+ throw new ProtocolException("Already connected");
+
+ method = method.toUpperCase();
+ if (valid_methods.indexOf("|" + method + "|") != -1)
+ this.method = method;
+ else
+ throw new ProtocolException("Invalid HTTP request method: " + method);
+ }
+
+ /**
+ * The request method currently in use for this connection.
+ *
+ * @return The request method
+ */
+ public String getRequestMethod()
+ {
+ return method;
+ }
+
+ /**
+ * Gets the status code from an HTTP response message, or -1 if
+ * the response code could not be determined.
+ * Note that all valid response codes have class variables
+ * defined for them in this class.
+ *
+ * @return The response code
+ *
+ * @exception IOException If an error occurs
+ */
+ public int getResponseCode() throws IOException
+ {
+ if (! gotResponseVals)
+ getResponseVals();
+ return responseCode;
+ }
+
+ /**
+ * Gets the HTTP response message, if any, returned along with the
+ * response code from a server. Null if no response message was set
+ * or an error occured while connecting.
+ *
+ * @return The response message
+ *
+ * @exception IOException If an error occurs
+ */
+ public String getResponseMessage() throws IOException
+ {
+ if (! gotResponseVals)
+ getResponseVals();
+ return responseMessage;
+ }
+
+ private void getResponseVals() throws IOException
+ {
+ // getHeaderField() will connect for us, but do it here first in
+ // order to pick up IOExceptions.
+ if (! connected)
+ connect();
+
+ gotResponseVals = true;
+
+ // If responseCode not yet explicitly set by subclass
+ if (responseCode == -1)
+ {
+ // Response is the first header received from the connection.
+ String respField = getHeaderField(0);
+
+ if (respField == null || ! respField.startsWith("HTTP/"))
+ {
+ // Set to default values on failure.
+ responseCode = -1;
+ responseMessage = null;
+ return;
+ }
+
+ int firstSpc;
+ int nextSpc;
+ firstSpc = respField.indexOf(' ');
+ nextSpc = respField.indexOf(' ', firstSpc + 1);
+ responseMessage = respField.substring(nextSpc + 1);
+ String codeStr = respField.substring(firstSpc + 1, nextSpc);
+ try
+ {
+ responseCode = Integer.parseInt(codeStr);
+ }
+ catch (NumberFormatException e)
+ {
+ // Set to default values on failure.
+ responseCode = -1;
+ responseMessage = null;
+ }
+ }
+ }
+
+ /**
+ * Returns a permission object representing the permission necessary to make
+ * the connection represented by this object
+ *
+ * @return the permission necessary for this connection
+ *
+ * @exception IOException If an error occurs
+ */
+ public Permission getPermission() throws IOException
+ {
+ URL url = getURL();
+ String host = url.getHost();
+ int port = url.getPort();
+ if (port == -1)
+ port = 80;
+
+ host = host + ":" + port;
+
+ return new SocketPermission(host, "connect");
+ }
+
+ /**
+ * This method allows the caller to retrieve any data that might have
+ * been sent despite the fact that an error occurred. For example, the
+ * HTML page sent along with a 404 File Not Found error. If the socket
+ * is not connected, or if no error occurred or no data was returned,
+ * this method returns null
.
+ *
+ * @return An InputStream
for reading error data.
+ */
+ public InputStream getErrorStream()
+ {
+ if (! connected)
+ return null;
+
+ int code;
+ try
+ {
+ code = getResponseCode();
+ }
+ catch (IOException e)
+ {
+ code = -1;
+ }
+
+ if (code == -1)
+ return null;
+
+ if (((code / 100) != 4) || ((code / 100) != 5))
+ return null;
+
+ try
+ {
+ PushbackInputStream pbis = new PushbackInputStream(getInputStream());
+
+ int i = pbis.read();
+ if (i == -1)
+ return null;
+
+ pbis.unread(i);
+ return pbis;
+ }
+ catch (IOException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the value of the named field parsed as date
+ *
+ * @param key the key of the header field
+ * @param value the default value if the header field is not present
+ *
+ * @return the value of the header field
+ */
+ public long getHeaderFieldDate(String key, long value)
+ {
+ // FIXME: implement this correctly
+ // http://www.w3.org/Protocols/HTTP-NG/ng-notes.txt
+ return super.getHeaderFieldDate(key, value);
+ }
+}
diff --git a/libjava/classpath/java/net/Inet4Address.java b/libjava/classpath/java/net/Inet4Address.java
new file mode 100644
index 000000000..e3cff7b13
--- /dev/null
+++ b/libjava/classpath/java/net/Inet4Address.java
@@ -0,0 +1,273 @@
+/* Inet4Address.java --
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.io.ObjectStreamException;
+
+/*
+ * Written using on-line Java Platform 1.4 API Specification and
+ * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt),
+ * RFC 1918 (http://www.ietf.org/rfc/rfc1918.txt),
+ * RFC 2365 (http://www.ietf.org/rfc/rfc2365.txt)
+ *
+ * @author Michael Koch
+ * @status Believed complete and correct.
+ */
+public final class Inet4Address extends InetAddress
+{
+ /**
+ * For compatability with Sun's JDK 1.4.2 rev. 5
+ */
+ static final long serialVersionUID = 3286316764910316507L;
+
+ /**
+ * The address family of these addresses (used for serialization).
+ */
+ private static final int AF_INET = 2;
+
+ /**
+ * Inet4Address objects are serialized as InetAddress objects.
+ */
+ private Object writeReplace() throws ObjectStreamException
+ {
+ return new InetAddress(addr, hostName, AF_INET);
+ }
+
+ /**
+ * Initializes this object's addr instance variable from the passed in
+ * byte array. Note that this constructor is protected and is called
+ * only by static methods in this class.
+ *
+ * @param addr The IP number of this address as an array of bytes
+ * @param host The hostname of this IP address.
+ */
+ Inet4Address(byte[] addr, String host)
+ {
+ super(addr, host, AF_INET);
+ }
+
+ /**
+ * Checks if the address is a multicast address
+ *
+ * @since 1.1
+ */
+ public boolean isMulticastAddress()
+ {
+ return (addr[0] & 0xf0) == 0xe0;
+ }
+
+ /**
+ * Checks if this address is a loopback address
+ */
+ public boolean isLoopbackAddress()
+ {
+ return (addr[0] & 0xff) == 0x7f;
+ }
+
+ /**
+ * Checks if this address is a wildcard address
+ *
+ * @since 1.4
+ */
+ public boolean isAnyLocalAddress()
+ {
+ return equals(InetAddress.ANY_IF);
+ }
+
+ /**
+ * Checks if this address is a link local address
+ *
+ * @since 1.4
+ */
+ public boolean isLinkLocalAddress()
+ {
+ return false;
+ }
+
+ /**
+ * Checks if this address is a site local address
+ *
+ * @since 1.4
+ */
+ public boolean isSiteLocalAddress()
+ {
+ // 10.0.0.0/8
+ if ((addr[0] & 0xff) == 0x0a)
+ return true;
+
+ // 172.16.0.0/12
+ if ((addr[0] & 0xff) == 0xac && (addr[1] & 0xf0) == 0x10)
+ return true;
+
+ // 192.168.0.0/16
+ if ((addr[0] & 0xff) == 0xc0 && (addr[1] & 0xff) == 0xa8)
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has global scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCGlobal()
+ {
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has node scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCNodeLocal()
+ {
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has link scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCLinkLocal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return ((addr[0] & 0xff) == 0xe0
+ && (addr[1] & 0xff) == 0x00
+ && (addr[2] & 0xff) == 0x00);
+ }
+
+ /**
+ * Checks if this multicast address has site scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCSiteLocal()
+ {
+ return false;
+ }
+
+ /**
+ * Checks if this multicast address has organization scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCOrgLocal()
+ {
+ return false;
+ }
+
+ /**
+ * Returns the address of the current instance
+ */
+ public byte[] getAddress()
+ {
+ return (byte[]) addr.clone();
+ }
+
+ /**
+ * Returns the address as string
+ *
+ * @since 1.0.2
+ */
+ public String getHostAddress()
+ {
+ CPStringBuilder sb = new CPStringBuilder(40);
+
+ int len = addr.length;
+ int i = 0;
+
+ for ( ; ; )
+ {
+ sb.append(addr[i] & 0xff);
+ i++;
+
+ if (i == len)
+ break;
+
+ sb.append('.');
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Computes the hashcode of the instance
+ */
+ public int hashCode()
+ {
+ int hash = 0;
+ int len = addr.length;
+ int i = len > 4 ? len - 4 : 0;
+
+ for (; i < len; i++)
+ hash = (hash << 8) | (addr[i] & 0xFF);
+
+ return hash;
+ }
+
+ /**
+ * Compare the current Inet4Address instance with obj
+ *
+ * @param obj Object to compare with
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof InetAddress))
+ return false;
+
+ byte[] addr1 = addr;
+ byte[] addr2 = ((InetAddress) obj).addr;
+
+ if (addr1.length != addr2.length)
+ return false;
+
+ for (int i = addr1.length; --i >= 0;)
+ if (addr1[i] != addr2[i])
+ return false;
+
+ return true;
+ }
+}
diff --git a/libjava/classpath/java/net/Inet6Address.java b/libjava/classpath/java/net/Inet6Address.java
new file mode 100644
index 000000000..60c406587
--- /dev/null
+++ b/libjava/classpath/java/net/Inet6Address.java
@@ -0,0 +1,429 @@
+/* Inet6Address.java --
+ Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.util.Arrays;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+
+/*
+ * Written using on-line Java Platform 1.4 API Specification and
+ * RFC 1884 (http://www.ietf.org/rfc/rfc1884.txt)
+ *
+ * @author Michael Koch
+ * @status Updated to 1.5. Serialization compatibility is tested.
+ */
+public final class Inet6Address extends InetAddress
+{
+ static final long serialVersionUID = 6880410070516793377L;
+
+ /**
+ * Needed for serialization
+ */
+ byte[] ipaddress;
+
+ /**
+ * The scope ID, if any.
+ * @since 1.5
+ * @serial
+ */
+ private int scope_id;
+
+ /**
+ * The scope ID, if any.
+ * @since 1.5
+ * @serial
+ */
+ private boolean scope_id_set;
+
+ /**
+ * Whether ifname is set or not.
+ * @since 1.5
+ * @serial
+ */
+ private boolean scope_ifname_set;
+
+ /**
+ * Name of the network interface, used only by the serialization methods
+ * @since 1.5
+ * @serial
+ */
+ private String ifname;
+
+ /**
+ * Scope network interface, or null
.
+ */
+ private transient NetworkInterface nif;
+
+ /**
+ * The address family of these addresses (used for serialization).
+ */
+ private static final int AF_INET6 = 10;
+
+ /**
+ * Create an Inet6Address object
+ *
+ * @param addr The IP address
+ * @param host The hostname
+ */
+ Inet6Address(byte[] addr, String host)
+ {
+ super(addr, host, AF_INET6);
+ // Super constructor clones the addr. Get a reference to the clone.
+ this.ipaddress = this.addr;
+ ifname = null;
+ scope_ifname_set = scope_id_set = false;
+ scope_id = 0;
+ nif = null;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an IP multicast address
+ *
+ * @since 1.1
+ */
+ public boolean isMulticastAddress()
+ {
+ return ipaddress[0] == (byte) 0xFF;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress in a wildcard address
+ *
+ * @since 1.4
+ */
+ public boolean isAnyLocalAddress()
+ {
+ byte[] anylocal = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ return Arrays.equals(ipaddress, anylocal);
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is a loopback address
+ *
+ * @since 1.4
+ */
+ public boolean isLoopbackAddress()
+ {
+ byte[] loopback = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+ return Arrays.equals(ipaddress, loopback);
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an link local address
+ *
+ * @since 1.4
+ */
+ public boolean isLinkLocalAddress()
+ {
+ return ipaddress[0] == 0xFA;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is a site local address
+ *
+ * @since 1.4
+ */
+ public boolean isSiteLocalAddress()
+ {
+ return ipaddress[0] == 0xFB;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has global scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCGlobal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return (ipaddress[1] & 0x0F) == 0xE;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has node scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCNodeLocal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return (ipaddress[1] & 0x0F) == 0x1;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has link scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCLinkLocal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return (ipaddress[1] & 0x0F) == 0x2;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has site scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCSiteLocal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return (ipaddress[1] & 0x0F) == 0x5;
+ }
+
+ /**
+ * Utility routine to check if the multicast address has organization scope
+ *
+ * @since 1.4
+ */
+ public boolean isMCOrgLocal()
+ {
+ if (! isMulticastAddress())
+ return false;
+
+ return (ipaddress[1] & 0x0F) == 0x8;
+ }
+
+ /**
+ * Returns the raw IP address of this InetAddress object. The result is in
+ * network byte order: the highest order byte of the address is i
+ * n getAddress()[0]
+ */
+ public byte[] getAddress()
+ {
+ return (byte[]) ipaddress.clone();
+ }
+
+ /**
+ * Creates a scoped Inet6Address where the scope has an integer id.
+ *
+ * @throws UnkownHostException if the address is an invalid number of bytes.
+ * @since 1.5
+ */
+ public static Inet6Address getByAddress(String host, byte[] addr,
+ int scopeId)
+ throws UnknownHostException
+ {
+ if( addr.length != 16 )
+ throw new UnknownHostException("Illegal address length: " + addr.length
+ + " bytes.");
+ Inet6Address ip = new Inet6Address( addr, host );
+ ip.scope_id = scopeId;
+ ip.scope_id_set = true;
+ return ip;
+ }
+
+ /**
+ * Creates a scoped Inet6Address where the scope is a given
+ * NetworkInterface.
+ *
+ * @throws UnkownHostException if the address is an invalid number of bytes.
+ * @since 1.5
+ */
+ public static Inet6Address getByAddress(String host, byte[] addr,
+ NetworkInterface nif)
+ throws UnknownHostException
+ {
+ if( addr.length != 16 )
+ throw new UnknownHostException("Illegal address length: " + addr.length
+ + " bytes.");
+ Inet6Address ip = new Inet6Address( addr, host );
+ ip.nif = nif;
+
+ return ip;
+ }
+
+ /**
+ * Returns the NetworkInterface
of the address scope
+ * if it is a scoped address and the scope is given in the form of a
+ * NetworkInterface.
+ * (I.e. the address was created using the
+ * getByAddress(String, byte[], NetworkInterface) method)
+ * Otherwise this method returns null
.
+ * @since 1.5
+ */
+ public NetworkInterface getScopedInterface()
+ {
+ return nif;
+ }
+
+ /**
+ * Returns the scope ID of the address scope if it is a scoped adress using
+ * an integer to identify the scope.
+ *
+ * Otherwise this method returns 0.
+ * @since 1.5
+ */
+ public int getScopeId()
+ {
+ // check scope_id_set because some JDK-serialized objects seem to have
+ // scope_id set to a nonzero value even when scope_id_set == false
+ if( scope_id_set )
+ return scope_id;
+ return 0;
+ }
+
+ /**
+ * Returns the IP address string in textual presentation
+ */
+ public String getHostAddress()
+ {
+ CPStringBuilder sbuf = new CPStringBuilder(40);
+
+ for (int i = 0; i < 16; i += 2)
+ {
+ int x = ((ipaddress[i] & 0xFF) << 8) | (ipaddress[i + 1] & 0xFF);
+
+ if (i > 0)
+ sbuf.append(':');
+
+ sbuf.append(Integer.toHexString(x));
+ }
+ if( nif != null )
+ sbuf.append( "%" + nif.getName() );
+ else if( scope_id_set )
+ sbuf.append( "%" + scope_id );
+
+ return sbuf.toString();
+ }
+
+ /**
+ * Returns a hashcode for this IP address
+ * (The hashcode is independent of scope)
+ */
+ public int hashCode()
+ {
+ return super.hashCode();
+ }
+
+ /**
+ * Compares this object against the specified object
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof Inet6Address))
+ return false;
+
+ Inet6Address ip = (Inet6Address)obj;
+ if (ipaddress.length != ip.ipaddress.length)
+ return false;
+
+ for (int i = 0; i < ip.ipaddress.length; i++)
+ if (ipaddress[i] != ip.ipaddress[i])
+ return false;
+
+ if( ip.nif != null && nif != null )
+ return nif.equals( ip.nif );
+ if( ip.nif != nif )
+ return false;
+ if( ip.scope_id_set != scope_id_set )
+ return false;
+ if( scope_id_set )
+ return (scope_id == ip.scope_id);
+ return true;
+ }
+
+ /**
+ * Utility routine to check if the InetAddress is an
+ * IPv4 compatible IPv6 address
+ *
+ * @since 1.4
+ */
+ public boolean isIPv4CompatibleAddress()
+ {
+ if (ipaddress[0] != 0x00 || ipaddress[1] != 0x00 || ipaddress[2] != 0x00
+ || ipaddress[3] != 0x00 || ipaddress[4] != 0x00
+ || ipaddress[5] != 0x00 || ipaddress[6] != 0x00
+ || ipaddress[7] != 0x00 || ipaddress[8] != 0x00
+ || ipaddress[9] != 0x00 || ipaddress[10] != 0x00
+ || ipaddress[11] != 0x00)
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Required for 1.5-compatible serialization.
+ * @since 1.5
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ try
+ {
+ if( scope_ifname_set )
+ nif = NetworkInterface.getByName( ifname );
+ }
+ catch( SocketException se )
+ {
+ // FIXME: Ignore this? or throw an IOException?
+ }
+ }
+
+ /**
+ * Required for 1.5-compatible serialization.
+ * @since 1.5
+ */
+ private void writeObject(ObjectOutputStream s)
+ throws IOException
+ {
+ if( nif != null )
+ {
+ ifname = nif.getName();
+ scope_ifname_set = true;
+ }
+ s.defaultWriteObject();
+ }
+}
diff --git a/libjava/classpath/java/net/InetAddress.java b/libjava/classpath/java/net/InetAddress.java
new file mode 100644
index 000000000..1a9dc6202
--- /dev/null
+++ b/libjava/classpath/java/net/InetAddress.java
@@ -0,0 +1,655 @@
+/* InetAddress.java -- Class to model an Internet address
+ Copyright (C) 1998, 1999, 2002, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+/**
+ * This class models an Internet address. It does not have a public
+ * constructor. Instead, new instances of this objects are created
+ * using the static methods getLocalHost(), getByName(), and
+ * getAllByName().
+ *
+ * true
if the address has to be resolved,
+ * false
otherwise
+ *
+ * @exception IllegalArgumentException If the port number is illegal or
+ * the hostname argument is null
+ */
+ private InetSocketAddress(String hostname, int port, boolean resolve)
+ {
+ if (hostname == null)
+ throw new IllegalArgumentException("Null host name value");
+
+ if (port < 0 || port > 65535)
+ throw new IllegalArgumentException("Bad port number: " + port);
+
+ this.port = port;
+ this.hostname = hostname;
+ this.addr = null;
+
+ if (resolve)
+ {
+ try
+ {
+ this.addr = InetAddress.getByName(hostname);
+ }
+ catch (Exception e) // UnknownHostException, SecurityException
+ {
+ // Do nothing here. this.addr is already set to null.
+ }
+ }
+
+ }
+
+ /**
+ * Creates an unresolved InetSocketAddress
object.
+ *
+ * @param hostname The hostname for the socket address
+ * @param port The port for the socket address
+ *
+ * @exception IllegalArgumentException If the port number is illegal or
+ * the hostname argument is null
+ *
+ * @since 1.5
+ */
+ public static InetSocketAddress createUnresolved(String hostname, int port)
+ {
+ return new InetSocketAddress(hostname, port, false);
+ }
+
+ /**
+ * Test if obj is a InetSocketAddress
and
+ * has the same address and port
+ *
+ * @param obj The obj to compare this address with.
+ *
+ * @return True if obj is equal.
+ */
+ public final boolean equals(Object obj)
+ {
+ // InetSocketAddress objects are equal when addr and port are equal.
+ // The hostname may differ.
+ if (obj instanceof InetSocketAddress)
+ {
+ InetSocketAddress sa = (InetSocketAddress) obj;
+
+ if (addr == null && sa.addr != null)
+ return false;
+ else if (addr == null && sa.addr == null) // we know hostname != null
+ return hostname.equals(sa.hostname) && sa.port == port;
+ else
+ return addr.equals(sa.addr) && sa.port == port;
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns the InetAddress
or
+ * null
if its unresolved
+ *
+ * @return The IP address of this address.
+ */
+ public final InetAddress getAddress()
+ {
+ return addr;
+ }
+
+ /**
+ * Returns hostname
+ *
+ * @return The hostname of this address.
+ */
+ public final String getHostName()
+ {
+ if (hostname == null) // we know addr != null
+ hostname = addr.getHostName();
+
+ return hostname;
+ }
+
+ /**
+ * Returns the port
+ *
+ * @return The port of this address.
+ */
+ public final int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the hashcode of the InetSocketAddress
+ *
+ * @return The hashcode for this address.
+ */
+ public final int hashCode()
+ {
+ return port + addr.hashCode();
+ }
+
+ /**
+ * Checks wether the address has been resolved or not
+ *
+ * @return True if address is unresolved.
+ */
+ public final boolean isUnresolved()
+ {
+ return addr == null;
+ }
+
+ /**
+ * Returns the InetSocketAddress
as string
+ *
+ * @return A string representation of this address.
+ */
+ public String toString()
+ {
+ // Note: if addr is null, then hostname != null.
+ return (addr == null ? hostname : addr.toString()) + ":" + port;
+ }
+}
diff --git a/libjava/classpath/java/net/JarURLConnection.java b/libjava/classpath/java/net/JarURLConnection.java
new file mode 100644
index 000000000..0ffd1afac
--- /dev/null
+++ b/libjava/classpath/java/net/JarURLConnection.java
@@ -0,0 +1,229 @@
+/* JarURLConnection.java -- Class for manipulating remote jar files
+ Copyright (C) 1998, 2002, 2003, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+import java.security.cert.Certificate;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+
+/**
+ * This abstract class represents a common superclass for implementations
+ * of jar URL's. A jar URL is a special type of URL that allows JAR
+ * files on remote systems to be accessed. It has the form:
+ * MimeTypeMapper
object.
+ */
+ public MimeTypeMapper()
+ {
+ for (int i = 0; i < mime_strings.length; i++)
+ mime_types.put(mime_strings[i][0], mime_strings[i][1]);
+
+ // Now read from the system mime database, if it exists. Entries found
+ // here override our internal ones.
+ try
+ {
+ // On Linux this usually means /etc/mime.types.
+ String file
+ = SystemProperties.getProperty("gnu.classpath.mime.types.file");
+ if (file != null)
+ fillFromFile(mime_types, file);
+ }
+ catch (IOException ignore)
+ {
+ }
+ }
+
+ public static void fillFromFile (MapgetTimeToLive
instead.
+ *
+ * @return The TTL value
+ *
+ * @exception IOException If an error occurs
+ *
+ * @deprecated 1.2 Replaced by getTimeToLive()
+ *
+ * @see MulticastSocket#getTimeToLive()
+ */
+ public byte getTTL() throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ // Use getTTL here rather than getTimeToLive in case we're using an impl
+ // other than the default PlainDatagramSocketImpl and it doesn't have
+ // getTimeToLive yet.
+ return getImpl().getTTL();
+ }
+
+ /**
+ * Returns the current value of the "Time to Live" option. This is the
+ * number of hops a packet can make before it "expires".
+ *
+ * @return The TTL value
+ *
+ * @exception IOException If an error occurs
+ *
+ * @since 1.2
+ */
+ public int getTimeToLive() throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ return getImpl().getTimeToLive();
+ }
+
+ /**
+ * Sets the interface to use for sending multicast packets.
+ *
+ * @param addr The new interface to use.
+ *
+ * @exception SocketException If an error occurs.
+ *
+ * @since 1.4
+ */
+ public void setInterface(InetAddress addr) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.IP_MULTICAST_IF, addr);
+ }
+
+ /**
+ * Sets the local network interface used to send multicast messages
+ *
+ * @param netIf The local network interface used to send multicast messages
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @see MulticastSocket#getNetworkInterface()
+ *
+ * @since 1.4
+ */
+ public void setNetworkInterface(NetworkInterface netIf)
+ throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ InetAddress address;
+ if (netIf != null)
+ out:
+ {
+ Enumeration e = netIf.getInetAddresses();
+ if (getLocalAddress() instanceof Inet4Address)
+ {
+ // Search for a IPv4 address.
+ while (e.hasMoreElements())
+ {
+ address = (InetAddress) e.nextElement();
+ if (address instanceof Inet4Address)
+ break out;
+ }
+ throw new SocketException("interface " + netIf.getName() + " has no IPv6 address");
+ }
+ else if (getLocalAddress() instanceof Inet6Address)
+ {
+ // Search for a IPv6 address.
+ while (e.hasMoreElements())
+ {
+ address = (InetAddress) e.nextElement();
+ if (address instanceof Inet6Address)
+ break out;
+ }
+ throw new SocketException("interface " + netIf.getName() + " has no IPv6 address");
+ }
+ else
+ throw new SocketException("interface " + netIf.getName() + " has no suitable IP address");
+ }
+ else
+ address = InetAddress.ANY_IF;
+
+
+ getImpl().setOption(SocketOptions.IP_MULTICAST_IF, address);
+ }
+
+ /**
+ * Gets the local network interface which is used to send multicast messages
+ *
+ * @return The local network interface to send multicast messages
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
+ *
+ * @since 1.4
+ */
+ public NetworkInterface getNetworkInterface() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ InetAddress address =
+ (InetAddress) getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
+
+ if (address.isAnyLocalAddress())
+ return NetworkInterface.createAnyInterface();
+
+ NetworkInterface netIf = NetworkInterface.getByInetAddress(address);
+
+ return netIf;
+ }
+
+ /**
+ * Disable/Enable local loopback of multicast packets. The option is used by
+ * the platform's networking code as a hint for setting whether multicast
+ * data will be looped back to the local socket.
+ *
+ * Because this option is a hint, applications that want to verify what
+ * loopback mode is set to should call #getLoopbackMode
+ *
+ * @param disable True to disable loopback mode
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public void setLoopbackMode(boolean disable) throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP,
+ Boolean.valueOf(disable));
+ }
+
+ /**
+ * Checks if local loopback mode is enabled
+ *
+ * @return true if loopback mode is enabled, false otherwise
+ *
+ * @exception SocketException If an error occurs
+ *
+ * @since 1.4
+ */
+ public boolean getLoopbackMode() throws SocketException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ Object buf = getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP);
+
+ if (buf instanceof Boolean)
+ return ((Boolean) buf).booleanValue();
+
+ throw new SocketException("unexpected type");
+ }
+
+ /**
+ * Sets the "Time to Live" value for a socket. The value must be between
+ * 1 and 255.
+ *
+ * @param ttl The new TTL value
+ *
+ * @exception IOException If an error occurs
+ *
+ * @deprecated 1.2 Replaced by setTimeToLive
+ *
+ * @see MulticastSocket#setTimeToLive(int ttl)
+ */
+ public void setTTL(byte ttl) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ // Use setTTL here rather than setTimeToLive in case we're using an impl
+ // other than the default PlainDatagramSocketImpl and it doesn't have
+ // setTimeToLive yet.
+ getImpl().setTTL(ttl);
+ }
+
+ /**
+ * Sets the "Time to Live" value for a socket. The value must be between
+ * 0 and 255, inclusive.
+ *
+ * @param ttl The new TTL value
+ *
+ * @exception IOException If an error occurs
+ *
+ * @since 1.2
+ */
+ public void setTimeToLive(int ttl) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (ttl < 0 || ttl > 255)
+ throw new IllegalArgumentException("Invalid ttl: " + ttl);
+
+ getImpl().setTimeToLive(ttl);
+ }
+
+ /**
+ * Joins the specified multicast group.
+ *
+ * @param mcastaddr The address of the group to join
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast method doesn't allow the operation
+ */
+ public void joinGroup(InetAddress mcastaddr) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! mcastaddr.isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkMulticast(mcastaddr);
+
+ getImpl().join(mcastaddr);
+ }
+
+ /**
+ * Leaves the specified multicast group
+ *
+ * @param mcastaddr The address of the group to leave
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast method doesn't allow the operation
+ */
+ public void leaveGroup(InetAddress mcastaddr) throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! mcastaddr.isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkMulticast(mcastaddr);
+
+ getImpl().leave(mcastaddr);
+ }
+
+ /**
+ * Joins the specified mulitcast group on a specified interface.
+ *
+ * @param mcastaddr The multicast address to join
+ * @param netIf The local network interface to receive the multicast
+ * messages on or null to defer the interface set by #setInterface or
+ * #setNetworkInterface
+ *
+ * @exception IOException If an error occurs
+ * @exception IllegalArgumentException If address type is not supported
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast method doesn't allow the operation
+ *
+ * @see MulticastSocket#setInterface(InetAddress addr)
+ * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
+ *
+ * @since 1.4
+ */
+ public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+ throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ if (! (mcastaddr instanceof InetSocketAddress))
+ throw new IllegalArgumentException("SocketAddress type not supported");
+
+ InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
+
+ if (! tmp.getAddress().isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkMulticast(tmp.getAddress());
+
+ getImpl().joinGroup(mcastaddr, netIf);
+ }
+
+ /**
+ * Leaves the specified mulitcast group on a specified interface.
+ *
+ * @param mcastaddr The multicast address to leave
+ * @param netIf The local networki interface or null to defer to the
+ * interface set by setInterface or setNetworkInterface
+ *
+ * @exception IOException If an error occurs
+ * @exception IllegalArgumentException If address type is not supported
+ * @exception SecurityException If a security manager exists and its
+ * checkMulticast method doesn't allow the operation
+ *
+ * @see MulticastSocket#setInterface(InetAddress addr)
+ * @see MulticastSocket#setNetworkInterface(NetworkInterface netIf)
+ *
+ * @since 1.4
+ */
+ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+ throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ InetSocketAddress tmp = (InetSocketAddress) mcastaddr;
+
+ if (! tmp.getAddress().isMulticastAddress())
+ throw new IOException("Not a Multicast address");
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkMulticast(tmp.getAddress());
+
+ getImpl().leaveGroup(mcastaddr, netIf);
+ }
+
+ /**
+ * Sends a packet of data to a multicast address with a TTL that is
+ * different from the default TTL on this socket. The default TTL for
+ * the socket is not changed.
+ *
+ * @param packet The packet of data to send
+ * @param ttl The TTL for this packet
+ *
+ * @exception IOException If an error occurs
+ * @exception SecurityException If a security manager exists and its
+ * checkConnect or checkMulticast method doesn't allow the operation
+ *
+ * @deprecated
+ */
+ public synchronized void send(DatagramPacket packet, byte ttl)
+ throws IOException
+ {
+ if (isClosed())
+ throw new SocketException("socket is closed");
+
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ {
+ InetAddress addr = packet.getAddress();
+ if (addr.isMulticastAddress())
+ s.checkPermission(new SocketPermission(addr.getHostName()
+ + packet.getPort(),
+ "accept,connect"));
+ else
+ s.checkConnect(addr.getHostAddress(), packet.getPort());
+ }
+
+ int oldttl = getImpl().getTimeToLive();
+ getImpl().setTimeToLive(((int) ttl) & 0xFF);
+ getImpl().send(packet);
+ getImpl().setTimeToLive(oldttl);
+ }
+}
diff --git a/libjava/classpath/java/net/NetPermission.java b/libjava/classpath/java/net/NetPermission.java
new file mode 100644
index 000000000..cabe54e06
--- /dev/null
+++ b/libjava/classpath/java/net/NetPermission.java
@@ -0,0 +1,90 @@
+/* NetPermission.java -- A class for basic miscellaneous network permission
+ Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.security.BasicPermission;
+
+
+/**
+ * This class is used to model miscellaneous network permissions. It is
+ * a subclass of BasicPermission
. This means that it models a
+ * "boolean" permission. One that you either have or do not have. Thus
+ * there is no permitted action list associated with this object.
+ *
+ * The following permission names are defined for this class:
+ *
+ *
+ *
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
+public final class NetPermission extends BasicPermission
+{
+ static final long serialVersionUID = -8343910153355041693L;
+
+ /**
+ * Initializes a new instance of NetPermission
with the
+ * specified name.
+ *
+ * @param name The name of this permission.
+ */
+ public NetPermission(String name)
+ {
+ super(name);
+ }
+
+ /**
+ * Initializes a new instance of NetPermission
with the
+ * specified name and perms. Note that the perms field is irrelevant and is
+ * ignored. This constructor should never need to be used.
+ *
+ * @param name The name of this permission
+ * @param perms The permitted actions of this permission (ignored)
+ */
+ public NetPermission(String name, String perms)
+ {
+ super(name);
+ }
+}
diff --git a/libjava/classpath/java/net/NetworkInterface.java b/libjava/classpath/java/net/NetworkInterface.java
new file mode 100644
index 000000000..127dfba78
--- /dev/null
+++ b/libjava/classpath/java/net/NetworkInterface.java
@@ -0,0 +1,316 @@
+/* NetworkInterface.java --
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.classpath.SystemProperties;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * This class models a network interface on the host computer. A network
+ * interface contains a name (typically associated with a specific
+ * hardware adapter) and a list of addresses that are bound to it.
+ * For example, an ethernet interface may be named "eth0" and have the
+ * address 192.168.1.101 assigned to it.
+ *
+ * @author Michael Koch (konqueror@gmx.de)
+ * @since 1.4
+ */
+public final class NetworkInterface
+{
+ private final VMNetworkInterface netif;
+
+ private NetworkInterface(VMNetworkInterface netif)
+ {
+ this.netif = netif;
+ }
+
+ /** Creates an NetworkInterface instance which
+ * represents any interface in the system. Its only
+ * address is 0.0.0.0/0.0.0.0
. This
+ * method is needed by {@link MulticastSocket#getNetworkInterface}
+ */
+ static NetworkInterface createAnyInterface()
+ {
+ return new NetworkInterface(new VMNetworkInterface());
+ }
+
+ /**
+ * Returns the name of the network interface
+ *
+ * @return The name of the interface.
+ */
+ public String getName()
+ {
+ return netif.name;
+ }
+
+ /**
+ * Returns all available addresses of the network interface
+ *
+ * If a @see SecurityManager is available all addresses are checked
+ * with @see SecurityManager::checkConnect() if they are available.
+ * Only InetAddresses
are returned where the security manager
+ * doesn't throw an exception.
+ *
+ * @return An enumeration of all addresses.
+ */
+ public EnumerationNetworkInterface
object representing the interface,
+ * or null if there is no interface with that name.
+ *
+ * @exception SocketException If an error occurs
+ * @exception NullPointerException If the specified name is null
+ */
+ public static NetworkInterface getByName(String name)
+ throws SocketException
+ {
+ if (name == null)
+ throw new NullPointerException();
+ VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces();
+ for (int i = 0; i < netifs.length; i++)
+ {
+ if (netifs[i].name.equals(name))
+ return new NetworkInterface(netifs[i]);
+ }
+ return null;
+ }
+
+ /**
+ * Return a network interface by its address
+ *
+ * @param addr The address of the interface to return
+ *
+ * @return the interface, or null
if none found
+ *
+ * @exception SocketException If an error occurs
+ * @exception NullPointerException If the specified addess is null
+ */
+ public static NetworkInterface getByInetAddress(InetAddress addr)
+ throws SocketException
+ {
+ if (addr == null)
+ throw new NullPointerException();
+ VMNetworkInterface[] netifs = VMNetworkInterface.getVMInterfaces();
+ for (int i = 0; i < netifs.length; i++)
+ {
+ if (netifs[i].addresses.contains(addr))
+ return new NetworkInterface(netifs[i]);
+ }
+ return null;
+ }
+
+ /**
+ * Return an Enumeration
of all available network interfaces
+ *
+ * @return all interfaces
+ *
+ * @exception SocketException If an error occurs
+ */
+ public static Enumerationtrue
if equal, false
otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof NetworkInterface))
+ return false;
+
+ NetworkInterface tmp = (NetworkInterface) obj;
+
+ if (netif.name == null)
+ return tmp.netif.name == null;
+
+ return (netif.name.equals(tmp.netif.name)
+ && (netif.addresses.equals(tmp.netif.addresses)));
+ }
+
+ /**
+ * Returns the hashcode of the current instance
+ *
+ * @return the hashcode
+ */
+ public int hashCode()
+ {
+ // FIXME: hash correctly
+ int hc = netif.addresses.hashCode();
+
+ if (netif.name != null)
+ hc += netif.name.hashCode();
+
+ return hc;
+ }
+
+ /**
+ * Returns a string representation of the interface
+ *
+ * @return the string
+ */
+ public String toString()
+ {
+ // FIXME: check if this is correct
+ CPStringBuilder result;
+ String separator = SystemProperties.getProperty("line.separator");
+
+ result = new CPStringBuilder();
+
+ result.append("name: ");
+ result.append(getDisplayName());
+ result.append(" (").append(getName()).append(") addresses:");
+ result.append(separator);
+
+ for (Iterator it = netif.addresses.iterator(); it.hasNext(); )
+ {
+ InetAddress address = (InetAddress) it.next();
+ result.append(address.toString()).append(";").append(separator);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Determines whether this interface is ready to transfer data.
+ *
+ * @return whether the interface is up
+ */
+ public boolean isUp()
+ throws SocketException
+ {
+ return VMNetworkInterface.isUp(netif.name);
+ }
+
+ /**
+ * Determines whether this interface does point to point
+ * transmission.
+ *
+ * @return whether the interface does point to point transmission
+ */
+ public boolean isPointToPoint()
+ throws SocketException
+ {
+ return VMNetworkInterface.isPointToPoint(netif.name);
+ }
+
+ /**
+ * Determines whether this interface is the loopback interface.
+ *
+ * @return whether the interface is the loopback interface
+ */
+ public boolean isLoopback()
+ throws SocketException
+ {
+ return VMNetworkInterface.isLoopback(netif.name);
+ }
+
+ /**
+ * Determines whether this interface supports multicast transmission.
+ *
+ * @return whether the interface supports multicast transmission.
+ */
+ public boolean supportsMulticast()
+ throws SocketException
+ {
+ return VMNetworkInterface.supportsMulticast(netif.name);
+ }
+
+}
diff --git a/libjava/classpath/java/net/NoRouteToHostException.java b/libjava/classpath/java/net/NoRouteToHostException.java
new file mode 100644
index 000000000..48c3a8e60
--- /dev/null
+++ b/libjava/classpath/java/net/NoRouteToHostException.java
@@ -0,0 +1,74 @@
+/* NoRouteToHostException.java -- Cannot connect to a host
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This exception indicates that there is no TCP/IP route to the requested
+ * host. This is often due to a misconfigured routing table.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @since 1.1
+ * @status updated to 1.4
+ */
+public class NoRouteToHostException extends SocketException
+{
+ /**
+ * Compatible with JDK 1.1+.
+ */
+ private static final long serialVersionUID = -1897550894873493790L;
+
+ /**
+ * Create an instance without a descriptive error message.
+ */
+ public NoRouteToHostException()
+ {
+ }
+
+ /**
+ * Create an instance with a descriptive error message, such as the text
+ * from strerror(3).
+ *
+ * @param message a message describing the error that occurred
+ */
+ public NoRouteToHostException(String message)
+ {
+ super(message);
+ }
+} // class NoRouteToHostException
diff --git a/libjava/classpath/java/net/PasswordAuthentication.java b/libjava/classpath/java/net/PasswordAuthentication.java
new file mode 100644
index 000000000..1d4ec8961
--- /dev/null
+++ b/libjava/classpath/java/net/PasswordAuthentication.java
@@ -0,0 +1,92 @@
+/* PasswordAuthentication.java -- Container class for username/password pairs
+ Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This class serves a container for username/password pairs.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ *
+ * @since 1.2
+ */
+public final class PasswordAuthentication
+{
+ /**
+ * The username
+ */
+ private String username;
+
+ /**
+ * The password
+ */
+ private char[] password;
+
+ /**
+ * Creates a new PasswordAuthentication
object from the
+ * specified username and password.
+ *
+ * @param username The username for this object
+ * @param password The password for this object
+ */
+ public PasswordAuthentication(String username, char[] password)
+ {
+ this.username = username;
+ this.password = password;
+ }
+
+ /**
+ * Returns the username associated with this object
+ *
+ * @return The username
+ */
+ public String getUserName()
+ {
+ return username;
+ }
+
+ /**
+ * Returns the password associated with this object
+ *
+ * @return The password
+ */
+ public char[] getPassword()
+ {
+ return password;
+ }
+}
diff --git a/libjava/classpath/java/net/PortUnreachableException.java b/libjava/classpath/java/net/PortUnreachableException.java
new file mode 100644
index 000000000..49a8c9ea1
--- /dev/null
+++ b/libjava/classpath/java/net/PortUnreachableException.java
@@ -0,0 +1,72 @@
+/* PortUnreachableException.java -- received an ICMP port unreachable datagram
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This exception signals that an ICMP port unreachable datagram has been
+ * received.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class PortUnreachableException extends SocketException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = 8462541992376507323L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public PortUnreachableException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message a message describing the error that occurred
+ */
+ public PortUnreachableException(String message)
+ {
+ super(message);
+ }
+} // class PortUnreachableException
diff --git a/libjava/classpath/java/net/ProtocolException.java b/libjava/classpath/java/net/ProtocolException.java
new file mode 100644
index 000000000..27718a979
--- /dev/null
+++ b/libjava/classpath/java/net/ProtocolException.java
@@ -0,0 +1,75 @@
+/* ProtocolException.java -- a low level protocol error occurred
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+
+
+/**
+ * This exception indicates that some sort of low level protocol
+ * exception occurred. Look in the descriptive message (if any) for
+ * details on what went wrong.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @status updated to 1.4
+ */
+public class ProtocolException extends IOException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -6098449442062388080L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public ProtocolException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message a message describing the error that occurred
+ */
+ public ProtocolException(String message)
+ {
+ super(message);
+ }
+} // class ProtocolException
diff --git a/libjava/classpath/java/net/Proxy.java b/libjava/classpath/java/net/Proxy.java
new file mode 100644
index 000000000..36a25fa80
--- /dev/null
+++ b/libjava/classpath/java/net/Proxy.java
@@ -0,0 +1,139 @@
+/* Proxy.java -- Represends a proxy for a network connection
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * Defines a proxy setting. This setting contains a type (https, socks,
+ * direct) and a socket address.
+ *
+ * @since 1.5
+ */
+public class Proxy
+{
+ /**
+ * Represents the proxy type.
+ */
+ public enum Type
+ {
+ DIRECT, HTTP, SOCKS;
+
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = -2231209257930100533L;
+ }
+
+ public static final Proxy NO_PROXY = new Proxy(Type.DIRECT, null);
+
+ private Type type;
+ private SocketAddress address;
+
+ /**
+ * Creates a new Proxy
object.
+ *
+ * @param type The type for this proxy
+ * @param address The address of this proxy
+ */
+ public Proxy(Type type, SocketAddress address)
+ {
+ this.type = type;
+ this.address = address;
+ }
+
+ /**
+ * Returns the socket address for this proxy object.
+ *
+ * @return the socket address
+ */
+ public SocketAddress address()
+ {
+ return address;
+ }
+
+ /**
+ * Returns the of this proxy instance.
+ *
+ * @return the type
+ *
+ * @see Type
+ */
+ public Type type()
+ {
+ return type;
+ }
+
+ /**
+ * Compares the given object with this object.
+ *
+ * @return true
if both objects or equals,
+ * false
otherwise.
+ */
+ public final boolean equals(Object obj)
+ {
+ if (! (obj instanceof Proxy))
+ return false;
+
+ Proxy tmp = (Proxy) obj;
+
+ return (type.equals(tmp.type)
+ && (address == null ? tmp.address == null
+ : address.equals(tmp.address)));
+ }
+
+ /**
+ * Returns the hashcode for this Proxy
object.
+ *
+ * @return the hashcode
+ */
+ public final int hashCode()
+ {
+ return type.hashCode() ^ (address == null ? 0 : address.hashCode());
+ }
+
+ /**
+ * Returns a string representation of this Proxy
object.
+ *
+ * @return the string
+ */
+ public String toString()
+ {
+ return type.toString() + (address == null ? ""
+ : (":" + address.toString()));
+ }
+}
diff --git a/libjava/classpath/java/net/ProxySelector.java b/libjava/classpath/java/net/ProxySelector.java
new file mode 100644
index 000000000..6c85f99c7
--- /dev/null
+++ b/libjava/classpath/java/net/ProxySelector.java
@@ -0,0 +1,117 @@
+/* ProxySelector.java -- A proxy selector class
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.java.net.DefaultProxySelector;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Class for handling proxies for different connections.
+ *
+ * @since 1.5
+ */
+public abstract class ProxySelector
+{
+ /**
+ * Default proxy selector.
+ */
+ private static ProxySelector defaultSelector = new DefaultProxySelector();
+
+ /**
+ * Creates a new ProxySelector
object.
+ */
+ public ProxySelector()
+ {
+ // Do nothing here.
+ }
+
+ /**
+ * Returns the default proxy selector.
+ *
+ * @return the default proxy selector
+ *
+ * @throws SecurityException If a security manager is installed and it
+ * denies NetPermission("getProxySelector")
+ */
+ public static ProxySelector getDefault()
+ {
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null)
+ sm.checkPermission(new NetPermission("getProxySelector"));
+
+ return defaultSelector;
+ }
+
+ /**
+ * Sets the default proxy selector.
+ *
+ * @param selector the defualt proxy selector
+ *
+ * @throws SecurityException If a security manager is installed and it
+ * denies NetPermission("setProxySelector")
+ */
+ public static void setDefault(ProxySelector selector)
+ {
+ SecurityManager sm = System.getSecurityManager();
+
+ if (sm != null)
+ sm.checkPermission(new NetPermission("setProxySelector"));
+
+ defaultSelector = selector;
+ }
+
+ /**
+ * Signals to the selector that a proxy was no available.
+ *
+ * @throws IllegalArgumentException If one argument is null
+ */
+ public abstract void connectFailed(URI uri, SocketAddress address,
+ IOException exception);
+
+ /**
+ * Returns the list of proxy settings for a given URI.
+ *
+ * @return list of proxy settings
+ *
+ * @throws IllegalArgumentException If uri is null
+ */
+ public abstract List
+ *
networkaddress.cache.ttl
networkaddress.cache.negative.ttl
[//authority][path]
+ * [?query]
+ * [user-info@]host
+ * [:port]
+ * null
and the empty string in Java, respectively.
+ * The scheme-specific part may never be undefined. It also follows from
+ * this that the path sub-part may also not be undefined, so as to ensure
+ * the former.
+ * Character Escaping and Quoting
+ *
+ *
+ *
+ *
+ *
+ *
+ * toASCIIString()
method
+ * is used. In contrast, illegal characters are always quoted, with the
+ * exception of the return values of the non-raw accessors.
+ *
+ *
+ * null
is returned to indicate an undefined
+ * value. Otherwise, the value is truly the empty string and this is
+ * the returned value.null
for undefined
+ * values, or an empty string for a URI part with empty content.
+ */
+ private static String getURIGroup(Matcher match, int group)
+ {
+ String matched = match.group(group);
+ if (matched == null || matched.length() == 0)
+ {
+ String prevMatched = match.group(group -1);
+ if (prevMatched == null || prevMatched.length() == 0)
+ return null;
+ else
+ return "";
+ }
+ return matched;
+ }
+
+ /**
+ * Sets fields of this URI by parsing the given string.
+ *
+ * @param str The string to parse
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ */
+ private void parseURI(String str) throws URISyntaxException
+ {
+ Matcher matcher = URI_PATTERN.matcher(str);
+
+ if (matcher.matches())
+ {
+ scheme = getURIGroup(matcher, SCHEME_GROUP);
+ rawSchemeSpecificPart = matcher.group(SCHEME_SPEC_PART_GROUP);
+ schemeSpecificPart = unquote(rawSchemeSpecificPart);
+ if (!isOpaque())
+ {
+ rawAuthority = getURIGroup(matcher, AUTHORITY_GROUP);
+ rawPath = matcher.group(PATH_GROUP);
+ rawQuery = getURIGroup(matcher, QUERY_GROUP);
+ }
+ rawFragment = getURIGroup(matcher, FRAGMENT_GROUP);
+ }
+ else
+ throw new URISyntaxException(str,
+ "doesn't match URI regular expression");
+ parseServerAuthority();
+
+ // We must eagerly unquote the parts, because this is the only time
+ // we may throw an exception.
+ authority = unquote(rawAuthority);
+ userInfo = unquote(rawUserInfo);
+ host = unquote(rawHost);
+ path = unquote(rawPath);
+ query = unquote(rawQuery);
+ fragment = unquote(rawFragment);
+ }
+
+ /**
+ * Unquote "%" + hex quotes characters
+ *
+ * @param str The string to unquote or null.
+ *
+ * @return The unquoted string or null if str was null.
+ *
+ * @exception URISyntaxException If the given string contains invalid
+ * escape sequences.
+ */
+ private static String unquote(String str) throws URISyntaxException
+ {
+ if (str == null)
+ return null;
+ byte[] buf = new byte[str.length()];
+ int pos = 0;
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if (c == '%')
+ {
+ if (i + 2 >= str.length())
+ throw new URISyntaxException(str, "Invalid quoted character");
+ int hi = Character.digit(str.charAt(++i), 16);
+ int lo = Character.digit(str.charAt(++i), 16);
+ if (lo < 0 || hi < 0)
+ throw new URISyntaxException(str, "Invalid quoted character");
+ buf[pos++] = (byte) (hi * 16 + lo);
+ }
+ else
+ buf[pos++] = (byte) c;
+ }
+ try
+ {
+ return new String(buf, 0, pos, "utf-8");
+ }
+ catch (java.io.UnsupportedEncodingException x2)
+ {
+ throw (Error) new InternalError().initCause(x2);
+ }
+ }
+
+ /**
+ * Quote characters illegal in URIs in given string.
+ *
+ * Replace illegal characters by encoding their UTF-8
+ * representation as "%" + hex code for each resulting
+ * UTF-8 character.
+ *
+ * @param str The string to quote
+ *
+ * @return The quoted string.
+ */
+ private static String quote(String str)
+ {
+ return quote(str, RFC3986_SSP);
+ }
+
+ /**
+ * Quote characters illegal in URI authorities in given string.
+ *
+ * Replace illegal characters by encoding their UTF-8
+ * representation as "%" + hex code for each resulting
+ * UTF-8 character.
+ *
+ * @param str The string to quote
+ *
+ * @return The quoted string.
+ */
+ private static String quoteAuthority(String str)
+ {
+ // Technically, we should be using RFC2396_AUTHORITY, but
+ // it contains no additional characters.
+ return quote(str, RFC3986_REG_NAME);
+ }
+
+ /**
+ * Quotes the characters in the supplied string that are not part of
+ * the specified set of legal characters.
+ *
+ * @param str the string to quote
+ * @param legalCharacters the set of legal characters
+ *
+ * @return the quoted string.
+ */
+ private static String quote(String str, String legalCharacters)
+ {
+ CPStringBuilder sb = new CPStringBuilder(str.length());
+ for (int i = 0; i < str.length(); i++)
+ {
+ char c = str.charAt(i);
+ if ((legalCharacters.indexOf(c) == -1)
+ && (c <= 127))
+ {
+ sb.append('%');
+ sb.append(HEX.charAt(c / 16));
+ sb.append(HEX.charAt(c % 16));
+ }
+ else
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Quote characters illegal in URI hosts in given string.
+ *
+ * Replace illegal characters by encoding their UTF-8
+ * representation as "%" + hex code for each resulting
+ * UTF-8 character.
+ *
+ * @param str The string to quote
+ *
+ * @return The quoted string.
+ */
+ private static String quoteHost(String str)
+ {
+ return quote(str, RFC3986_HOST);
+ }
+
+ /**
+ * Quote characters illegal in URI paths in given string.
+ *
+ * Replace illegal characters by encoding their UTF-8
+ * representation as "%" + hex code for each resulting
+ * UTF-8 character.
+ *
+ * @param str The string to quote
+ *
+ * @return The quoted string.
+ */
+ private static String quotePath(String str)
+ {
+ // Technically, we should be using RFC2396_PATH, but
+ // it contains no additional characters.
+ return quote(str, RFC3986_PATH_SEGMENTS);
+ }
+
+ /**
+ * Quote characters illegal in URI user infos in given string.
+ *
+ * Replace illegal characters by encoding their UTF-8
+ * representation as "%" + hex code for each resulting
+ * UTF-8 character.
+ *
+ * @param str The string to quote
+ *
+ * @return The quoted string.
+ */
+ private static String quoteUserInfo(String str)
+ {
+ return quote(str, RFC3986_USERINFO);
+ }
+
+ /**
+ * Creates an URI from the given string
+ *
+ * @param str The string to create the URI from
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ * @exception NullPointerException If str is null
+ */
+ public URI(String str) throws URISyntaxException
+ {
+ this.string = str;
+ parseURI(str);
+ }
+
+ /**
+ * Create an URI from the given components
+ *
+ * @param scheme The scheme name
+ * @param userInfo The username and authorization info
+ * @param host The hostname
+ * @param port The port number
+ * @param path The path
+ * @param query The query
+ * @param fragment The fragment
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ */
+ public URI(String scheme, String userInfo, String host, int port,
+ String path, String query, String fragment)
+ throws URISyntaxException
+ {
+ this((scheme == null ? "" : scheme + ":")
+ + (userInfo == null && host == null && port == -1 ? "" : "//")
+ + (userInfo == null ? "" : quoteUserInfo(userInfo) + "@")
+ + (host == null ? "" : quoteHost(host))
+ + (port == -1 ? "" : ":" + String.valueOf(port))
+ + (path == null ? "" : quotePath(path))
+ + (query == null ? "" : "?" + quote(query))
+ + (fragment == null ? "" : "#" + quote(fragment)));
+ }
+
+ /**
+ * Create an URI from the given components
+ *
+ * @param scheme The scheme name
+ * @param authority The authority
+ * @param path The apth
+ * @param query The query
+ * @param fragment The fragment
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ */
+ public URI(String scheme, String authority, String path, String query,
+ String fragment) throws URISyntaxException
+ {
+ this((scheme == null ? "" : scheme + ":")
+ + (authority == null ? "" : "//" + quoteAuthority(authority))
+ + (path == null ? "" : quotePath(path))
+ + (query == null ? "" : "?" + quote(query))
+ + (fragment == null ? "" : "#" + quote(fragment)));
+ }
+
+ /**
+ * Create an URI from the given components
+ *
+ * @param scheme The scheme name
+ * @param host The hostname
+ * @param path The path
+ * @param fragment The fragment
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ */
+ public URI(String scheme, String host, String path, String fragment)
+ throws URISyntaxException
+ {
+ this(scheme, null, host, -1, path, null, fragment);
+ }
+
+ /**
+ * Create an URI from the given components
+ *
+ * @param scheme The scheme name
+ * @param ssp The scheme specific part
+ * @param fragment The fragment
+ *
+ * @exception URISyntaxException If the given string violates RFC 2396
+ */
+ public URI(String scheme, String ssp, String fragment)
+ throws URISyntaxException
+ {
+ this((scheme == null ? "" : scheme + ":")
+ + (ssp == null ? "" : quote(ssp))
+ + (fragment == null ? "" : "#" + quote(fragment)));
+ }
+
+ /**
+ * Create an URI from the given string
+ *
+ * @param str The string to create the URI from
+ *
+ * @exception IllegalArgumentException If the given string violates RFC 2396
+ * @exception NullPointerException If str is null
+ */
+ public static URI create(String str)
+ {
+ try
+ {
+ return new URI(str);
+ }
+ catch (URISyntaxException e)
+ {
+ throw (IllegalArgumentException) new IllegalArgumentException()
+ .initCause(e);
+ }
+ }
+
+ /**
+ * Attempts to parse this URI's authority component, if defined,
+ * into user-information, host, and port components. The purpose
+ * of this method was to disambiguate between some authority sections,
+ * which form invalid server-based authories, but valid registry
+ * based authorities. In the updated RFC 3986, the authority section
+ * is defined differently, with registry-based authorities part of
+ * the host section. Thus, this method is now simply an explicit
+ * way of parsing any authority section.
+ *
+ * @return the URI, with the authority section parsed into user
+ * information, host and port components.
+ * @throws URISyntaxException if the given string violates RFC 2396
+ */
+ public URI parseServerAuthority() throws URISyntaxException
+ {
+ if (rawAuthority != null)
+ {
+ Matcher matcher = AUTHORITY_PATTERN.matcher(rawAuthority);
+
+ if (matcher.matches())
+ {
+ rawUserInfo = getURIGroup(matcher, AUTHORITY_USERINFO_GROUP);
+ rawHost = getURIGroup(matcher, AUTHORITY_HOST_GROUP);
+
+ String portStr = getURIGroup(matcher, AUTHORITY_PORT_GROUP);
+
+ if (portStr != null && ! portStr.isEmpty())
+ try
+ {
+ port = Integer.parseInt(portStr);
+ }
+ catch (NumberFormatException e)
+ {
+ URISyntaxException use =
+ new URISyntaxException
+ (string, "doesn't match URI regular expression");
+ use.initCause(e);
+ throw use;
+ }
+ }
+ else
+ throw new URISyntaxException(string,
+ "doesn't match URI regular expression");
+ }
+ return this;
+ }
+
+ /**
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param uri the URI to relativize agsint this URI
+ * @return the resulting URI
+ * @throws NullPointerException if the uri is null
+ */
+ public URI relativize(URI uri)
+ {
+ if (isOpaque() || uri.isOpaque())
+ return uri;
+ if (scheme == null && uri.getScheme() != null)
+ return uri;
+ if (scheme != null && !(scheme.equals(uri.getScheme())))
+ return uri;
+ if (rawAuthority == null && uri.getRawAuthority() != null)
+ return uri;
+ if (rawAuthority != null && !(rawAuthority.equals(uri.getRawAuthority())))
+ return uri;
+ String basePath = rawPath;
+ if (!(uri.getRawPath().equals(rawPath)))
+ {
+ if (!(basePath.endsWith("/")))
+ basePath = basePath.concat("/");
+ if (!(uri.getRawPath().startsWith(basePath)))
+ return uri;
+ }
+ try
+ {
+ return new URI(null, null,
+ uri.getRawPath().substring(basePath.length()),
+ uri.getRawQuery(), uri.getRawFragment());
+ }
+ catch (URISyntaxException e)
+ {
+ throw (Error) new InternalError("Relativized URI variant could not "+
+ "be constructed").initCause(e);
+ }
+ }
+
+ /**
+ * Creates an URL from an URI
+ *
+ * @throws MalformedURLException If a protocol handler for the URL could
+ * not be found, or if some other error occurred while constructing the URL
+ * @throws IllegalArgumentException If the URI is not absolute
+ */
+ public URL toURL() throws IllegalArgumentException, MalformedURLException
+ {
+ if (isAbsolute())
+ return new URL(this.toString());
+
+ throw new IllegalArgumentException("not absolute");
+ }
+
+ /**
+ * Returns the scheme of the URI
+ */
+ public String getScheme()
+ {
+ return scheme;
+ }
+
+ /**
+ * Tells whether this URI is absolute or not
+ */
+ public boolean isAbsolute()
+ {
+ return scheme != null;
+ }
+
+ /**
+ * Tell whether this URI is opaque or not
+ */
+ public boolean isOpaque()
+ {
+ return ((scheme != null) && ! (schemeSpecificPart.startsWith("/")));
+ }
+
+ /**
+ * Returns the raw scheme specific part of this URI.
+ * The scheme-specific part is never undefined, though it may be empty
+ */
+ public String getRawSchemeSpecificPart()
+ {
+ return rawSchemeSpecificPart;
+ }
+
+ /**
+ * Returns the decoded scheme specific part of this URI.
+ */
+ public String getSchemeSpecificPart()
+ {
+ return schemeSpecificPart;
+ }
+
+ /**
+ * Returns the raw authority part of this URI
+ */
+ public String getRawAuthority()
+ {
+ return rawAuthority;
+ }
+
+ /**
+ * Returns the decoded authority part of this URI
+ */
+ public String getAuthority()
+ {
+ return authority;
+ }
+
+ /**
+ * Returns the raw user info part of this URI
+ */
+ public String getRawUserInfo()
+ {
+ return rawUserInfo;
+ }
+
+ /**
+ * Returns the decoded user info part of this URI
+ */
+ public String getUserInfo()
+ {
+ return userInfo;
+ }
+
+ /**
+ * Returns the hostname of the URI
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Returns the port number of the URI
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the raw path part of this URI
+ */
+ public String getRawPath()
+ {
+ return rawPath;
+ }
+
+ /**
+ * Returns the path of the URI
+ */
+ public String getPath()
+ {
+ return path;
+ }
+
+ /**
+ * Returns the raw query part of this URI
+ */
+ public String getRawQuery()
+ {
+ return rawQuery;
+ }
+
+ /**
+ * Returns the query of the URI
+ */
+ public String getQuery()
+ {
+ return query;
+ }
+
+ /**
+ * Return the raw fragment part of this URI
+ */
+ public String getRawFragment()
+ {
+ return rawFragment;
+ }
+
+ /**
+ * Returns the fragment of the URI
+ */
+ public String getFragment()
+ {
+ return fragment;
+ }
+
+ /**
+ * URI
, then the method returns false.
+ * Otherwise, the following criteria are observed:
+ *
+ *
+ *
+ * @param obj the obj to compare the URI with.
+ * @return
+ *
+ *
+ *
+ *
+ *
+ *
+ * true
if the objects are equal, according to
+ * the specification above.
+ */
+ public boolean equals(Object obj)
+ {
+ if (!(obj instanceof URI))
+ return false;
+ URI uriObj = (URI) obj;
+ if (scheme == null)
+ {
+ if (uriObj.getScheme() != null)
+ return false;
+ }
+ else
+ if (!(scheme.equalsIgnoreCase(uriObj.getScheme())))
+ return false;
+ if (rawFragment == null)
+ {
+ if (uriObj.getRawFragment() != null)
+ return false;
+ }
+ else
+ if (!(rawFragment.equalsIgnoreCase(uriObj.getRawFragment())))
+ return false;
+ boolean opaqueThis = isOpaque();
+ boolean opaqueObj = uriObj.isOpaque();
+ if (opaqueThis && opaqueObj)
+ return rawSchemeSpecificPart.equals(uriObj.getRawSchemeSpecificPart());
+ else if (!opaqueThis && !opaqueObj)
+ {
+ boolean common = rawPath.equalsIgnoreCase(uriObj.getRawPath())
+ && ((rawQuery == null && uriObj.getRawQuery() == null)
+ || rawQuery.equalsIgnoreCase(uriObj.getRawQuery()));
+ if (rawAuthority == null && uriObj.getRawAuthority() == null)
+ return common;
+ if (host == null)
+ return common
+ && rawAuthority.equalsIgnoreCase(uriObj.getRawAuthority());
+ return common
+ && host.equalsIgnoreCase(uriObj.getHost())
+ && port == uriObj.getPort()
+ && (rawUserInfo == null ?
+ uriObj.getRawUserInfo() == null :
+ rawUserInfo.equalsIgnoreCase(uriObj.getRawUserInfo()));
+ }
+ else
+ return false;
+ }
+
+ /**
+ * Computes the hashcode of the URI
+ */
+ public int hashCode()
+ {
+ return (getScheme() == null ? 0 : 13 * getScheme().hashCode())
+ + 17 * getRawSchemeSpecificPart().hashCode()
+ + (getRawFragment() == null ? 0 : 21 + getRawFragment().hashCode());
+ }
+
+ /**
+ * Compare the URI with another URI.
+ * Undefined components are taken to be less than any other component.
+ * The following criteria are observed:
+ *
toString()
for URIs that don't contain any non-US-ASCII
+ * characters. Otherwise, the non-US-ASCII characters are replaced
+ * by their percent-encoded representations.
+ *
+ * @return a string representation of the URI, containing only US-ASCII
+ * characters.
+ */
+ public String toASCIIString()
+ {
+ String strRep = toString();
+ boolean inNonAsciiBlock = false;
+ CPStringBuilder buffer = new CPStringBuilder();
+ CPStringBuilder encBuffer = null;
+ for (int i = 0; i < strRep.length(); i++)
+ {
+ char c = strRep.charAt(i);
+ if (c <= 127)
+ {
+ if (inNonAsciiBlock)
+ {
+ buffer.append(escapeCharacters(encBuffer.toString()));
+ inNonAsciiBlock = false;
+ }
+ buffer.append(c);
+ }
+ else
+ {
+ if (!inNonAsciiBlock)
+ {
+ encBuffer = new CPStringBuilder();
+ inNonAsciiBlock = true;
+ }
+ encBuffer.append(c);
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Converts the non-ASCII characters in the supplied string
+ * to their equivalent percent-encoded representations.
+ * That is, they are replaced by "%" followed by their hexadecimal value.
+ *
+ * @param str a string including non-ASCII characters.
+ * @return the string with the non-ASCII characters converted to their
+ * percent-encoded representations.
+ */
+ private static String escapeCharacters(String str)
+ {
+ try
+ {
+ CPStringBuilder sb = new CPStringBuilder();
+ // this is far from optimal, but it works
+ byte[] utf8 = str.getBytes("utf-8");
+ for (int j = 0; j < utf8.length; j++)
+ {
+ sb.append('%');
+ sb.append(HEX.charAt((utf8[j] & 0xff) / 16));
+ sb.append(HEX.charAt((utf8[j] & 0xff) % 16));
+ }
+ return sb.toString();
+ }
+ catch (java.io.UnsupportedEncodingException x)
+ {
+ throw (Error) new InternalError("Escaping error").initCause(x);
+ }
+ }
+
+}
diff --git a/libjava/classpath/java/net/URISyntaxException.java b/libjava/classpath/java/net/URISyntaxException.java
new file mode 100644
index 000000000..27a70bdb7
--- /dev/null
+++ b/libjava/classpath/java/net/URISyntaxException.java
@@ -0,0 +1,144 @@
+/* URISyntaxException.java -- a string could not be parsed as a URI
+ Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+
+/**
+ * This exception is thrown when a String cannot be parsed as a URI.
+ *
+ * @author Eric Blake (ebb9@email.byu.edu)
+ * @see URI
+ * @since 1.4
+ * @status updated to 1.4
+ */
+public class URISyntaxException extends Exception
+{
+ /**
+ * Compatible with JDK 1.4+.
+ */
+ private static final long serialVersionUID = 2137979680897488891L;
+
+ /**
+ * The failed input.
+ *
+ * @serial the bad URI
+ */
+ private final String input;
+
+ /**
+ * The index of failure.
+ *
+ * @serial the location of the problem
+ */
+ private final int index;
+
+ /**
+ * Create an exception from the invalid string, with the index set to -1.
+ *
+ * @param input the bad URI
+ * @param msg the descriptive error message
+ * @throws NullPointerException if input or msg are null
+ */
+ public URISyntaxException(String input, String msg)
+ {
+ this(input, msg, -1);
+ }
+
+ /**
+ * Create an exception from the invalid string, with the index of the
+ * point of failure.
+ *
+ * @param input the bad URI
+ * @param msg the descriptive error message
+ * @param index the index of the parse error, or -1
+ * @throws NullPointerException if input or msg are null
+ * @throws IllegalArgumentException if index < -1
+ */
+ public URISyntaxException(String input, String msg, int index)
+ {
+ // The toString() hack checks for null.
+ super(msg.toString());
+ this.input = input.toString();
+ this.index = index;
+ if (index < -1)
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Returns the bad input string.
+ *
+ * @return the bad URI, guaranteed non-null
+ */
+ public String getInput()
+ {
+ return input;
+ }
+
+ /**
+ * Returns the reason for the failure.
+ *
+ * @return the message, guaranteed non-null
+ */
+ public String getReason()
+ {
+ return super.getMessage();
+ }
+
+ /**
+ * Returns the index of the failure, or -1.
+ *
+ * @return the index of failure
+ */
+ public int getIndex()
+ {
+ return index;
+ }
+
+ /**
+ * Returns a message describing the parse error, as if by
+ * getReason() + (getIndex() >= 0 ? " at index " + getIndex() : "")
+ * + ": " + getInput()
.
+ *
+ * @return the message string
+ */
+ public String getMessage()
+ {
+ return (super.getMessage() + (index >= 0 ? " at index " + index : "")
+ + ": " + input);
+ }
+}
diff --git a/libjava/classpath/java/net/URL.java b/libjava/classpath/java/net/URL.java
new file mode 100644
index 000000000..1b778b40a
--- /dev/null
+++ b/libjava/classpath/java/net/URL.java
@@ -0,0 +1,1010 @@
+/* URL.java -- Uniform Resource Locator Class
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.classpath.SystemProperties;
+import gnu.java.net.URLParseError;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This final class represents an Internet Uniform Resource Locator (URL).
+ * For details on the syntax of URL's and what they can be used for,
+ * refer to RFC 1738, available from
+ * http://ds.internic.net/rfcs/rfc1738.txt
+ * + * There are a great many protocols supported by URL's such as "http", + * "ftp", and "file". This object can handle any arbitrary URL for which + * a URLStreamHandler object can be written. Default protocol handlers + * are provided for the "http" and "ftp" protocols. Additional protocols + * handler implementations may be provided in the future. In any case, + * an application or applet can install its own protocol handlers that + * can be "chained" with other protocol hanlders in the system to extend + * the base functionality provided with this class. (Note, however, that + * unsigned applets cannot access properties by default or install their + * own protocol handlers). + *
+ * This chaining is done via the system property java.protocol.handler.pkgs + * If this property is set, it is assumed to be a "|" separated list of + * package names in which to attempt locating protocol handlers. The + * protocol handler is searched for by appending the string + * ".<protocol>.Handler" to each packed in the list until a hander is + * found. If a protocol handler is not found in this list of packages, or if + * the property does not exist, then the default protocol handler of + * "gnu.java.net.<protocol>.Handler" is tried. If this is + * unsuccessful, a MalformedURLException is thrown. + *
+ * All of the constructor methods of URL attempt to load a protocol + * handler and so any needed protocol handlers must be installed when + * the URL is constructed. + *
+ * Here is an example of how URL searches for protocol handlers. Assume + * the value of java.protocol.handler.pkgs is "com.foo|com.bar" and the + * URL is "news://comp.lang.java.programmer". URL would looking the + * following places for protocol handlers: + *
+ * com.foo.news.Handler + * com.bar.news.Handler + * gnu.java.net.news.Handler + *
+ * If the protocol handler is not found in any of those locations, a + * MalformedURLException would be thrown. + *
+ * Please note that a protocol handler must be a subclass of + * URLStreamHandler. + *
+ * Normally, this class caches protocol handlers. Once it finds a handler + * for a particular protocol, it never tries to look up a new handler + * again. However, if the system property + * gnu.java.net.nocache_protocol_handlers is set, then this + * caching behavior is disabled. This property is specific to this + * implementation. Sun's JDK may or may not do protocol caching, but it + * almost certainly does not examine this property. + *
+ * Please also note that an application can install its own factory for
+ * loading protocol handlers (see setURLStreamHandlerFactory). If this is
+ * done, then the above information is superseded and the behavior of this
+ * class in loading protocol handlers is dependent on that factory.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ *
+ * @see URLStreamHandler
+ */
+public final class URL implements Serializable
+{
+ private static final String DEFAULT_SEARCH_PATH =
+ "gnu.java.net.protocol|gnu.inet";
+
+ // Cached System ClassLoader
+ private static ClassLoader systemClassLoader;
+
+ /**
+ * The name of the protocol for this URL.
+ * The protocol is always stored in lower case.
+ */
+ private String protocol;
+
+ /**
+ * The "authority" portion of the URL.
+ */
+ private String authority;
+
+ /**
+ * The hostname or IP address of this protocol.
+ * This includes a possible user. For example
+ * Additionally, this method allows the caller to specify a protocol handler
+ * to use instead of the default. If this handler is specified, the caller
+ * must have the "specifyStreamHandler" permission
+ * (see New instances can be created by two static
+ * Normally creating a Open issues:
+ *
+ * A URLConnection object is normally created by calling the openConnection()
+ * method of a URL object. This method is somewhat misnamed because it does
+ * not actually open the connection. Instead, it return an unconnected
+ * instance of this object. The caller then has the opportunity to set
+ * various connection options prior to calling the actual connect() method.
+ *
+ * After the connection has been opened, there are a number of methods in
+ * this class that access various attributes of the data, typically
+ * represented by headers sent in advance of the actual data itself.
+ *
+ * Also of note are the getInputStream and getContent() methods which allow
+ * the caller to retrieve the actual data from the connection. Note that
+ * for some types of connections, writing is also allowed. The setDoOutput()
+ * method must be called prior to connecing in order to enable this, then
+ * the getOutputStream method called after the connection in order to
+ * obtain a stream to write the output to.
+ *
+ * The getContent() method is of particular note. This method returns an
+ * Object that encapsulates the data returned. There is no way do determine
+ * the type of object that will be returned in advance. This is determined
+ * by the actual content handlers as described in the description of that
+ * method.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public abstract class URLConnection
+{
+ /**
+ * This is an object that maps filenames to MIME types. The interface
+ * to do this is implemented by this class, so just create an empty
+ * instance and store it here.
+ */
+ private static FileNameMap fileNameMap;
+
+ /**
+ * This is the ContentHandlerFactory set by the caller, if any
+ */
+ private static ContentHandlerFactory factory;
+
+ /**
+ * This is the default value that will be used to determine whether or
+ * not user interaction should be allowed.
+ */
+ private static boolean defaultAllowUserInteraction;
+
+ /**
+ * This is the default flag indicating whether or not to use caches to
+ * store the data returned from a server
+ */
+ private static boolean defaultUseCaches = true;
+
+ /**
+ * Default internal content handler factory.
+ */
+ private static ContentHandlerFactory defaultFactory
+ = new gnu.java.net.DefaultContentHandlerFactory();
+
+ /**
+ * This variable determines whether or not interaction is allowed with
+ * the user. For example, to prompt for a username and password.
+ */
+ protected boolean allowUserInteraction;
+
+ /**
+ * Indicates whether or not a connection has been established to the
+ * destination specified in the URL
+ */
+ protected boolean connected;
+
+ /**
+ * Indicates whether or not input can be read from this URL
+ */
+ protected boolean doInput = true;
+
+ /**
+ * Indicates whether or not output can be sent to this URL
+ */
+ protected boolean doOutput;
+
+ /**
+ * If this flag is set, the protocol is allowed to cache data whenever
+ * it can (caching is not guaranteed). If it is not set, the protocol
+ * must a get a fresh copy of the data.
+ *
+ * This field is set by the setUseCaches method and returned by the
+ * getUseCaches method.
+ *
+ * Its default value is that determined by the last invocation of
+ * setDefaultUseCaches
+ */
+ protected boolean useCaches;
+
+ /**
+ * If this value is non-zero, then the connection will only attempt to
+ * fetch the document pointed to by the URL if the document has been
+ * modified more recently than the date set in this variable. That date
+ * should be specified as the number of seconds since 1/1/1970 GMT.
+ */
+ protected long ifModifiedSince;
+
+ /**
+ * This is the URL associated with this connection
+ */
+ protected URL url;
+
+ private static SimpleDateFormat[] dateFormats;
+ private static boolean dateformats_initialized;
+
+ /**
+ * The connection timeout period.
+ */
+ private int connectTimeout;
+
+ /**
+ * The read timeout period.
+ */
+ private int readTimeout;
+
+ /* Cached ParsePosition, used when parsing dates. */
+ private ParsePosition position;
+
+ /**
+ * Creates a URL connection to a given URL. A real connection is not made.
+ * Use This class first determines the MIME type of the content, then
+ * creates a ContentHandler object to process the input. If the
+ *
+ * Note that because of items such as HTTP redirects, the permission
+ * object returned might be different before and after connecting.
+ *
+ * @return A Permission object
+ *
+ * @exception IOException If the computation of the permission requires
+ * network or file I/O and an exception occurs while computing it
+ */
+ public Permission getPermission() throws IOException
+ {
+ // Subclasses may override this.
+ return new AllPermission();
+ }
+
+ /**
+ * Returns an InputStream for this connection. As this default
+ * implementation returns null, subclasses should override this method
+ *
+ * @return An InputStream for this connection
+ *
+ * @exception IOException If an error occurs
+ * @exception UnknownServiceException If the protocol does not support input
+ */
+ public InputStream getInputStream() throws IOException
+ {
+ // Subclasses for specific protocols override this.
+ throw new UnknownServiceException("Protocol " + url.getProtocol()
+ + " does not support input.");
+ }
+
+ /**
+ * Returns an OutputStream for this connection. As this default
+ * implementation returns null, subclasses should override this method
+ *
+ * @return An OutputStream for this connection
+ *
+ * @exception IOException If an error occurs
+ * @exception UnknownServiceException If the protocol does not support output
+ */
+ public OutputStream getOutputStream() throws IOException
+ {
+ // Subclasses for specific protocols override this.
+ throw new UnknownServiceException("Protocol " + url.getProtocol()
+ + " does not support output.");
+ }
+
+ /**
+ * The methods prints the value of this object as a String by calling the
+ * toString() method of its associated URL. Overrides Object.toString()
+ *
+ * @return A String representation of this object
+ */
+ public String toString()
+ {
+ return this.getClass().getName() + ":" + url.toString();
+ }
+
+ /**
+ * Sets the value of a flag indicating whether or not input is going
+ * to be done for this connection. This default to true unless the
+ * doOutput flag is set to false, in which case this defaults to false.
+ *
+ * @param input
+ * NOTE: Overriding MIME types sent from the server can be obnoxious
+ * to user's. See Internet Exploder 4 if you don't believe me.
+ *
+ * @param is The InputStream to determine the MIME type from
+ *
+ * @return The MIME type
+ *
+ * @exception IOException If an error occurs
+ */
+ public static String guessContentTypeFromStream(InputStream is)
+ throws IOException
+ {
+ String result = VMURLConnection.guessContentTypeFromStream(is);
+ if (result == null)
+ return "application/octet-stream";
+ return result;
+ }
+
+ /**
+ * This method returns the
+ * This method is very useful for decoding strings sent to CGI scripts
+ *
+ * Written using on-line Java Platform 1.2/1.4 API Specification.
+ * Status: Believed complete and correct.
+ *
+ * @since 1.2
+ *
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Aaron M. Renn (arenn@urbanophile.com) (documentation comments)
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+public class URLDecoder
+{
+ /**
+ * Public contructor. Note that this class has only static methods.
+ */
+ public URLDecoder()
+ {
+ }
+
+ /**
+ * This method translates the passed in string from x-www-form-urlencoded
+ * format using the default encoding "UTF-8" to decode the hex encoded
+ * unsafe characters.
+ *
+ * @param s the String to convert
+ *
+ * @return the converted String
+ *
+ * @deprecated
+ */
+ public static String decode(String s)
+ {
+ try
+ {
+ return decode(s, "UTF-8");
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ // Should never happen since UTF-8 encoding should always be supported
+ return s;
+ }
+ }
+
+ /**
+ * This method translates the passed in string from x-www-form-urlencoded
+ * format using the given character encoding to decode the hex encoded
+ * unsafe characters.
+ *
+ * This implementation will decode the string even if it contains
+ * unsafe characters (characters that should have been encoded) or if the
+ * two characters following a % do not represent a hex encoded byte.
+ * In those cases the unsafe character or the % character will be added
+ * verbatim to the decoded result.
+ *
+ * @param s the String to convert
+ * @param encoding the character encoding to use the decode the hex encoded
+ * unsafe characters
+ *
+ * @return the converted String
+ *
+ * @exception UnsupportedEncodingException If the named encoding is not
+ * supported
+ *
+ * @since 1.4
+ */
+ public static String decode(String s, String encoding)
+ throws UnsupportedEncodingException
+ {
+ // First convert all '+' characters to spaces.
+ String str = s.replace('+', ' ');
+
+ // Then go through the whole string looking for byte encoded characters
+ int i;
+ int start = 0;
+ byte[] bytes = null;
+ int length = str.length();
+ CPStringBuilder result = new CPStringBuilder(length);
+ while ((i = str.indexOf('%', start)) >= 0)
+ {
+ // Add all non-encoded characters to the result buffer
+ result.append(str.substring(start, i));
+ start = i;
+
+ // Get all consecutive encoded bytes
+ while ((i + 2 < length) && (str.charAt(i) == '%'))
+ i += 3;
+
+ // Decode all these bytes
+ if ((bytes == null) || (bytes.length < ((i - start) / 3)))
+ bytes = new byte[((i - start) / 3)];
+
+ int index = 0;
+ try
+ {
+ while (start < i)
+ {
+ String sub = str.substring(start + 1, start + 3);
+ bytes[index] = (byte) Integer.parseInt(sub, 16);
+ index++;
+ start += 3;
+ }
+ }
+ catch (NumberFormatException nfe)
+ {
+ // One of the hex encoded strings was bad
+ }
+
+ // Add the bytes as characters according to the given encoding
+ result.append(new String(bytes, 0, index, encoding));
+
+ // Make sure we skip to just after a % sign
+ // There might not have been enough encoded characters after the %
+ // or the hex chars were not actually hex chars (NumberFormatException)
+ if (start < length && s.charAt(start) == '%')
+ {
+ result.append('%');
+ start++;
+ }
+ }
+
+ // Add any characters left
+ if (start < str.length())
+ result.append(str.substring(start));
+
+ return result.toString();
+ }
+} // class URLDecoder
diff --git a/libjava/classpath/java/net/URLEncoder.java b/libjava/classpath/java/net/URLEncoder.java
new file mode 100644
index 000000000..09c0f3de0
--- /dev/null
+++ b/libjava/classpath/java/net/URLEncoder.java
@@ -0,0 +1,186 @@
+/* URLEncoder.java -- Class to convert strings to a properly encoded URL
+ Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.io.UnsupportedEncodingException;
+
+
+/*
+ * Written using on-line Java Platform 1.2/1.4 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This utility class contains static methods that converts a
+ * string into a fully encoded URL string in x-www-form-urlencoded
+ * format. This format replaces certain disallowed characters with
+ * encoded equivalents. All upper case and lower case letters in the
+ * US alphabet remain as is, the space character (' ') is replaced with
+ * '+' sign, and all other characters are converted to a "%XX" format
+ * where XX is the hexadecimal representation of that character in a
+ * certain encoding (by default, the platform encoding, though the
+ * standard is "UTF-8").
+ *
+ * This method is very useful for encoding strings to be sent to CGI scripts
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Mark Wielaard (mark@klomp.org)
+ */
+public class URLEncoder
+{
+ /**
+ * This method translates the passed in string into x-www-form-urlencoded
+ * format using the default encoding. The standard encoding is
+ * "UTF-8", and the two-argument form of this method should be used
+ * instead.
+ *
+ * @param s The String to convert
+ *
+ * @return The converted String
+ *
+ * @deprecated
+ */
+ public static String encode(String s)
+ {
+ try
+ {
+ // We default to 8859_1 for compatibility with the same
+ // default elsewhere in the library.
+ return encode(s, System.getProperty("file.encoding", "8859_1"));
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ // Should never happen since default should always be supported
+ return s;
+ }
+ }
+
+ /**
+ * This method translates the passed in string into x-www-form-urlencoded
+ * format using the character encoding to hex-encode the unsafe characters.
+ *
+ * @param s The String to convert
+ * @param encoding The encoding to use for unsafe characters
+ *
+ * @return The converted String
+ *
+ * @exception UnsupportedEncodingException If the named encoding is not
+ * supported
+ *
+ * @since 1.4
+ */
+ public static String encode(String s, String encoding)
+ throws UnsupportedEncodingException
+ {
+ int length = s.length();
+ int start = 0;
+ int i = 0;
+
+ CPStringBuilder result = new CPStringBuilder(length);
+ while (true)
+ {
+ while (i < length && isSafe(s.charAt(i)))
+ i++;
+
+ // Safe character can just be added
+ result.append(s.substring(start, i));
+
+ // Are we done?
+ if (i >= length)
+ return result.toString();
+ else if (s.charAt(i) == ' ')
+ {
+ result.append('+'); // Replace space char with plus symbol.
+ i++;
+ }
+ else
+ {
+ // Get all unsafe characters
+ start = i;
+ char c;
+ while (i < length && (c = s.charAt(i)) != ' ' && ! isSafe(c))
+ i++;
+
+ // Convert them to %XY encoded strings
+ String unsafe = s.substring(start, i);
+ byte[] bytes = unsafe.getBytes(encoding);
+ for (int j = 0; j < bytes.length; j++)
+ {
+ result.append('%');
+ int val = bytes[j];
+ result.append(hex.charAt((val & 0xf0) >> 4));
+ result.append(hex.charAt(val & 0x0f));
+ }
+ }
+ start = i;
+ }
+ }
+
+ /**
+ * Private static method that returns true if the given char is either
+ * a uppercase or lowercase letter from 'a' till 'z', or a digit froim
+ * '0' till '9', or one of the characters '-', '_', '.' or '*'. Such
+ * 'safe' character don't have to be url encoded.
+ */
+ private static boolean isSafe(char c)
+ {
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.'
+ || c == '*');
+ }
+
+ /**
+ * Private constructor that does nothing. Included to avoid a default
+ * public constructor being created by the compiler.
+ */
+ private URLEncoder()
+ {
+ }
+
+ /**
+ * Used to convert to hex. We don't use Integer.toHexString, since
+ * it converts to lower case (and the Sun docs pretty clearly
+ * specify upper case here), and because it doesn't provide a
+ * leading 0.
+ */
+ private static final String hex = "0123456789ABCDEF";
+}
diff --git a/libjava/classpath/java/net/URLStreamHandler.java b/libjava/classpath/java/net/URLStreamHandler.java
new file mode 100644
index 000000000..5433aedd9
--- /dev/null
+++ b/libjava/classpath/java/net/URLStreamHandler.java
@@ -0,0 +1,541 @@
+/* URLStreamHandler.java -- Abstract superclass for all protocol handlers
+ Copyright (C) 1998, 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.io.File;
+import java.io.IOException;
+
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+/**
+ * This class is the superclass of all URL protocol handlers. The URL
+ * class loads the appropriate protocol handler to establish a connection
+ * to a (possibly) remote service (eg, "http", "ftp") and to do protocol
+ * specific parsing of URL's. Refer to the URL class documentation for
+ * details on how that class locates and loads protocol handlers.
+ *
+ * A protocol handler implementation should override the openConnection()
+ * method, and optionally override the parseURL() and toExternalForm()
+ * methods if necessary. (The default implementations will parse/write all
+ * URL's in the same form as http URL's). A protocol specific subclass
+ * of URLConnection will most likely need to be created as well.
+ *
+ * Note that the instance methods in this class are called as if they
+ * were static methods. That is, a URL object to act on is passed with
+ * every call rather than the caller assuming the URL is stored in an
+ * instance variable of the "this" object.
+ *
+ * The methods in this class are protected and accessible only to subclasses.
+ * URLStreamConnection objects are intended for use by the URL class only,
+ * not by other classes (unless those classes are implementing protocols).
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ *
+ * @see URL
+ */
+public abstract class URLStreamHandler
+{
+ /**
+ * Creates a URLStreamHander
+ */
+ public URLStreamHandler()
+ {
+ }
+
+ /**
+ * Returns a URLConnection for the passed in URL. Note that this should
+ * not actually create the connection to the (possibly) remote host, but
+ * rather simply return a URLConnection object. The connect() method of
+ * URL connection is used to establish the actual connection, possibly
+ * after the caller sets up various connection options.
+ *
+ * @param url The URL to get a connection object for
+ *
+ * @return A URLConnection object for the given URL
+ *
+ * @exception IOException If an error occurs
+ */
+ protected abstract URLConnection openConnection(URL url)
+ throws IOException;
+
+ /**
+ * This method parses the string passed in as a URL and set's the
+ * instance data fields in the URL object passed in to the various values
+ * parsed out of the string. The start parameter is the position to start
+ * scanning the string. This is usually the position after the ":" which
+ * terminates the protocol name. The end parameter is the position to
+ * stop scanning. This will be either the end of the String, or the
+ * position of the "#" character, which separates the "file" portion of
+ * the URL from the "anchor" portion.
+ *
+ * This method assumes URL's are formatted like http protocol URL's, so
+ * subclasses that implement protocols with URL's the follow a different
+ * syntax should override this method. The lone exception is that if
+ * the protocol name set in the URL is "file", this method will accept
+ * an empty hostname (i.e., "file:///"), which is legal for that protocol
+ *
+ * @param url The URL object in which to store the results
+ * @param spec The String-ized URL to parse
+ * @param start The position in the string to start scanning from
+ * @param end The position in the string to stop scanning
+ */
+ protected void parseURL(URL url, String spec, int start, int end)
+ {
+ String host = url.getHost();
+ int port = url.getPort();
+ String file = url.getFile();
+ String ref = url.getRef();
+ String userInfo = url.getUserInfo();
+ String authority = url.getAuthority();
+ String query = null;
+
+ // On Windows we need to change \ to / for file URLs
+ char separator = File.separatorChar;
+ if (url.getProtocol().equals("file") && separator != '/')
+ {
+ file = file.replace(separator, '/');
+ spec = spec.replace(separator, '/');
+ }
+
+ if (spec.regionMatches(start, "//", 0, 2))
+ {
+ String genuineHost;
+ int hostEnd;
+ int colon;
+ int at_host;
+
+ start += 2;
+ int slash = spec.indexOf('/', start);
+ if (slash >= 0)
+ hostEnd = slash;
+ else
+ hostEnd = end;
+
+ authority = host = spec.substring(start, hostEnd);
+
+ // We first need a genuine host name (with userinfo).
+ // So we check for '@': if it's present check the port in the
+ // section after '@' in the other case check it in the full string.
+ // P.S.: We don't care having '@' at the beginning of the string.
+ if ((at_host = host.indexOf('@')) >= 0)
+ {
+ genuineHost = host.substring(at_host);
+ userInfo = host.substring(0, at_host);
+ }
+ else
+ genuineHost = host;
+
+ // Look for optional port number. It is valid for the non-port
+ // part of the host name to be null (e.g. a URL "http://:80").
+ // TBD: JDK 1.2 in this case sets host to null rather than "";
+ // this is undocumented and likely an unintended side effect in 1.2
+ // so we'll be simple here and stick with "". Note that
+ // "http://" or "http:///" produce a "" host in JDK 1.2.
+ if ((colon = genuineHost.indexOf(':')) >= 0)
+ {
+ try
+ {
+ port = Integer.parseInt(genuineHost.substring(colon + 1));
+ }
+ catch (NumberFormatException e)
+ {
+ // Ignore invalid port values; port is already set to u's
+ // port.
+ }
+
+ // Now we must cut the port number in the original string.
+ if (at_host >= 0)
+ host = host.substring(0, at_host + colon);
+ else
+ host = host.substring(0, colon);
+ }
+ file = null;
+ start = hostEnd;
+ }
+ else if (host == null)
+ host = "";
+
+ if (file == null || file.length() == 0
+ || (start < end && spec.charAt(start) == '/'))
+ {
+ // No file context available; just spec for file.
+ // Or this is an absolute path name; ignore any file context.
+ file = spec.substring(start, end);
+ ref = null;
+ }
+ else if (start < end)
+ {
+ // Context is available, but only override it if there is a new file.
+ int lastSlash = file.lastIndexOf('/');
+ if (lastSlash < 0)
+ file = spec.substring(start, end);
+ else
+ file = (file.substring(0, lastSlash)
+ + '/' + spec.substring(start, end));
+
+ // For URLs constructed relative to a context, we
+ // need to canonicalise the file path.
+ file = canonicalizeFilename(file);
+
+ ref = null;
+ }
+
+ if (ref == null)
+ {
+ // Normally there should be no '#' in the file part,
+ // but we are nice.
+ int hash = file.indexOf('#');
+ if (hash != -1)
+ {
+ ref = file.substring(hash + 1, file.length());
+ file = file.substring(0, hash);
+ }
+ }
+
+ // We care about the query tag only if there is no reference at all.
+ if (ref == null)
+ {
+ int queryTag = file.indexOf('?');
+ if (queryTag != -1)
+ {
+ query = file.substring(queryTag + 1);
+ file = file.substring(0, queryTag);
+ }
+ }
+
+ // XXX - Classpath used to call PlatformHelper.toCanonicalForm() on
+ // the file part. It seems like overhead, but supposedly there is some
+ // benefit in windows based systems (it also lowercased the string).
+ setURL(url, url.getProtocol(), host, port, authority, userInfo, file, query, ref);
+ }
+
+ /*
+ * Canonicalize a filename.
+ */
+ private static String canonicalizeFilename(String file)
+ {
+ // XXX - GNU Classpath has an implementation that might be more appropriate
+ // for Windows based systems (gnu.java.io.PlatformHelper.toCanonicalForm)
+ int index;
+
+ // Replace "/./" with "/". This probably isn't very efficient in
+ // the general case, but it's probably not bad most of the time.
+ while ((index = file.indexOf("/./")) >= 0)
+ file = file.substring(0, index) + file.substring(index + 2);
+
+ // Process "/../" correctly. This probably isn't very efficient in
+ // the general case, but it's probably not bad most of the time.
+ while ((index = file.indexOf("/../")) >= 0)
+ {
+ // Strip of the previous directory - if it exists.
+ int previous = file.lastIndexOf('/', index - 1);
+ if (previous >= 0)
+ file = file.substring(0, previous) + file.substring(index + 3);
+ else
+ break;
+ }
+ return file;
+ }
+
+ /**
+ * Compares two URLs, excluding the fragment component
+ *
+ * @param url1 The first url
+ * @param url2 The second url to compare with the first
+ *
+ * @return True if both URLs point to the same file, false otherwise.
+ *
+ * @specnote Now protected
+ */
+ protected boolean sameFile(URL url1, URL url2)
+ {
+ if (url1 == url2)
+ return true;
+
+ // This comparison is very conservative. It assumes that any
+ // field can be null.
+ if (url1 == null || url2 == null)
+ return false;
+ int p1 = url1.getPort();
+ if (p1 == -1)
+ p1 = url1.ph.getDefaultPort();
+ int p2 = url2.getPort();
+ if (p2 == -1)
+ p2 = url2.ph.getDefaultPort();
+ if (p1 != p2)
+ return false;
+ String s1;
+ String s2;
+ s1 = url1.getProtocol();
+ s2 = url2.getProtocol();
+ if (s1 != s2 && (s1 == null || ! s1.equals(s2)))
+ return false;
+ s1 = url1.getHost();
+ s2 = url2.getHost();
+ if (s1 != s2 && (s1 == null || ! s1.equals(s2)))
+ return false;
+ s1 = canonicalizeFilename(url1.getFile());
+ s2 = canonicalizeFilename(url2.getFile());
+ if (s1 != s2 && (s1 == null || ! s1.equals(s2)))
+ return false;
+ return true;
+ }
+
+ /**
+ * This methods sets the instance variables representing the various fields
+ * of the URL to the values passed in.
+ *
+ * @param u The URL to modify
+ * @param protocol The protocol to set
+ * @param host The host name to et
+ * @param port The port number to set
+ * @param file The filename to set
+ * @param ref The reference
+ *
+ * @exception SecurityException If the protocol handler of the URL is
+ * different from this one
+ *
+ * @deprecated 1.2 Please use
+ * #setURL(URL,String,String,int,String,String,String,String);
+ */
+ protected void setURL(URL u, String protocol, String host, int port,
+ String file, String ref)
+ {
+ u.set(protocol, host, port, file, ref);
+ }
+
+ /**
+ * Sets the fields of the URL argument to the indicated values
+ *
+ * @param u The URL to modify
+ * @param protocol The protocol to set
+ * @param host The host name to set
+ * @param port The port number to set
+ * @param authority The authority to set
+ * @param userInfo The user information to set
+ * @param path The path/filename to set
+ * @param query The query part to set
+ * @param ref The reference
+ *
+ * @exception SecurityException If the protocol handler of the URL is
+ * different from this one
+ */
+ protected void setURL(URL u, String protocol, String host, int port,
+ String authority, String userInfo, String path,
+ String query, String ref)
+ {
+ u.set(protocol, host, port, authority, userInfo, path, query, ref);
+ }
+
+ /**
+ * This is the default method for computing whether two URLs are
+ * equivalent. This method assumes that neither URL is null.
+ *
+ * @param url1 An URL object
+ * @param url2 Another URL object
+ *
+ * @return True if both given URLs are equal, false otherwise.
+ */
+ protected boolean equals(URL url1, URL url2)
+ {
+ // This comparison is very conservative. It assumes that any
+ // field can be null.
+ int port1 = url1.getPort();
+ if (port1 == -1)
+ port1 = url1.getDefaultPort();
+ int port2 = url2.getPort();
+ if (port2 == -1)
+ port2 = url2.getDefaultPort();
+ // Note that we don't bother checking the 'authority'; it is
+ // redundant.
+ return (port1 == port2
+ && ((url1.getProtocol() == null && url2.getProtocol() == null)
+ || (url1.getProtocol() != null
+ && url1.getProtocol().equals(url2.getProtocol())))
+ && ((url1.getUserInfo() == null && url2.getUserInfo() == null)
+ || (url1.getUserInfo() != null
+ && url1.getUserInfo().equals(url2.getUserInfo())))
+ && ((url1.getHost() == null && url2.getHost() == null)
+ || (url1.getHost() != null && url1.getHost().equals(url2.getHost())))
+ && ((url1.getPath() == null && url2.getPath() == null)
+ || (url1.getPath() != null && url1.getPath().equals(url2.getPath())))
+ && ((url1.getQuery() == null && url2.getQuery() == null)
+ || (url1.getQuery() != null
+ && url1.getQuery().equals(url2.getQuery())))
+ && ((url1.getRef() == null && url2.getRef() == null)
+ || (url1.getRef() != null && url1.getRef().equals(url2.getRef()))));
+ }
+
+ /**
+ * Compares the host components of two URLs.
+ *
+ * @param url1 The first URL.
+ * @param url2 The second URL.
+ *
+ * @return True if both URLs contain the same host.
+ */
+ protected boolean hostsEqual(URL url1, URL url2)
+ {
+ InetAddress addr1 = getHostAddress(url1);
+ InetAddress addr2 = getHostAddress(url2);
+
+ if (addr1 != null && addr2 != null)
+ return addr1.equals(addr2);
+
+ String host1 = url1.getHost();
+ String host2 = url2.getHost();
+
+ if (host1 != null && host2 != null)
+ return host1.equalsIgnoreCase(host2);
+
+ return host1 == null && host2 == null;
+ }
+
+ /**
+ * Get the IP address of our host. An empty host field or a DNS failure will
+ * result in a null return.
+ *
+ * @param url The URL to return the host address for.
+ *
+ * @return The address of the hostname in url.
+ */
+ protected InetAddress getHostAddress(URL url)
+ {
+ String hostname = url.getHost();
+
+ if (hostname.equals(""))
+ return null;
+
+ try
+ {
+ return InetAddress.getByName(hostname);
+ }
+ catch (UnknownHostException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the default port for a URL parsed by this handler. This method is
+ * meant to be overidden by handlers with default port numbers.
+ *
+ * @return The default port number.
+ */
+ protected int getDefaultPort()
+ {
+ return -1;
+ }
+
+ /**
+ * Provides the default hash calculation. May be overidden by handlers for
+ * other protocols that have different requirements for hashCode calculation.
+ *
+ * @param url The URL to calc the hashcode for.
+ *
+ * @return The hashcode for the given URL.
+ */
+ protected int hashCode(URL url)
+ {
+ return url.getProtocol().hashCode()
+ + ((url.getHost() == null) ? 0 : url.getHost().hashCode())
+ + url.getFile().hashCode() + url.getPort();
+ }
+
+ /**
+ * This method converts a URL object into a String. This method creates
+ * Strings in the mold of http URL's, so protocol handlers which use URL's
+ * that have a different syntax should override this method
+ *
+ * @param url The URL object to convert
+ *
+ * @return A string representation of the url
+ */
+ protected String toExternalForm(URL url)
+ {
+ String protocol;
+ String file;
+ String ref;
+ String authority;
+
+ protocol = url.getProtocol();
+ authority = url.getAuthority();
+ if (authority == null)
+ authority = "";
+
+ file = url.getFile();
+ ref = url.getRef();
+
+ // Guess a reasonable size for the string buffer so we have to resize
+ // at most once.
+ int size = protocol.length() + authority.length() + file.length() + 24;
+ CPStringBuilder sb = new CPStringBuilder(size);
+
+ if (protocol.length() > 0)
+ {
+ sb.append(protocol);
+ sb.append(":");
+ }
+
+ // If we have superfluous leading slashes (that means, at least 2)
+ // we always add the authority component ("//" + host) to
+ // avoid ambiguity. Otherwise we would generate an URL like
+ // proto://home/foo
+ // where we meant:
+ // host: Network communication through TCP and UDP sockets or URLs.joe@some.host.net
.
+ */
+ private String host;
+
+ /**
+ * The user information necessary to establish the connection.
+ */
+ private String userInfo;
+
+ /**
+ * The port number of this protocol or -1 if the port number used is
+ * the default for this protocol.
+ */
+ private int port = -1; // Initialize for constructor using context.
+
+ /**
+ * The "file" portion of the URL. It is defined as path[?query]
.
+ */
+ private String file;
+
+ /**
+ * The anchor portion of the URL.
+ */
+ private String ref;
+
+ /**
+ * This is the hashCode for this URL
+ */
+ private int hashCode;
+
+ /**
+ * The protocol handler in use for this URL
+ */
+ transient URLStreamHandler ph;
+
+ /**
+ * If an application installs its own protocol handler factory, this is
+ * where we keep track of it.
+ */
+ private static URLStreamHandlerFactory factory;
+ private static final long serialVersionUID = -7627629688361524110L;
+
+ /**
+ * This a table where we cache protocol handlers to avoid the overhead
+ * of looking them up each time.
+ */
+ private static HashMapURL
with the
+ * specified protocol, host, port, and file. Additionally, this method
+ * allows the caller to specify a protocol handler to use instead of
+ * the default. If this handler is specified, the caller must have
+ * the "specifyStreamHandler" permission (see NetPermission
)
+ * or a SecurityException
will be thrown.
+ *
+ * @param protocol The protocol for this URL ("http", "ftp", etc)
+ * @param host The hostname or IP address to connect to
+ * @param port The port number to use, or -1 to use the protocol's default
+ * port
+ * @param file The "file" portion of the URL.
+ * @param ph The protocol handler to use with this URL.
+ *
+ * @exception MalformedURLException If no protocol handler can be loaded
+ * for the specified protocol.
+ * @exception SecurityException If the SecurityManager
exists
+ * and does not allow the caller to specify its own protocol handler.
+ *
+ * @since 1.2
+ */
+ public URL(String protocol, String host, int port, String file,
+ URLStreamHandler ph) throws MalformedURLException
+ {
+ if (protocol == null)
+ throw new MalformedURLException("null protocol");
+ protocol = protocol.toLowerCase();
+ this.protocol = protocol;
+
+ if (ph != null)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+ this.ph = ph;
+ }
+ else
+ this.ph = getURLStreamHandler(protocol);
+
+ if (this.ph == null)
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
+
+ this.host = host;
+ this.port = port;
+ this.authority = (host != null) ? host : "";
+ if (port >= 0 && host != null)
+ this.authority += ":" + port;
+
+ int hashAt = file.indexOf('#');
+ if (hashAt < 0)
+ {
+ this.file = file;
+ this.ref = null;
+ }
+ else
+ {
+ this.file = file.substring(0, hashAt);
+ this.ref = file.substring(hashAt + 1);
+ }
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Initializes a URL from a complete string specification such as
+ * "http://www.urbanophile.com/arenn/". First the protocol name is parsed
+ * out of the string. Then a handler is located for that protocol and
+ * the parseURL() method of that protocol handler is used to parse the
+ * remaining fields.
+ *
+ * @param spec The complete String representation of a URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * or the URL cannot be parsed
+ */
+ public URL(String spec) throws MalformedURLException
+ {
+ this((URL) null, spec != null ? spec : "", (URLStreamHandler) null,
+ false);
+ }
+
+ /**
+ * This method parses a String representation of a URL within the
+ * context of an existing URL. Principally this means that any
+ * fields not present the URL are inheritied from the context URL.
+ * This allows relative URL's to be easily constructed. If the
+ * context argument is null, then a complete URL must be specified
+ * in the URL string. If the protocol parsed out of the URL is
+ * different from the context URL's protocol, then then URL String
+ * is also expected to be a complete URL.
+ *
+ * @param context The context on which to parse the specification
+ * @param spec The string to parse an URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * for the URL cannot be parsed
+ */
+ public URL(URL context, String spec) throws MalformedURLException
+ {
+ this(context, spec,
+ (context == null) ? (URLStreamHandler) null : context.ph,
+ false);
+ }
+
+ /**
+ * Creates an URL from given arguments
+ * This method parses a String representation of a URL within the
+ * context of an existing URL. Principally this means that any fields
+ * not present the URL are inheritied from the context URL. This allows
+ * relative URL's to be easily constructed. If the context argument is
+ * null, then a complete URL must be specified in the URL string.
+ * If the protocol parsed out of the URL is different
+ * from the context URL's protocol, then then URL String is also
+ * expected to be a complete URL.
+ * NetPermission
) or a SecurityException
+ * will be thrown.
+ *
+ * @param context The context in which to parse the specification
+ * @param spec The string to parse as an URL
+ * @param ph The stream handler for the URL
+ *
+ * @exception MalformedURLException If a protocol handler cannot be found
+ * or the URL cannot be parsed
+ * @exception SecurityException If the SecurityManager
exists
+ * and does not allow the caller to specify its own protocol handler.
+ *
+ * @since 1.2
+ */
+ public URL(URL context, String spec, URLStreamHandler ph)
+ throws MalformedURLException
+ {
+ this(context, spec, ph, true);
+ }
+
+ /**
+ * Private constructor called by all other constructors taking
+ * a context and spec.
+ *
+ * @param context The context in which to parse the specification
+ * @param spec The string to parse as an URL
+ * @param ph The stream handler for the URL
+ * @param phFromUser Whether or not the user supplied the URLStreamHandler
+ *
+ */
+ private URL(URL context, String spec, URLStreamHandler ph,
+ boolean phFromUser)
+ throws MalformedURLException
+ {
+ /* A protocol is defined by the doc as the substring before a ':'
+ * as long as the ':' occurs before any '/'.
+ *
+ * If context is null, then spec must be an absolute URL.
+ *
+ * The relative URL need not specify all the components of a URL.
+ * If the protocol, host name, or port number is missing, the value
+ * is inherited from the context. A bare file component is appended
+ * to the context's file. The optional anchor is not inherited.
+ */
+
+ // If this is an absolute URL, then ignore context completely.
+ // An absolute URL must have chars prior to "://" but cannot have a colon
+ // right after the "://". The second colon is for an optional port value
+ // and implies that the host from the context is used if available.
+ int colon;
+ int slash = spec.indexOf('/');
+ if ((colon = spec.indexOf("://", 1)) > 0
+ && ((colon < slash || slash < 0))
+ && ! spec.regionMatches(colon, "://:", 0, 4))
+ {
+ context = null;
+ if (! phFromUser)
+ ph = null;
+ }
+
+ boolean protocolSpecified = false;
+
+ if ((colon = spec.indexOf(':')) > 0
+ && (colon < slash || slash < 0))
+ {
+ // Protocol may have been specified in spec string.
+ protocolSpecified = true;
+ protocol = spec.substring(0, colon).toLowerCase();
+ if (context != null)
+ {
+ if (context.protocol.equals(protocol))
+ {
+ // The 1.2 doc specifically says these are copied to the new URL.
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ authority = context.authority;
+ }
+ else
+ {
+ // There was a colon in the spec. Check to see if
+ // what precedes it is a valid protocol. If it was
+ // not, assume that it is relative to the context.
+ URLStreamHandler specPh = getURLStreamHandler(protocol.trim());
+ if (null == specPh)
+ protocolSpecified = false;
+ }
+ }
+ }
+
+ if (!protocolSpecified)
+ {
+ if (context != null)
+ {
+ // Protocol NOT specified in spec string.
+ // Use context fields (except ref) as a foundation for relative URLs.
+ colon = -1;
+ protocol = context.protocol;
+ host = context.host;
+ port = context.port;
+ userInfo = context.userInfo;
+ if (spec.indexOf(":/", 1) < 0)
+ {
+ file = context.file;
+ if (file == null || file.length() == 0)
+ file = "/";
+ }
+ authority = context.authority;
+ }
+ else // Protocol NOT specified in spec. and no context available.
+ throw new MalformedURLException("Absolute URL required with null"
+ + " context: " + spec);
+ }
+
+ protocol = protocol.trim();
+
+ if (ph != null)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null && phFromUser)
+ s.checkPermission(new NetPermission("specifyStreamHandler"));
+
+ this.ph = ph;
+ }
+ else
+ this.ph = getURLStreamHandler(protocol);
+
+ if (this.ph == null)
+ throw new MalformedURLException("Protocol handler not found: "
+ + protocol);
+
+ // JDK 1.2 doc for parseURL specifically states that any '#' ref
+ // is to be excluded by passing the 'limit' as the indexOf the '#'
+ // if one exists, otherwise pass the end of the string.
+ int hashAt = spec.indexOf('#', colon + 1);
+
+ try
+ {
+ this.ph.parseURL(this, spec, colon + 1,
+ hashAt < 0 ? spec.length() : hashAt);
+ }
+ catch (URLParseError e)
+ {
+ MalformedURLException mue = new MalformedURLException(e.getMessage());
+ mue.initCause(e);
+ throw mue;
+ }
+ catch (RuntimeException e)
+ {
+ // This isn't documented, but the JDK also catches
+ // RuntimeExceptions here.
+ MalformedURLException mue = new MalformedURLException(e.getMessage());
+ mue.initCause(e);
+ throw mue;
+ }
+
+ if (hashAt >= 0)
+ ref = spec.substring(hashAt + 1);
+
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Test another URL for equality with this one. This will be true only if
+ * the argument is non-null and all of the fields in the URL's match
+ * exactly (ie, protocol, host, port, file, and ref). Overrides
+ * Object.equals(), implemented by calling the equals method of the handler.
+ *
+ * @param obj The URL to compare with
+ *
+ * @return true if the URL is equal, false otherwise
+ */
+ public boolean equals(Object obj)
+ {
+ if (! (obj instanceof URL))
+ return false;
+
+ return ph.equals(this, (URL) obj);
+ }
+
+ /**
+ * Returns the contents of this URL as an object by first opening a
+ * connection, then calling the getContent() method against the connection
+ *
+ * @return A content object for this URL
+ * @exception IOException If opening the connection or getting the
+ * content fails.
+ *
+ * @since 1.3
+ */
+ public Object getContent() throws IOException
+ {
+ return openConnection().getContent();
+ }
+
+ /**
+ * Gets the contents of this URL
+ *
+ * @param classes The allow classes for the content object.
+ *
+ * @return a context object for this URL.
+ *
+ * @exception IOException If an error occurs
+ */
+ public Object getContent(Class[] classes) throws IOException
+ {
+ return openConnection().getContent(classes);
+ }
+
+ /**
+ * Returns the file portion of the URL.
+ * Defined as path[?query]
.
+ * Returns the empty string if there is no file portion.
+ *
+ * @return The filename specified in this URL, or an empty string if empty.
+ */
+ public String getFile()
+ {
+ return file == null ? "" : file;
+ }
+
+ /**
+ * Returns the path of the URL. This is the part of the file before any '?'
+ * character.
+ *
+ * @return The path specified in this URL, or null if empty.
+ *
+ * @since 1.3
+ */
+ public String getPath()
+ {
+ // The spec says we need to return an empty string, but some
+ // applications depends on receiving null when the path is empty.
+ if (file == null)
+ return null;
+ int quest = file.indexOf('?');
+ return quest < 0 ? getFile() : file.substring(0, quest);
+ }
+
+ /**
+ * Returns the authority of the URL
+ *
+ * @return The authority specified in this URL.
+ *
+ * @since 1.3
+ */
+ public String getAuthority()
+ {
+ return authority;
+ }
+
+ /**
+ * Returns the host of the URL
+ *
+ * @return The host specified in this URL.
+ */
+ public String getHost()
+ {
+ int at = (host == null) ? -1 : host.indexOf('@');
+ return at < 0 ? host : host.substring(at + 1, host.length());
+ }
+
+ /**
+ * Returns the port number of this URL or -1 if the default port number is
+ * being used.
+ *
+ * @return The port number
+ *
+ * @see #getDefaultPort()
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Returns the default port of the URL. If the StreamHandler for the URL
+ * protocol does not define a default port it returns -1.
+ *
+ * @return The default port of the current protocol.
+ */
+ public int getDefaultPort()
+ {
+ return ph.getDefaultPort();
+ }
+
+ /**
+ * Returns the protocol of the URL
+ *
+ * @return The specified protocol.
+ */
+ public String getProtocol()
+ {
+ return protocol;
+ }
+
+ /**
+ * Returns the ref (sometimes called the "# reference" or "anchor") portion
+ * of the URL.
+ *
+ * @return The ref
+ */
+ public String getRef()
+ {
+ return ref;
+ }
+
+ /**
+ * Returns the user information of the URL. This is the part of the host
+ * name before the '@'.
+ *
+ * @return the user at a particular host or null when no user defined.
+ */
+ public String getUserInfo()
+ {
+ if (userInfo != null)
+ return userInfo;
+ int at = (host == null) ? -1 : host.indexOf('@');
+ return at < 0 ? null : host.substring(0, at);
+ }
+
+ /**
+ * Returns the query of the URL. This is the part of the file before the
+ * '?'.
+ *
+ * @return the query part of the file, or null when there is no query part.
+ */
+ public String getQuery()
+ {
+ int quest = (file == null) ? -1 : file.indexOf('?');
+ return quest < 0 ? null : file.substring(quest + 1, file.length());
+ }
+
+ /**
+ * Returns a hashcode computed by the URLStreamHandler of this URL
+ *
+ * @return The hashcode for this URL.
+ */
+ public int hashCode()
+ {
+ if (hashCode != 0)
+ return hashCode; // Use cached value if available.
+ else
+ return ph.hashCode(this);
+ }
+
+ /**
+ * Returns a URLConnection object that represents a connection to the remote
+ * object referred to by the URL. The URLConnection is created by calling the
+ * openConnection() method of the protocol handler
+ *
+ * @return A URLConnection for this URL
+ *
+ * @exception IOException If an error occurs
+ */
+ public URLConnection openConnection() throws IOException
+ {
+ return ph.openConnection(this);
+ }
+
+ /**
+ * Opens a connection to this URL and returns an InputStream for reading
+ * from that connection
+ *
+ * @return An InputStream
for this URL.
+ *
+ * @exception IOException If an error occurs
+ */
+ public InputStream openStream() throws IOException
+ {
+ return openConnection().getInputStream();
+ }
+
+ /**
+ * Tests whether or not another URL refers to the same "file" as this one.
+ * This will be true if and only if the passed object is not null, is a
+ * URL, and matches all fields but the ref (ie, protocol, host, port,
+ * and file);
+ *
+ * @param url The URL object to test with
+ *
+ * @return true if URL matches this URL's file, false otherwise
+ */
+ public boolean sameFile(URL url)
+ {
+ return ph.sameFile(this, url);
+ }
+
+ /**
+ * Sets the specified fields of the URL. This is not a public method so
+ * that only URLStreamHandlers can modify URL fields. This might be called
+ * by the parseURL()
method in that class. URLs are otherwise
+ * constant. If the given protocol does not exist, it will keep the previously
+ * set protocol.
+ *
+ * @param protocol The protocol name for this URL
+ * @param host The hostname or IP address for this URL
+ * @param port The port number of this URL
+ * @param file The "file" portion of this URL.
+ * @param ref The anchor portion of this URL.
+ */
+ protected void set(String protocol, String host, int port, String file,
+ String ref)
+ {
+ URLStreamHandler protocolHandler = null;
+ protocol = protocol.toLowerCase();
+ if (! this.protocol.equals(protocol))
+ protocolHandler = getURLStreamHandler(protocol);
+
+ // It is an hidden feature of the JDK. If the protocol does not exist,
+ // we keep the previously initialized protocol.
+ if (protocolHandler != null)
+ {
+ this.ph = protocolHandler;
+ this.protocol = protocol;
+ }
+ this.authority = "";
+ this.port = port;
+ this.host = host;
+ this.file = file;
+ this.ref = ref;
+
+ if (host != null)
+ this.authority += host;
+ if (port >= 0)
+ this.authority += ":" + port;
+
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Sets the specified fields of the URL. This is not a public method so
+ * that only URLStreamHandlers can modify URL fields. URLs are otherwise
+ * constant. If the given protocol does not exist, it will keep the previously
+ * set protocol.
+ *
+ * @param protocol The protocol name for this URL.
+ * @param host The hostname or IP address for this URL.
+ * @param port The port number of this URL.
+ * @param authority The authority of this URL.
+ * @param userInfo The user and password (if needed) of this URL.
+ * @param path The "path" portion of this URL.
+ * @param query The query of this URL.
+ * @param ref The anchor portion of this URL.
+ *
+ * @since 1.3
+ */
+ protected void set(String protocol, String host, int port, String authority,
+ String userInfo, String path, String query, String ref)
+ {
+ URLStreamHandler protocolHandler = null;
+ protocol = protocol.toLowerCase();
+ if (! this.protocol.equals(protocol))
+ protocolHandler = getURLStreamHandler(protocol);
+
+ // It is an hidden feature of the JDK. If the protocol does not exist,
+ // we keep the previously initialized protocol.
+ if (protocolHandler != null)
+ {
+ this.ph = protocolHandler;
+ this.protocol = protocol;
+ }
+ this.host = host;
+ this.userInfo = userInfo;
+ this.port = port;
+ this.authority = authority;
+ if (query == null)
+ this.file = path;
+ else
+ this.file = path + "?" + query;
+ this.ref = ref;
+ hashCode = hashCode(); // Used for serialization.
+ }
+
+ /**
+ * Sets the URLStreamHandlerFactory for this class. This factory is
+ * responsible for returning the appropriate protocol handler for
+ * a given URL.
+ *
+ * @param fac The URLStreamHandlerFactory class to use
+ *
+ * @exception Error If the factory is alread set.
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ */
+ public static synchronized void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
+ {
+ if (factory != null)
+ throw new Error("URLStreamHandlerFactory already set");
+
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+ factory = fac;
+ }
+
+ /**
+ * Returns a String representing this URL. The String returned is
+ * created by calling the protocol handler's toExternalForm() method.
+ *
+ * @return A string for this URL
+ */
+ public String toExternalForm()
+ {
+ // Identical to toString().
+ return ph.toExternalForm(this);
+ }
+
+ /**
+ * Returns a String representing this URL. Identical to toExternalForm().
+ * The value returned is created by the protocol handler's
+ * toExternalForm method. Overrides Object.toString()
+ *
+ * @return A string for this URL
+ */
+ public String toString()
+ {
+ // Identical to toExternalForm().
+ return ph.toExternalForm(this);
+ }
+
+ /**
+ * This internal method is used in two different constructors to load
+ * a protocol handler for this URL.
+ *
+ * @param protocol The protocol to load a handler for
+ *
+ * @return A URLStreamHandler for this protocol, or null when not found.
+ */
+ private static synchronized URLStreamHandler getURLStreamHandler(String protocol)
+ {
+ URLStreamHandler ph = null;
+
+ // First, see if a protocol handler is in our cache.
+ if (cache_handlers)
+ {
+ if ((ph = ph_cache.get(protocol)) != null)
+ return ph;
+ }
+
+ // If a non-default factory has been set, use it to find the protocol.
+ if (factory != null)
+ {
+ ph = factory.createURLStreamHandler(protocol);
+ }
+
+ // Non-default factory may have returned null or a factory wasn't set.
+ // Use the default search algorithm to find a handler for this protocol.
+ if (ph == null)
+ {
+ // Get the list of packages to check and append our default handler
+ // to it, along with the JDK specified default as a last resort.
+ // Except in very unusual environments the JDK specified one shouldn't
+ // ever be needed (or available).
+ String ph_search_path =
+ SystemProperties.getProperty("java.protocol.handler.pkgs");
+
+ // Tack our default package on at the ends.
+ if (ph_search_path != null)
+ ph_search_path += "|" + DEFAULT_SEARCH_PATH;
+ else
+ ph_search_path = DEFAULT_SEARCH_PATH;
+
+ // Finally loop through our search path looking for a match.
+ StringTokenizer pkgPrefix = new StringTokenizer(ph_search_path, "|");
+
+ // Cache the systemClassLoader
+ if (systemClassLoader == null)
+ {
+ systemClassLoader = AccessController.doPrivileged
+ (new PrivilegedActionURI
object for this URL
.
+ * This is the same as calling new URI(this.toString())
.
+ * RFC2396-compliant URLs are guaranteed a successful conversion to
+ * a URI
instance. However, there are some values which
+ * form valid URLs, but which do not also form RFC2396-compliant URIs.
+ *
+ * @throws URISyntaxException if this URL is not RFC2396-compliant,
+ * and thus can not be successfully converted to a URI.
+ */
+ public URI toURI()
+ throws URISyntaxException
+ {
+ return new URI(toString());
+ }
+
+}
diff --git a/libjava/classpath/java/net/URLClassLoader.java b/libjava/classpath/java/net/URLClassLoader.java
new file mode 100644
index 000000000..418ee77f3
--- /dev/null
+++ b/libjava/classpath/java/net/URLClassLoader.java
@@ -0,0 +1,860 @@
+/* URLClassLoader.java -- ClassLoader that loads classes from one or more URLs
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import gnu.java.net.loader.FileURLLoader;
+import gnu.java.net.loader.JarURLLoader;
+import gnu.java.net.loader.RemoteURLLoader;
+import gnu.java.net.loader.Resource;
+import gnu.java.net.loader.URLLoader;
+import gnu.java.net.loader.URLStreamHandlerCache;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.SecureClassLoader;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+
+/**
+ * A secure class loader that can load classes and resources from
+ * multiple locations. Given an array of URL
s this class
+ * loader will retrieve classes and resources by fetching them from
+ * possible remote locations. Each URL
is searched in
+ * order in which it was added. If the file portion of the
+ * URL
ends with a '/' character then it is interpreted
+ * as a base directory, otherwise it is interpreted as a jar file from
+ * which the classes/resources are resolved.
+ *
+ * newInstance()
methods or by three public
+ * contructors. Both ways give the option to supply an initial array
+ * of URL
s and (optionally) a parent classloader (that is
+ * different from the standard system class loader).URLClassLoader
throws a
+ * SecurityException
if a SecurityManager
is
+ * installed and the checkCreateClassLoader()
method does
+ * not return true. But the newInstance()
methods may be
+ * used by any code as long as it has permission to acces the given
+ * URL
s. URLClassLoaders
created by the
+ * newInstance()
methods also explicitly call the
+ * checkPackageAccess()
method of
+ * SecurityManager
if one is installed before trying to
+ * load a class. Note that only subclasses of
+ * URLClassLoader
can add new URLs after the
+ * URLClassLoader had been created. But it is always possible to get
+ * an array of all URLs that the class loader uses to resolve classes
+ * and resources by way of the getURLs()
method.
+ *
+ *
+ * definePackage()
and sealing work
+ * precisely?newInstance()
but do we have to use it in more
+ * places?URLStreamHandler
s has not been tested.newInstance()
+ * or null when created through a normal constructor or when no
+ * SecurityManager
was installed.
+ */
+ private final AccessControlContext securityContext;
+
+ // Helper classes
+
+ /**
+ * Creates a URLClassLoader that gets classes from the supplied URLs.
+ * To determine if this classloader may be created the constructor of
+ * the super class (SecureClassLoader
) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the default parent ClassLoader).
+ *
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls) throws SecurityException
+ {
+ super();
+ this.factory = null;
+ this.securityContext = null;
+ addURLs(urls);
+ }
+
+ /**
+ * Creates a URLClassLoader
that gets classes from the supplied
+ * URL
s.
+ * To determine if this classloader may be created the constructor of
+ * the super class (SecureClassLoader
) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the supplied parent ClassLoader).
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @param parent The parent class loader used before trying this class
+ * loader.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @exception SecurityException
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls, ClassLoader parent)
+ throws SecurityException
+ {
+ super(parent);
+ this.factory = null;
+ this.securityContext = null;
+ addURLs(urls);
+ }
+
+ // Package-private to avoid a trampoline constructor.
+ /**
+ * Package-private constructor used by the static
+ * newInstance(URL[])
method. Creates an
+ * URLClassLoader
with the given parent but without any
+ * URL
s yet. This is used to bypass the normal security
+ * check for creating classloaders, but remembers the security
+ * context which will be used when defining classes. The
+ * URL
s to load from must be added by the
+ * newInstance()
method in the security context of the
+ * caller.
+ *
+ * @param securityContext the security context of the unprivileged code.
+ */
+ URLClassLoader(ClassLoader parent, AccessControlContext securityContext)
+ {
+ super(parent);
+ this.factory = null;
+ this.securityContext = securityContext;
+ }
+
+ /**
+ * Creates a URLClassLoader that gets classes from the supplied URLs.
+ * To determine if this classloader may be created the constructor of
+ * the super class (SecureClassLoader
) is called first, which
+ * can throw a SecurityException. Then the supplied URLs are added
+ * in the order given to the URLClassLoader which uses these URLs to
+ * load classes and resources (after using the supplied parent ClassLoader).
+ * It will use the supplied URLStreamHandlerFactory
to get the
+ * protocol handlers of the supplied URLs.
+ * @param urls Locations that should be searched by this ClassLoader when
+ * resolving Classes or Resources.
+ * @param parent The parent class loader used before trying this class
+ * loader.
+ * @param factory Used to get the protocol handler for the URLs.
+ * @exception SecurityException if the SecurityManager disallows the
+ * creation of a ClassLoader.
+ * @exception SecurityException
+ * @see SecureClassLoader
+ */
+ public URLClassLoader(URL[] urls, ClassLoader parent,
+ URLStreamHandlerFactory factory)
+ throws SecurityException
+ {
+ super(parent);
+ this.securityContext = null;
+ this.factory = factory;
+ // If this factory is not yet in factoryCache, add it.
+ factoryCache.add(factory);
+ addURLs(urls);
+ }
+
+ // Methods
+
+ /**
+ * Adds a new location to the end of the internal URL store.
+ * @param newUrl the location to add
+ */
+ protected void addURL(URL newUrl)
+ {
+ urls.add(newUrl);
+ addURLImpl(newUrl);
+ }
+
+ private void addURLImpl(URL newUrl)
+ {
+ synchronized (this)
+ {
+ if (newUrl == null)
+ return; // Silently ignore...
+
+ // Reset the toString() value.
+ thisString = null;
+
+ // Create a loader for this URL.
+ URLLoader loader = null;
+ String file = newUrl.getFile();
+ String protocol = newUrl.getProtocol();
+
+ // If we have a file: URL, we want to make it absolute
+ // here, before we decide whether it is really a jar.
+ URL absoluteURL;
+ if ("file".equals (protocol))
+ {
+ File dir = new File(file);
+ try
+ {
+ absoluteURL = dir.getCanonicalFile().toURL();
+ }
+ catch (IOException ignore)
+ {
+ try
+ {
+ absoluteURL = dir.getAbsoluteFile().toURL();
+ }
+ catch (MalformedURLException _)
+ {
+ // This really should not happen.
+ absoluteURL = newUrl;
+ }
+ }
+ }
+ else
+ {
+ // This doesn't hurt, and it simplifies the logic a
+ // little.
+ absoluteURL = newUrl;
+ }
+
+ // First see if we can find a handler with the correct name.
+ try
+ {
+ Class> handler = Class.forName(URL_LOADER_PREFIX + protocol);
+ Class>[] argTypes = new Class>[] { URLClassLoader.class,
+ URLStreamHandlerCache.class,
+ URLStreamHandlerFactory.class,
+ URL.class,
+ URL.class };
+ Constructor k = handler.getDeclaredConstructor(argTypes);
+ loader
+ = (URLLoader) k.newInstance(new Object[] { this,
+ factoryCache,
+ factory,
+ newUrl,
+ absoluteURL });
+ }
+ catch (ClassNotFoundException ignore)
+ {
+ // Fall through.
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("couldn't find URLLoader constructor");
+ vme.initCause(nsme);
+ throw vme;
+ }
+ catch (InstantiationException inste)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("couldn't instantiate URLLoader");
+ vme.initCause(inste);
+ throw vme;
+ }
+ catch (InvocationTargetException ite)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("error instantiating URLLoader");
+ vme.initCause(ite);
+ throw vme;
+ }
+ catch (IllegalAccessException illae)
+ {
+ // Programming error in the class library.
+ InternalError vme
+ = new InternalError("invalid access to URLLoader");
+ vme.initCause(illae);
+ throw vme;
+ }
+
+ if (loader == null)
+ {
+ // If it is not a directory, use the jar loader.
+ if (! (file.endsWith("/") || file.endsWith(File.separator)))
+ loader = new JarURLLoader(this, factoryCache, factory,
+ newUrl, absoluteURL);
+ else if ("file".equals(protocol))
+ loader = new FileURLLoader(this, factoryCache, factory,
+ newUrl, absoluteURL);
+ else
+ loader = new RemoteURLLoader(this, factoryCache, factory,
+ newUrl);
+ }
+
+ urlinfos.add(loader);
+ ArrayListSecureClassLoader.getPermissions()
and the actual
+ * permissions to access the objects referenced by the URL of the
+ * code source. The extra permissions added depend on the protocol
+ * and file portion of the URL in the code source. If the URL has
+ * the "file" protocol ends with a '/' character then it must be a
+ * directory and a file Permission to read everything in that
+ * directory and all subdirectories is added. If the URL had the
+ * "file" protocol and doesn't end with a '/' character then it must
+ * be a normal file and a file permission to read that file is
+ * added. If the URL
has any other protocol then a
+ * socket permission to connect and accept connections from the host
+ * portion of the URL is added.
+ *
+ * @param source The codesource that needs the permissions to be accessed
+ * @return the collection of permissions needed to access the code resource
+ * @see java.security.SecureClassLoader#getPermissions(CodeSource)
+ */
+ protected PermissionCollection getPermissions(CodeSource source)
+ {
+ // XXX - This implementation does exactly as the Javadoc describes.
+ // But maybe we should/could use URLConnection.getPermissions()?
+ // First get the permissions that would normally be granted
+ PermissionCollection permissions = super.getPermissions(source);
+
+ // Now add any extra permissions depending on the URL location.
+ URL url = source.getLocation();
+ String protocol = url.getProtocol();
+ if (protocol.equals("file"))
+ {
+ String file = url.getFile();
+
+ // If the file end in / it must be an directory.
+ if (file.endsWith("/") || file.endsWith(File.separator))
+ {
+ // Grant permission to read everything in that directory and
+ // all subdirectories.
+ permissions.add(new FilePermission(file + "-", "read"));
+ }
+ else
+ {
+ // It is a 'normal' file.
+ // Grant permission to access that file.
+ permissions.add(new FilePermission(file, "read"));
+ }
+ }
+ else
+ {
+ // Grant permission to connect to and accept connections from host
+ String host = url.getHost();
+ if (host != null)
+ permissions.add(new SocketPermission(host, "connect,accept"));
+ }
+
+ return permissions;
+ }
+
+ /**
+ * Returns all the locations that this class loader currently uses the
+ * resolve classes and resource. This includes both the initially supplied
+ * URLs as any URLs added later by the loader.
+ * @return All the currently used URLs
+ */
+ public URL[] getURLs()
+ {
+ return (URL[]) urls.toArray(new URL[urls.size()]);
+ }
+
+ /**
+ * Creates a new instance of a URLClassLoader
that gets
+ * classes from the supplied URL
s. This class loader
+ * will have as parent the standard system class loader.
+ *
+ * @param urls the initial URLs used to resolve classes and
+ * resources
+ *
+ * @return the class loader
+ *
+ * @exception SecurityException when the calling code does not have
+ * permission to access the given URL
s
+ */
+ public static URLClassLoader newInstance(URL[] urls)
+ throws SecurityException
+ {
+ return newInstance(urls, null);
+ }
+
+ /**
+ * Creates a new instance of a URLClassLoader
that gets
+ * classes from the supplied URL
s and with the supplied
+ * loader as parent class loader.
+ *
+ * @param urls the initial URLs used to resolve classes and
+ * resources
+ * @param parent the parent class loader
+ *
+ * @return the class loader
+ *
+ * @exception SecurityException when the calling code does not have
+ * permission to access the given URL
s
+ */
+ public static URLClassLoader newInstance(URL[] urls, final ClassLoader parent)
+ throws SecurityException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null)
+ return new URLClassLoader(urls, parent);
+ else
+ {
+ final Object securityContext = sm.getSecurityContext();
+
+ // XXX - What to do with anything else then an AccessControlContext?
+ if (! (securityContext instanceof AccessControlContext))
+ throw new SecurityException("securityContext must be AccessControlContext: "
+ + securityContext);
+
+ URLClassLoader loader =
+ AccessController.doPrivileged(new PrivilegedActionconnect()
to do this.
+ *
+ * @param url The Object to create the URL connection to
+ *
+ * @see URLConnection#connect()
+ */
+ protected URLConnection(URL url)
+ {
+ // Set up all our instance variables
+ this.url = url;
+ allowUserInteraction = defaultAllowUserInteraction;
+ useCaches = defaultUseCaches;
+ }
+
+ /**
+ * Establishes the actual connection to the URL associated with this
+ * connection object
+ *
+ * @exception IOException if an error occurs
+ */
+ public abstract void connect() throws IOException;
+
+ /**
+ * Returns the URL object associated with this connection
+ *
+ * @return The URL for this connection.
+ */
+ public URL getURL()
+ {
+ return url;
+ }
+
+ /**
+ * Returns the connection timeout speed, in milliseconds, or zero if
+ * the timeout is infinite or not set.
+ *
+ * @return The timeout.
+ *
+ * @since 1.5
+ */
+ public int getConnectTimeout()
+ {
+ return connectTimeout;
+ }
+
+ /**
+ * Set the connection timeout speed, in milliseconds, or zero if the timeout
+ * is to be considered infinite. Note that in certain socket
+ * implementations/platforms this method may not have any effect.
+ *
+ * Throws an IllegalArgumentException
if timeout < 0.
+ *
+ * @param timeout the timeout, in milliseconds.
+ *
+ * @since 1.5
+ */
+ public void setConnectTimeout(int timeout)
+ throws IllegalArgumentException
+ {
+ if( timeout < 0 )
+ throw new IllegalArgumentException("Timeout must be 0 or positive.");
+ connectTimeout = timeout;
+ }
+
+ /**
+ * Returns the read timeout, in milliseconds, or zero if the timeout
+ * is infinite or not set.
+ *
+ * @return The timeout.
+ *
+ * @see #setReadTimeout
+ *
+ * @since 1.5
+ */
+ public int getReadTimeout()
+ {
+ return readTimeout;
+ }
+
+ /**
+ * Set the read timeout, in milliseconds, or zero if the timeout
+ * is to be considered infinite. Note that in certain socket
+ * implementations/platforms this method may not have any effect.
+ *
+ * Throws an IllegalArgumentException
if timeout < 0.
+ *
+ * @param timeout - The timeout, in milliseconds.
+ *
+ * @throws IllegalArgumentException if timeout is negative.
+ *
+ * @see #getReadTimeout
+ *
+ * @since 1.5
+ */
+ public void setReadTimeout(int timeout)
+ throws IllegalArgumentException
+ {
+ if( timeout < 0 )
+ throw new IllegalArgumentException("Timeout must be 0 or positive.");
+ readTimeout = timeout;
+ }
+
+ /**
+ * Returns the value of the content-length header field or -1 if the value
+ * is not known or not present.
+ *
+ * @return The content-length field
+ */
+ public int getContentLength()
+ {
+ return getHeaderFieldInt("content-length", -1);
+ }
+
+ /**
+ * Returns the the content-type of the data pointed to by the URL. This
+ * method first tries looking for a content-type header. If that is not
+ * present, it attempts to use the file name to determine the content's
+ * MIME type. If that is unsuccessful, the method returns null. The caller
+ * may then still attempt to determine the MIME type by a call to
+ * guessContentTypeFromStream()
+ *
+ * @return The content MIME type
+ */
+ public String getContentType()
+ {
+ return getHeaderField("content-type");
+ }
+
+ /**
+ * Returns the value of the content-encoding field or null if it is not
+ * known or not present.
+ *
+ * @return The content-encoding field
+ */
+ public String getContentEncoding()
+ {
+ return getHeaderField("content-encoding");
+ }
+
+ /**
+ * Returns the value of the expires header or 0 if not known or present.
+ * If populated, the return value is number of seconds since midnight
+ * on 1/1/1970 GMT.
+ *
+ * @return The expiration time.
+ */
+ public long getExpiration()
+ {
+ return getHeaderFieldDate("expires", 0L);
+ }
+
+ /**
+ * Returns the date of the document pointed to by the URL as reported in
+ * the date field of the header or 0 if the value is not present or not
+ * known. If populated, the return value is number of seconds since
+ * midnight on 1/1/1970 GMT.
+ *
+ * @return The document date
+ */
+ public long getDate()
+ {
+ return getHeaderFieldDate("date", 0L);
+ }
+
+ /**
+ * Returns the value of the last-modified header field or 0 if not known known
+ * or not present. If populated, the return value is the number of seconds
+ * since midnight on 1/1/1970.
+ *
+ * @return The last modified time
+ */
+ public long getLastModified()
+ {
+ return getHeaderFieldDate("last-modified", 0L);
+ }
+
+ /**
+ * Return a String representing the header value at the specified index.
+ * This allows the caller to walk the list of header fields. The analogous
+ * {@link #getHeaderField(int)} method allows access to the corresponding
+ * key for this header field
+ *
+ * @param index The index into the header field list to retrieve the value for
+ *
+ * @return The header value or null if index is past the end of the headers
+ */
+ public String getHeaderField(int index)
+ {
+ // Subclasses for specific protocols override this.
+ return null;
+ }
+
+ /**
+ * Returns a String representing the value of the header field having
+ * the named key. Returns null if the header field does not exist.
+ *
+ * @param name The key of the header field
+ *
+ * @return The value of the header field as a String
+ */
+ public String getHeaderField(String name)
+ {
+ // Subclasses for specific protocols override this.
+ return null;
+ }
+
+ /**
+ * Returns an unmodifiable Map containing all sent header fields.
+ *
+ * @return The map of header fields. The map consists of String keys with
+ * an unmodifiable List of String objects as value.
+ *
+ * @since 1.4
+ */
+ public MapInputStream
. Images usually return a class that
+ * implements ImageProducer
. There is not guarantee
+ * what type of object will be returned, however.
+ *
+ * ContentHandlerFactory
is set, then that object is
+ * called to load a content handler, otherwise a class called
+ * gnu.java.net.content.<content_type> is tried. If this
+ * handler does not exist, the method will simple return the
+ * InputStream
returned by
+ * getInputStream()
. Note that the default
+ * implementation of getInputStream()
throws a
+ * UnknownServiceException
so subclasses are encouraged
+ * to override this method.Permission
object representing the
+ * permissions required to access this URL. This method returns
+ * java.security.AllPermission
by default. Subclasses should
+ * override it to return a more specific permission. For example, an
+ * HTTP URL should return an instance of SocketPermission
+ * for the appropriate host and port.
+ * true
if input is to be done,
+ * false
otherwise
+ *
+ * @exception IllegalStateException If already connected
+ */
+ public void setDoInput(boolean input)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ doInput = input;
+ }
+
+ /**
+ * Returns the value of a flag indicating whether or not input is going
+ * to be done for this connection. This default to true unless the
+ * doOutput flag is set to false, in which case this defaults to false.
+ *
+ * @return true if input is to be done, false otherwise
+ */
+ public boolean getDoInput()
+ {
+ return doInput;
+ }
+
+ /**
+ * Sets a boolean flag indicating whether or not output will be done
+ * on this connection. The default value is false, so this method can
+ * be used to override the default
+ *
+ * @param output ture if output is to be done, false otherwise
+ *
+ * @exception IllegalStateException If already connected
+ */
+ public void setDoOutput(boolean output)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ doOutput = output;
+ }
+
+ /**
+ * Returns a boolean flag indicating whether or not output will be done
+ * on this connection. This defaults to false.
+ *
+ * @return true if output is to be done, false otherwise
+ */
+ public boolean getDoOutput()
+ {
+ return doOutput;
+ }
+
+ /**
+ * Sets a boolean flag indicating whether or not user interaction is
+ * allowed for this connection. (For example, in order to prompt for
+ * username and password info.
+ *
+ * @param allow true if user interaction should be allowed, false otherwise.
+ *
+ * @exception IllegalStateException If already connected
+ */
+ public void setAllowUserInteraction(boolean allow)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ allowUserInteraction = allow;
+ }
+
+ /**
+ * Returns a boolean flag indicating whether or not user interaction is
+ * allowed for this connection. (For example, in order to prompt for
+ * username and password info.
+ *
+ * @return true if user interaction is allowed, false otherwise
+ */
+ public boolean getAllowUserInteraction()
+ {
+ return allowUserInteraction;
+ }
+
+ /**
+ * Sets the default flag for whether or not interaction with a user
+ * is allowed. This will be used for all connections unless overridden
+ *
+ * @param allow true to allow user interaction, false otherwise
+ */
+ public static void setDefaultAllowUserInteraction(boolean allow)
+ {
+ defaultAllowUserInteraction = allow;
+ }
+
+ /**
+ * Returns the default flag for whether or not interaction with a user
+ * is allowed. This will be used for all connections unless overridden
+ *
+ * @return true if user interaction is allowed, false otherwise
+ */
+ public static boolean getDefaultAllowUserInteraction()
+ {
+ return defaultAllowUserInteraction;
+ }
+
+ /**
+ * Sets a boolean flag indicating whether or not caching will be used
+ * (if possible) to store data downloaded via the connection.
+ *
+ * @param usecaches The new value
+ *
+ * @exception IllegalStateException If already connected
+ */
+ public void setUseCaches(boolean usecaches)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ useCaches = usecaches;
+ }
+
+ /**
+ * Returns a boolean flag indicating whether or not caching will be used
+ * (if possible) to store data downloaded via the connection.
+ *
+ * @return true if caching should be used if possible, false otherwise
+ */
+ public boolean getUseCaches()
+ {
+ return useCaches;
+ }
+
+ /**
+ * Sets the ifModified since instance variable. If this value is non
+ * zero and the underlying protocol supports it, the actual document will
+ * not be fetched unless it has been modified since this time. The value
+ * passed should be 0 if this feature is to be disabled or the time expressed
+ * as the number of seconds since midnight 1/1/1970 GMT otherwise.
+ *
+ * @param ifmodifiedsince The new value in milliseconds
+ * since January 1, 1970 GMT
+ *
+ * @exception IllegalStateException If already connected
+ */
+ public void setIfModifiedSince(long ifmodifiedsince)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ ifModifiedSince = ifmodifiedsince;
+ }
+
+ /**
+ * Returns the ifModified since instance variable. If this value is non
+ * zero and the underlying protocol supports it, the actual document will
+ * not be fetched unless it has been modified since this time. The value
+ * returned will be 0 if this feature is disabled or the time expressed
+ * as the number of seconds since midnight 1/1/1970 GMT otherwise
+ *
+ * @return The ifModifiedSince value
+ */
+ public long getIfModifiedSince()
+ {
+ return ifModifiedSince;
+ }
+
+ /**
+ * Returns the default value used to determine whether or not caching
+ * of documents will be done when possible.
+ *
+ * @return true if caches will be used, false otherwise
+ */
+ public boolean getDefaultUseCaches()
+ {
+ return defaultUseCaches;
+ }
+
+ /**
+ * Sets the default value used to determine whether or not caching
+ * of documents will be done when possible.
+ *
+ * @param use true to use caches if possible by default, false otherwise
+ */
+ public void setDefaultUseCaches(boolean use)
+ {
+ defaultUseCaches = use;
+ }
+
+ /**
+ * Sets the value of the named request property.
+ * This method does overwrite the value of existing properties with
+ * the new value.
+ *
+ * @param key The name of the property
+ * @param value The value of the property
+ *
+ * @exception IllegalStateException If already connected
+ * @exception NullPointerException If key is null
+ *
+ * @see URLConnection#getRequestProperty(String key)
+ * @see URLConnection#addRequestProperty(String key, String value)
+ *
+ * @since 1.4
+ */
+ public void setRequestProperty(String key, String value)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ if (key == null)
+ throw new NullPointerException("key is null");
+
+ // Do nothing unless overridden by subclasses that support setting
+ // header fields in the request.
+ }
+
+ /**
+ * Adds a new request property by a key/value pair.
+ * This method does not overwrite existing properties with the same key.
+ *
+ * @param key Key of the property to add
+ * @param value Value of the Property to add
+ *
+ * @exception IllegalStateException If already connected
+ * @exception NullPointerException If key is null
+ *
+ * @see URLConnection#getRequestProperty(String)
+ * @see URLConnection#setRequestProperty(String, String)
+ *
+ * @since 1.4
+ */
+ public void addRequestProperty(String key, String value)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ if (key == null)
+ throw new NullPointerException("key is null");
+
+ // Do nothing unless overridden by subclasses that support adding
+ // header fields in the request.
+ }
+
+ /**
+ * Returns the value of the named request property.
+ *
+ * @param key The name of the property
+ *
+ * @return Value of the property, or null
if key is null.
+ *
+ * @exception IllegalStateException If already connected
+ *
+ * @see URLConnection#setRequestProperty(String, String)
+ * @see URLConnection#addRequestProperty(String, String)
+ */
+ public String getRequestProperty(String key)
+ {
+ if (connected)
+ throw new IllegalStateException("Already connected");
+
+ // Overridden by subclasses that support reading header fields from the
+ // request.
+ return null;
+ }
+
+ /**
+ * Returns an unmodifiable Map containing the request properties.
+ *
+ * @return The map of properties. The map consists of String keys with an
+ * unmodifiable List of String objects as value.
+ *
+ * @exception IllegalStateException If already connected
+ *
+ * @since 1.4
+ */
+ public MapFileNameMap
object being used
+ * to decode MIME types by file extension.
+ *
+ * @return The FileNameMap
.
+ *
+ * @since 1.2
+ */
+ public static synchronized FileNameMap getFileNameMap()
+ {
+ // Delayed initialization.
+ if (fileNameMap == null)
+ fileNameMap = new MimeTypeMapper();
+
+ return fileNameMap;
+ }
+
+ /**
+ * This method sets the FileNameMap
object being used
+ * to decode MIME types by file extension.
+ *
+ * @param map The FileNameMap
.
+ *
+ * @exception SecurityException If a security manager exists and its
+ * checkSetFactory method doesn't allow the operation
+ *
+ * @since 1.2
+ */
+ public static synchronized void setFileNameMap(FileNameMap map)
+ {
+ // Throw an exception if an extant security manager precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+
+ fileNameMap = map;
+ }
+
+ private ContentHandler getContentHandler(String contentType)
+ {
+ // No content type so just handle it as the default.
+ if (contentType == null || contentType.equals(""))
+ return null;
+
+ ContentHandler handler = null;
+
+ // If a non-default factory has been set, use it.
+ if (factory != null)
+ handler = factory.createContentHandler(contentType);
+
+ // Now try default factory. Using this factory to instantiate built-in
+ // content handlers is preferable
+ if (handler == null)
+ handler = defaultFactory.createContentHandler(contentType);
+
+ // User-set factory has not returned a handler. Use the default search
+ // algorithm.
+ if (handler == null)
+ {
+ // Get the list of packages to check and append our default handler
+ // to it, along with the JDK specified default as a last resort.
+ // Except in very unusual environments the JDK specified one shouldn't
+ // ever be needed (or available).
+ String propVal = SystemProperties.getProperty("java.content.handler.pkgs");
+ propVal = (((propVal == null) ? "" : (propVal + "|"))
+ + "gnu.java.net.content|sun.net.www.content");
+
+ // Deal with "Content-Type: text/html; charset=ISO-8859-1".
+ int parameterBegin = contentType.indexOf(';');
+ if (parameterBegin >= 1)
+ contentType = contentType.substring(0, parameterBegin);
+ contentType = contentType.trim();
+
+ // Replace the '/' character in the content type with '.' and
+ // all other non-alphabetic, non-numeric characters with '_'.
+ char[] cArray = contentType.toCharArray();
+ for (int i = 0; i < cArray.length; i++)
+ {
+ if (cArray[i] == '/')
+ cArray[i] = '.';
+ else if (! ((cArray[i] >= 'A' && cArray[i] <= 'Z') ||
+ (cArray[i] >= 'a' && cArray[i] <= 'z') ||
+ (cArray[i] >= '0' && cArray[i] <= '9')))
+ cArray[i] = '_';
+ }
+ String contentClass = new String(cArray);
+
+ // See if a class of this content type exists in any of the packages.
+ StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
+ do
+ {
+ String facName = pkgPrefix.nextToken() + "." + contentClass;
+ try
+ {
+ handler =
+ (ContentHandler) Class.forName(facName).newInstance();
+ }
+ catch (Exception e)
+ {
+ // Can't instantiate; handler still null, go on to next element.
+ }
+ } while (handler == null && pkgPrefix.hasMoreTokens());
+ }
+
+ return handler;
+ }
+
+ // We don't put these in a static initializer, because it creates problems
+ // with initializer co-dependency: SimpleDateFormat's constructors
+ // eventually depend on URLConnection (via the java.text.*Symbols classes).
+ private static synchronized void initializeDateFormats()
+ {
+ if (dateformats_initialized)
+ return;
+
+ Locale locale = new Locale("En", "Us", "Unix");
+ dateFormats = new SimpleDateFormat[3];
+ dateFormats[0] =
+ new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
+ dateFormats[1] =
+ new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
+ dateFormats[2] = new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
+ dateformats_initialized = true;
+ }
+}
diff --git a/libjava/classpath/java/net/URLDecoder.java b/libjava/classpath/java/net/URLDecoder.java
new file mode 100644
index 000000000..73cedea5c
--- /dev/null
+++ b/libjava/classpath/java/net/URLDecoder.java
@@ -0,0 +1,182 @@
+/* URLDecoder.java -- Class to decode URL's from encoded form.
+ Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.io.UnsupportedEncodingException;
+
+
+/**
+ * This utility class contains static methods that converts a
+ * string encoded in the x-www-form-urlencoded format to the original
+ * text. The x-www-form-urlencoded format replaces certain disallowed
+ * characters with encoded equivalents. All upper case and lower case
+ * letters in the US alphabet remain as is, the space character (' ')
+ * is replaced with '+' sign, and all other characters are converted to a
+ * "%XX" format where XX is the hexadecimal representation of that character
+ * in a given character encoding (default is "UTF-8").
+ * URLStreamHandler
object.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ */
+public interface URLStreamHandlerFactory
+{
+ /**
+ * This method maps the protocol portion of a URL to a
+ * URLStreamHandler
object.
+ *
+ * @param protocol The protocol name to map ("http", "ftp", etc).
+ *
+ * @return The URLStreamHandler
for the specified protocol
+ */
+ URLStreamHandler createURLStreamHandler(String protocol);
+} // interface URLStreamHandlerFactory
diff --git a/libjava/classpath/java/net/UnknownHostException.java b/libjava/classpath/java/net/UnknownHostException.java
new file mode 100644
index 000000000..c5ba18330
--- /dev/null
+++ b/libjava/classpath/java/net/UnknownHostException.java
@@ -0,0 +1,77 @@
+/* UnknownHostException.java -- The hostname is unknown
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+
+
+/**
+ * This exception indicates that an attempt was made to reference a hostname
+ * or IP address that is not valid. This could possibly indicate that a
+ * DNS problem has occurred, but most often means that the host was not
+ * correctly specified.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Per Bothner
+ * @status updated to 1.4
+ */
+public class UnknownHostException extends IOException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -4639126076052875403L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public UnknownHostException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message, such as the
+ * name of the host that could not be resolved.
+ *
+ * @param message a message describing the error that occurred
+ */
+ public UnknownHostException(String message)
+ {
+ super(message);
+ }
+} // class UnknownHostException
diff --git a/libjava/classpath/java/net/UnknownServiceException.java b/libjava/classpath/java/net/UnknownServiceException.java
new file mode 100644
index 000000000..65cc8f592
--- /dev/null
+++ b/libjava/classpath/java/net/UnknownServiceException.java
@@ -0,0 +1,76 @@
+/* UnknownServiceException.java -- A service error occurred
+ Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.net;
+
+import java.io.IOException;
+
+
+/**
+ * Contrary to what you might think, this does not indicate that the
+ * TCP/IP service name specified was invalid. Instead it indicates that
+ * the MIME type returned from a URL could not be determined or that an
+ * attempt was made to write to a read-only URL.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @status updated to 1.4
+ */
+public class UnknownServiceException extends IOException
+{
+ /**
+ * Compatible with JDK 1.0+.
+ */
+ private static final long serialVersionUID = -4169033248853639508L;
+
+ /**
+ * Create a new instance without a descriptive error message.
+ */
+ public UnknownServiceException()
+ {
+ }
+
+ /**
+ * Create a new instance with a descriptive error message.
+ *
+ * @param message a message describing the error that occurred
+ */
+ public UnknownServiceException(String message)
+ {
+ super(message);
+ }
+} // class UnknownServiceException
diff --git a/libjava/classpath/java/net/package.html b/libjava/classpath/java/net/package.html
new file mode 100644
index 000000000..133ee716f
--- /dev/null
+++ b/libjava/classpath/java/net/package.html
@@ -0,0 +1,46 @@
+
+
+
+
+