From 8f523f3a1047919d3563daf1ef47ba87336ebe89 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Tue, 15 Nov 2005 23:20:01 +0000 Subject: Imported GNU Classpath 0.19 + gcj-import-20051115. * sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. From-SVN: r107049 --- libjava/classpath/gnu/java/awt/AWTUtilities.java | 9 +- libjava/classpath/gnu/java/awt/EmbeddedWindow.java | 6 +- libjava/classpath/gnu/java/awt/FocusManager.java | 52 --- .../gnu/java/awt/peer/gtk/GdkFontMetrics.java | 29 +- .../gnu/java/awt/peer/gtk/GdkGraphics.java | 12 +- .../gnu/java/awt/peer/gtk/GdkGraphics2D.java | 53 +++- .../gnu/java/awt/peer/gtk/GdkTextLayout.java | 5 +- .../gnu/java/awt/peer/gtk/GtkChoicePeer.java | 3 - .../gnu/java/awt/peer/gtk/GtkComponentPeer.java | 7 +- .../gnu/java/awt/peer/gtk/GtkDialogPeer.java | 28 +- .../gnu/java/awt/peer/gtk/GtkFramePeer.java | 3 +- .../classpath/gnu/java/awt/peer/qt/QtToolkit.java | 4 +- .../gnu/java/beans/DummyAppletContext.java | 37 +-- .../gnu/java/beans/decoder/BooleanHandler.java | 4 +- libjava/classpath/gnu/java/io/PlatformHelper.java | 5 - .../classpath/gnu/java/net/LineInputStream.java | 13 +- .../protocol/http/ByteArrayResponseBodyReader.java | 123 -------- .../java/net/protocol/http/ChunkedInputStream.java | 2 +- .../gnu/java/net/protocol/http/Cookie.java | 2 +- .../gnu/java/net/protocol/http/HTTPConnection.java | 174 +++++----- .../java/net/protocol/http/HTTPURLConnection.java | 108 ++++--- .../gnu/java/net/protocol/http/Headers.java | 85 ++--- .../protocol/http/LimitedLengthInputStream.java | 220 +++++++++++++ .../gnu/java/net/protocol/http/Request.java | 191 +++++------ .../gnu/java/net/protocol/http/Response.java | 55 ++-- .../java/net/protocol/http/ResponseBodyReader.java | 70 ----- .../net/protocol/http/event/ConnectionEvent.java | 81 ----- .../protocol/http/event/ConnectionListener.java | 58 ---- .../java/net/protocol/http/event/RequestEvent.java | 107 ------- .../net/protocol/http/event/RequestListener.java | 70 ----- .../gnu/java/net/protocol/http/event/package.html | 46 --- .../gnu/java/net/protocol/jar/Connection.java | 23 +- .../classpath/gnu/java/nio/SocketChannelImpl.java | 2 +- .../gnu/java/nio/channels/FileChannelImpl.java | 3 +- .../gnu/java/nio/charset/UTF_16Decoder.java | 19 +- .../gnu/java/nio/charset/UnicodeLittle.java | 2 +- .../gnu/java/nio/charset/iconv/IconvProvider.java | 6 +- .../classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java | 2 +- .../gnu/java/rmi/server/RMIClassLoaderImpl.java | 350 +++++++++++++++++++++ .../gnu/java/rmi/server/RMIObjectInputStream.java | 2 +- .../gnu/java/rmi/server/UnicastServer.java | 5 +- .../classpath/gnu/java/security/PolicyFile.java | 6 +- .../classpath/gnu/java/security/der/BitString.java | 13 + .../classpath/gnu/java/security/der/DERReader.java | 2 +- .../provider/DiffieHellmanKeyFactoryImpl.java | 123 ++++++++ .../DiffieHellmanKeyPairGeneratorImpl.java | 86 +++++ .../classpath/gnu/java/security/provider/Gnu.java | 15 +- .../java/security/x509/ext/BasicConstraints.java | 2 +- .../gnu/java/security/x509/ext/Extension.java | 10 +- .../classpath/gnu/java/text/BaseBreakIterator.java | 7 +- 50 files changed, 1287 insertions(+), 1053 deletions(-) delete mode 100644 libjava/classpath/gnu/java/awt/FocusManager.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java create mode 100644 libjava/classpath/gnu/java/net/protocol/http/LimitedLengthInputStream.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java delete mode 100644 libjava/classpath/gnu/java/net/protocol/http/event/package.html create mode 100644 libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java create mode 100644 libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java create mode 100644 libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java (limited to 'libjava/classpath/gnu/java') diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java index af1fc13..ca7b551 100644 --- a/libjava/classpath/gnu/java/awt/AWTUtilities.java +++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java @@ -592,9 +592,12 @@ public class AWTUtilities if (destination == null) destination = getRoot(source); - - convertPointToScreen(pt, source); - convertPointFromScreen(pt, destination); + + if (source.isShowing() && destination.isShowing()) + { + convertPointToScreen(pt, source); + convertPointFromScreen(pt, destination); + } return pt; } diff --git a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java index 08b2140..99f90c9 100644 --- a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java +++ b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java @@ -98,13 +98,11 @@ public class EmbeddedWindow extends Frame } catch (IllegalAccessException e) { - throw new RuntimeException - ("couldn't set java.awt.Component.peer field"); + throw new AssertionError (e); } catch (NoSuchFieldException e) { - throw new RuntimeException - ("couldn't set java.awt.Component.peer field"); + throw new AssertionError (e); } super.addNotify(); diff --git a/libjava/classpath/gnu/java/awt/FocusManager.java b/libjava/classpath/gnu/java/awt/FocusManager.java deleted file mode 100644 index 49b40bf..0000000 --- a/libjava/classpath/gnu/java/awt/FocusManager.java +++ /dev/null @@ -1,52 +0,0 @@ -/* FocusManager.java -- Provide Swing FocusManager API compatibility - Copyright (C) 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 gnu.java.awt; - -/** - * This is a subclass of the otherwise abstract class - * {@link javax.swing.FocusManager}. Its sole purpose is to make the Swing - * FocusManager usable as a FocusManager in AWT, so that we can provide both - * the new (1.4) KeyboardFocusManager API and still support the older - * Swing FocusManager. - * - * @author Roman Kennke - */ -public class FocusManager - extends javax.swing.FocusManager -{ -} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java index 7a439e8..c79f403 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontMetrics.java @@ -1,5 +1,5 @@ /* GdkFontMetrics.java - Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -62,15 +62,28 @@ public class GdkFontMetrics extends FontMetrics static final int TEXT_METRICS_HEIGHT = 3; static final int TEXT_METRICS_X_ADVANCE = 4; static final int TEXT_METRICS_Y_ADVANCE = 5; - - + + /** + * Makes sure to return a Font based on the given Font that has as + * peer a GdkFontPeer. Used in the initializer. + */ + private static Font initFont(Font font) + { + if (font == null) + return new Font("Dialog", Font.PLAIN, 12); + else if (font.getPeer() instanceof GdkFontPeer) + return font; + else + { + ClasspathToolkit toolkit; + toolkit = (ClasspathToolkit) Toolkit.getDefaultToolkit(); + return toolkit.getFont(font.getName(), font.getAttributes()); + } + } + public GdkFontMetrics (Font font) { - super (font.getPeer() instanceof GdkFontPeer - ? font - : ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) - .getFont (font.getName(), font.getAttributes ())); - + super(initFont(font)); peer = (GdkFontPeer) this.font.getPeer(); font_metrics = new int[5]; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java index 160602b..d80306c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -68,7 +68,7 @@ public class GdkGraphics extends Graphics Color color, xorColor; GtkComponentPeer component; - Font font; + Font font = new Font ("Dialog", Font.PLAIN, 12); Rectangle clip; GtkImage image; @@ -88,6 +88,8 @@ public class GdkGraphics extends Graphics color = g.color; xorColor = g.xorColor; font = g.font; + if (font == null) + font = new Font ("Dialog", Font.PLAIN, 12); clip = new Rectangle (g.clip); component = g.component; @@ -115,7 +117,6 @@ public class GdkGraphics extends Graphics GdkGraphics (GtkComponentPeer component) { this.component = component; - font = component.awtComponent.getFont (); color = Color.black; if (component.isRealized ()) @@ -128,6 +129,8 @@ public class GdkGraphics extends Graphics { initState (component); color = component.awtComponent.getForeground (); + if (color == null) + color = Color.BLACK; Dimension d = component.awtComponent.getSize (); clip = new Rectangle (0, 0, d.width, d.height); } @@ -137,6 +140,8 @@ public class GdkGraphics extends Graphics { initStateUnlocked (component); color = component.awtComponent.getForeground (); + if (color == null) + color = Color.BLACK; Dimension d = component.awtComponent.getSize (); clip = new Rectangle (0, 0, d.width, d.height); } @@ -378,7 +383,8 @@ public class GdkGraphics extends Graphics public void setFont (Font font) { - this.font = font; + if (font != null) + this.font = font; } native void setFunction (int gdk_func); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 6d9aabf..c9ed301 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -101,7 +101,7 @@ public class GdkGraphics2D extends Graphics2D static { if (! Configuration.GTK_CAIRO_ENABLED) - throw new Error("Grahics2D not implemented. " + throw new Error("Graphics2D not implemented. " + "Cairo was not found or disabled at configure time"); if (Configuration.INIT_LOAD_LIBRARY) @@ -154,11 +154,22 @@ public class GdkGraphics2D extends Graphics2D public Graphics create(int x, int y, int width, int height) { - return new GdkGraphics2D(width, height); + return new GdkGraphics2D(this, x, y, width, height); + } + + private void fail_g2d () + { + System.err.println ("Attempted to instantiate GdkGraphics2D" + + " but Graphics2D not enabled. Try again with" + + " -Dgnu.java.awt.peer.gtk.Graphics=Graphics2D"); + System.exit (1); } GdkGraphics2D(GdkGraphics2D g) { + if (!GtkToolkit.useGraphics2D ()) + fail_g2d (); + paint = g.paint; stroke = g.stroke; setRenderingHints(g.hints); @@ -198,8 +209,18 @@ public class GdkGraphics2D extends Graphics2D stateStack = new Stack(); } + GdkGraphics2D(GdkGraphics2D g, int x, int y, int widht, int height) + { + this(g); + translate(x, y); + clipRect(0, 0, widht, height); + } + GdkGraphics2D(int width, int height) { + if (!GtkToolkit.useGraphics2D ()) + fail_g2d (); + initState(width, height); setColor(Color.black); @@ -215,6 +236,9 @@ public class GdkGraphics2D extends Graphics2D GdkGraphics2D(GtkComponentPeer component) { + if (!GtkToolkit.useGraphics2D ()) + fail_g2d (); + this.component = component; if (component.isRealized()) @@ -949,7 +973,10 @@ public class GdkGraphics2D extends Graphics2D public Shape getClip() { - return clip.getBounds2D(); //getClipInDevSpace(); + if (clip == null) + return null; + else + return clip.getBounds2D(); //getClipInDevSpace(); } public Rectangle getClipBounds() @@ -992,8 +1019,11 @@ public class GdkGraphics2D extends Graphics2D if (clip == null) { // Reset clipping. - Dimension d = component.awtComponent.getSize(); - setClip(0, 0, d.width, d.height); + if (component != null) + { + Dimension d = component.awtComponent.getSize(); + setClip(0, 0, d.width, d.height); + } } else { @@ -1045,8 +1075,9 @@ public class GdkGraphics2D extends Graphics2D public void clearRect(int x, int y, int width, int height) { - cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0, - bg.getBlue() / 255.0, 1.0); + if (bg != null) + cairoSetRGBAColor(bg.getRed() / 255.0, bg.getGreen() / 255.0, + bg.getBlue() / 255.0, 1.0); cairoNewPath(); cairoRectangle(x, y, width, height); cairoFill(); @@ -1371,7 +1402,8 @@ public class GdkGraphics2D extends Graphics2D public void copyArea(int x, int y, int width, int height, int dx, int dy) { - throw new java.lang.UnsupportedOperationException(); + GdkGraphics2D g = (GdkGraphics2D) create(x, y, width, height); + gdkDrawDrawable(g, x + dx, y + dy); } public void drawArc(int x, int y, int width, int height, int startAngle, @@ -1604,6 +1636,11 @@ public class GdkGraphics2D extends Graphics2D public void setFont(Font f) { + // Sun's JDK does not throw NPEs, instead it leaves the current setting + // unchanged. So do we. + if (f == null) + return; + if (f.getPeer() instanceof GdkFontPeer) font = f; else diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java index ff51745..c3ae581 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java @@ -388,10 +388,7 @@ public class GdkTextLayout throw new Error("not implemented"); } - public Shape getOutline (AffineTransform tx) - { - throw new Error("not implemented"); - } + public native Shape getOutline (AffineTransform tx); public Shape getVisualHighlightShape (TextHitInfo firstEndpoint, TextHitInfo secondEndpoint, diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java index c140744..ed7dc74 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -131,9 +131,6 @@ public class GtkChoicePeer extends GtkComponentPeer protected void postChoiceItemEvent (String label, int stateChange) { - // Must set our state before notifying listeners - if (stateChange == ItemEvent.SELECTED) - ((Choice) awtComponent).select (label); postItemEvent (label, stateChange); } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index 60e8371..fe0dae7 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -71,6 +71,7 @@ import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; +import java.awt.peer.WindowPeer; import java.util.Timer; import java.util.TimerTask; @@ -98,6 +99,7 @@ public class GtkComponentPeer extends GtkGenericPeer native int[] gtkWidgetGetBackground (); native void gtkWidgetGetDimensions (int[] dim); native void gtkWidgetGetPreferredDimensions (int[] dim); + native void gtkWindowGetLocationOnScreen (int[] point); native void gtkWidgetGetLocationOnScreen (int[] point); native void gtkWidgetSetCursor (int type); native void gtkWidgetSetCursorUnlocked (int type); @@ -270,7 +272,10 @@ public class GtkComponentPeer extends GtkGenericPeer public Point getLocationOnScreen () { int point[] = new int[2]; - gtkWidgetGetLocationOnScreen (point); + if( this instanceof WindowPeer ) + gtkWindowGetLocationOnScreen (point); + else + gtkWidgetGetLocationOnScreen (point); return new Point (point[0], point[1]); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java index c2cbc37..f5ba3ad 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -44,6 +44,10 @@ import java.awt.Rectangle; import java.awt.event.PaintEvent; import java.awt.peer.DialogPeer; +import javax.swing.JDialog; +import javax.swing.JPopupMenu; +import javax.swing.JToolTip; + public class GtkDialogPeer extends GtkWindowPeer implements DialogPeer { @@ -82,10 +86,28 @@ public class GtkDialogPeer extends GtkWindowPeer void create () { - // Create a decorated dialog window. - create (GDK_WINDOW_TYPE_HINT_DIALOG, true); - Dialog dialog = (Dialog) awtComponent; + int type = GDK_WINDOW_TYPE_HINT_DIALOG; + + if (dialog instanceof JDialog) + { + Class heavyWeightClass; + try + { + heavyWeightClass = Class.forName("javax.swing.Popup$JWindowPopup"); + } + catch (ClassNotFoundException e) + { + throw new AssertionError(e); + } + + if (dialog.getClass() == heavyWeightClass + || ((JDialog) dialog).getContentPane() instanceof JToolTip) + type = GDK_WINDOW_TYPE_HINT_MENU; + } + + // Create a decorated dialog window. + create (type, !((Dialog) awtComponent).isUndecorated ()); gtkWindowSetModal (dialog.isModal ()); setTitle (dialog.getTitle ()); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index 6eb90ff..99cca0c 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -168,7 +168,8 @@ public class GtkFramePeer extends GtkWindowPeer void create () { // Create a normal decorated window. - create (GDK_WINDOW_TYPE_HINT_NORMAL, true); + create (GDK_WINDOW_TYPE_HINT_NORMAL, + !((Frame) awtComponent).isUndecorated ()); Frame frame = (Frame) awtComponent; diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java index 54f4888..591b528 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtToolkit.java @@ -37,6 +37,7 @@ exception statement from your version. */ package gnu.java.awt.peer.qt; +import gnu.classpath.Configuration; import gnu.java.awt.EmbeddedWindow; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.EmbeddedWindowPeer; @@ -135,7 +136,8 @@ public class QtToolkit extends ClasspathToolkit { eventQueue = new EventQueue(); repaintThread = new QtRepaintThread(); - System.loadLibrary("qtpeer"); + if (Configuration.INIT_LOAD_LIBRARY) + System.loadLibrary("qtpeer"); String theme = null; try diff --git a/libjava/classpath/gnu/java/beans/DummyAppletContext.java b/libjava/classpath/gnu/java/beans/DummyAppletContext.java index 4facb47..583d2f5 100644 --- a/libjava/classpath/gnu/java/beans/DummyAppletContext.java +++ b/libjava/classpath/gnu/java/beans/DummyAppletContext.java @@ -63,7 +63,6 @@ import java.util.Iterator; class DummyAppletContext implements AppletContext { private static final Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.EMPTY_SET); - private static final AudioClip DUMMY_CLIP = new DummyAudioClip(); DummyAppletContext() { @@ -80,14 +79,7 @@ class DummyAppletContext implements AppletContext */ public AudioClip getAudioClip(URL url) { - try - { - return (url.openConnection() != null ? DUMMY_CLIP : null); - } - catch (IOException ioe) - { - return null; - } + return Applet.newAudioClip(url); } /** Loads the Image instance by delegating to @@ -170,31 +162,4 @@ class DummyAppletContext implements AppletContext { return Collections.EMPTY_SET.iterator(); } - - /** Dummy AudioClip implementation that does nothing but - * preventing NullPointerExceptionS being thrown in programs - * that expect a valid AudioClip instance to be returned by - * their Applet. - * - * @author Robert Schuster - */ - static class DummyAudioClip implements AudioClip - { - public void play() - { - } - - public void stop() - { - } - - public void loop() - { - } - - public String toString() - { - return "DummyAudioClip never plays anything - implement javax.sound and make us happy :)"; - } - } } diff --git a/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java index a34fe34..a675e8c 100644 --- a/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java +++ b/libjava/classpath/gnu/java/beans/decoder/BooleanHandler.java @@ -57,10 +57,10 @@ class BooleanHandler extends SimpleHandler protected Object parse(String number) throws AssemblyException { if (number.equals("true")) - return new Boolean(true); + return Boolean.TRUE; if (number.equals("false")) - return new Boolean(false); + return Boolean.FALSE; throw new AssemblyException(new IllegalArgumentException("Element contained no valid boolean value.")); } diff --git a/libjava/classpath/gnu/java/io/PlatformHelper.java b/libjava/classpath/gnu/java/io/PlatformHelper.java index d2c6012..79ce6e8 100644 --- a/libjava/classpath/gnu/java/io/PlatformHelper.java +++ b/libjava/classpath/gnu/java/io/PlatformHelper.java @@ -109,11 +109,6 @@ public class PlatformHelper String tmppath = path.replace('/', separatorChar); StringBuffer canonpath; - // We found it'll be more efficient and easy to handle to - // return a lowercased canonical path - if(isWindows) - tmppath = tmppath.toLowerCase(); - int i; if ((i = beginWithRootPathPrefix(tmppath)) == 0 ) diff --git a/libjava/classpath/gnu/java/net/LineInputStream.java b/libjava/classpath/gnu/java/net/LineInputStream.java index 5ca0686..81a3c7d 100644 --- a/libjava/classpath/gnu/java/net/LineInputStream.java +++ b/libjava/classpath/gnu/java/net/LineInputStream.java @@ -1,5 +1,5 @@ /* LineInputStream.java -- - Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.net; +import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.FilterInputStream; import java.io.IOException; @@ -91,7 +92,8 @@ public class LineInputStream buf = new ByteArrayOutputStream(); this.encoding = encoding; eof = false; - blockReads = in.markSupported(); + // If it is already buffered, additional buffering gains nothing. + blockReads = !(in instanceof BufferedInputStream) && in.markSupported(); } /** @@ -109,11 +111,12 @@ public class LineInputStream if (blockReads) { // Use mark and reset to read chunks of bytes - final int MIN_LENGTH = 1024; + final int MAX_LENGTH = 1024; int len, pos; - + len = in.available(); - len = (len < MIN_LENGTH) ? MIN_LENGTH : len; + if (len == 0 || len > MAX_LENGTH) + len = MAX_LENGTH; byte[] b = new byte[len]; in.mark(len); // Read into buffer b diff --git a/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java b/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java deleted file mode 100644 index 680e45d..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/ByteArrayResponseBodyReader.java +++ /dev/null @@ -1,123 +0,0 @@ -/* Authenticator.java --ByteArrayResponseBodyReader.java -- - Copyright (C) 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 gnu.java.net.protocol.http; - -/** - * Simple response body reader that stores content in a byte array. - * - * @author Chris Burdess (dog@gnu.org) - */ -public class ByteArrayResponseBodyReader - implements ResponseBodyReader -{ - - /** - * The content. - */ - protected byte[] content; - - /** - * The position in the content at which the next write will occur. - */ - protected int pos; - - /** - * The length of the buffer. - */ - protected int len; - - /** - * Constructs a new byte array response body reader. - */ - public ByteArrayResponseBodyReader() - { - this(4096); - } - - /** - * Constructs a new byte array response body reader with the specified - * initial buffer size. - * @param size the initial buffer size - */ - public ByteArrayResponseBodyReader(int size) - { - content = new byte[size]; - pos = len = 0; - } - - /** - * This reader accepts all responses. - */ - public boolean accept(Request request, Response response) - { - return true; - } - - public void read(byte[] buffer, int offset, int length) - { - int l = length - offset; - if (pos + l > content.length) - { - byte[] tmp = new byte[content.length * 2]; - System.arraycopy(content, 0, tmp, 0, pos); - content = tmp; - } - System.arraycopy(buffer, offset, content, pos, l); - pos += l; - len = pos; - } - - public void close() - { - pos = 0; - } - - /** - * Retrieves the content of this reader as a byte array. - * The size of the returned array is the number of bytes read. - */ - public byte[] toByteArray() - { - byte[] ret = new byte[len]; - System.arraycopy(content, 0, ret, 0, len); - return ret; - } - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java index c0706b7..a4487d1 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java +++ b/libjava/classpath/gnu/java/net/protocol/http/ChunkedInputStream.java @@ -110,7 +110,7 @@ public class ChunkedInputStream // Read chunk header int c, last = 0; boolean seenSemi = false; - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); do { c = in.read(); diff --git a/libjava/classpath/gnu/java/net/protocol/http/Cookie.java b/libjava/classpath/gnu/java/net/protocol/http/Cookie.java index 45e2f73..0be7a09 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/Cookie.java +++ b/libjava/classpath/gnu/java/net/protocol/http/Cookie.java @@ -139,7 +139,7 @@ public class Cookie public String toString(boolean showPath, boolean showDomain) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append(name); buf.append('='); buf.append(value); diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java index 6d9f447..573a791 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java +++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPConnection.java @@ -41,10 +41,6 @@ package gnu.java.net.protocol.http; import gnu.classpath.Configuration; import gnu.classpath.SystemProperties; import gnu.java.net.EmptyX509TrustManager; -import gnu.java.net.protocol.http.event.ConnectionEvent; -import gnu.java.net.protocol.http.event.ConnectionListener; -import gnu.java.net.protocol.http.event.RequestEvent; -import gnu.java.net.protocol.http.event.RequestListener; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -57,6 +53,7 @@ import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -131,8 +128,6 @@ public class HTTPConnection */ protected int minorVersion; - private final List connectionListeners; - private final List requestListeners; private final List handshakeCompletedListeners; /** @@ -165,6 +160,12 @@ public class HTTPConnection */ protected CookieManager cookieManager; + + /** + * The pool that this connection is a member of (if any). + */ + private LinkedHashMap pool; + /** * Creates a new HTTP connection. * @param hostname the name of the host to connect to @@ -236,8 +237,6 @@ public class HTTPConnection this.connectionTimeout = connectionTimeout; this.timeout = timeout; majorVersion = minorVersion = 1; - connectionListeners = new ArrayList(4); - requestListeners = new ArrayList(4); handshakeCompletedListeners = new ArrayList(2); } @@ -332,6 +331,73 @@ public class HTTPConnection } /** + * The number of times this HTTPConnection has be used via keep-alive. + */ + int useCount; + + /** + * Generates a key for connections in the connection pool. + * + * @param h the host name. + * @param p the port. + * @param sec true if using https. + * + * @return the key. + */ + static Object getPoolKey(String h, int p, boolean sec) + { + StringBuilder buf = new StringBuilder(sec ? "https://" : "http://"); + buf.append(h); + buf.append(':'); + buf.append(p); + return buf.toString(); + } + + /** + * Set the connection pool that this HTTPConnection is a member of. + * If left unset or set to null, it will not be a member of any pool + * and will not be a candidate for reuse. + * + * @param p the pool. + */ + void setPool(LinkedHashMap p) + { + pool = p; + } + + /** + * Signal that this HTTPConnection is no longer needed and can be + * returned to the connection pool. + * + */ + void release() + { + if (pool != null) + { + synchronized (pool) + { + useCount++; + Object key = HTTPConnection.getPoolKey(hostname, port, secure); + pool.put(key, this); + while (pool.size() >= HTTPURLConnection.maxConnections) + { + // maxConnections must always be >= 1 + Object lru = pool.keySet().iterator().next(); + HTTPConnection c = (HTTPConnection)pool.remove(lru); + try + { + c.closeConnection(); + } + catch (IOException ioe) + { + // Ignore it. We are just cleaning up. + } + } + } + } + } + + /** * Creates a new request using this connection. * @param method the HTTP method to invoke * @param path the URI-escaped RFC2396 abs_path with @@ -367,7 +433,7 @@ public class HTTPConnection Cookie[] cookies = cookieManager.getCookies(hostname, secure, path); if (cookies != null && cookies.length > 0) { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append("$Version=1"); for (int i = 0; i < cookies.length; i++) { @@ -378,7 +444,6 @@ public class HTTPConnection ret.setHeader("Cookie", buf.toString()); } } - fireRequestEvent(RequestEvent.REQUEST_CREATED, ret); return ret; } @@ -388,14 +453,7 @@ public class HTTPConnection public void close() throws IOException { - try - { - closeConnection(); - } - finally - { - fireConnectionEvent(ConnectionEvent.CONNECTION_CLOSED); - } + closeConnection(); } /** @@ -534,7 +592,7 @@ public class HTTPConnection */ protected String getURI() { - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); buf.append(secure ? "https://" : "http://"); buf.append(hostname); if (secure) @@ -584,84 +642,6 @@ public class HTTPConnection // -- Events -- - public void addConnectionListener(ConnectionListener l) - { - synchronized (connectionListeners) - { - connectionListeners.add(l); - } - } - - public void removeConnectionListener(ConnectionListener l) - { - synchronized (connectionListeners) - { - connectionListeners.remove(l); - } - } - - protected void fireConnectionEvent(int type) - { - ConnectionEvent event = new ConnectionEvent(this, type); - ConnectionListener[] l = null; - synchronized (connectionListeners) - { - l = new ConnectionListener[connectionListeners.size()]; - connectionListeners.toArray(l); - } - for (int i = 0; i < l.length; i++) - { - switch (type) - { - case ConnectionEvent.CONNECTION_CLOSED: - l[i].connectionClosed(event); - break; - } - } - } - - public void addRequestListener(RequestListener l) - { - synchronized (requestListeners) - { - requestListeners.add(l); - } - } - - public void removeRequestListener(RequestListener l) - { - synchronized (requestListeners) - { - requestListeners.remove(l); - } - } - - protected void fireRequestEvent(int type, Request request) - { - RequestEvent event = new RequestEvent(this, type, request); - RequestListener[] l = null; - synchronized (requestListeners) - { - l = new RequestListener[requestListeners.size()]; - requestListeners.toArray(l); - } - for (int i = 0; i < l.length; i++) - { - switch (type) - { - case RequestEvent.REQUEST_CREATED: - l[i].requestCreated(event); - break; - case RequestEvent.REQUEST_SENDING: - l[i].requestSent(event); - break; - case RequestEvent.REQUEST_SENT: - l[i].requestSent(event); - break; - } - } - } - void addHandshakeCompletedListener(HandshakeCompletedListener l) { synchronized (handshakeCompletedListeners) diff --git a/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java index 9f2055f..d5da7d6 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java +++ b/libjava/classpath/gnu/java/net/protocol/http/HTTPURLConnection.java @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.net.protocol.http; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; @@ -75,7 +74,8 @@ public class HTTPURLConnection /** * Pool of reusable connections, used if keepAlive is true. */ - private static final Map connectionPool = new LinkedHashMap(); + private static final LinkedHashMap connectionPool = new LinkedHashMap(); + static int maxConnections; /* * The underlying connection. @@ -87,7 +87,6 @@ public class HTTPURLConnection int proxyPort; String agent; boolean keepAlive; - int maxConnections; private Request request; private Headers requestHeaders; @@ -95,8 +94,8 @@ public class HTTPURLConnection private boolean requestMethodSetExplicitly; private Response response; - private ByteArrayInputStream responseSink; - private ByteArrayInputStream errorSink; + private InputStream responseSink; + private InputStream errorSink; private HandshakeCompletedEvent handshakeEvent; @@ -202,34 +201,59 @@ public class HTTPURLConnection } connection.setProxy(proxyHostname, proxyPort); } - request = connection.newRequest(method, file); - if (!keepAlive) - { - request.setHeader("Connection", "close"); - } - if (agent != null) - { - request.setHeader("User-Agent", agent); - } - request.getHeaders().putAll(requestHeaders); - if (requestSink != null) + try { - byte[] content = requestSink.toByteArray(); - RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content); - request.setRequestBodyWriter(writer); + request = connection.newRequest(method, file); + if (!keepAlive) + { + request.setHeader("Connection", "close"); + } + if (agent != null) + { + request.setHeader("User-Agent", agent); + } + request.getHeaders().putAll(requestHeaders); + if (requestSink != null) + { + byte[] content = requestSink.toByteArray(); + RequestBodyWriter writer = new ByteArrayRequestBodyWriter(content); + request.setRequestBodyWriter(writer); + } + if (creds != null) + { + request.setAuthenticator(new Authenticator() { + public Credentials getCredentials(String realm, int attempts) + { + return (attempts < 2) ? creds : null; + } + }); + } + response = request.dispatch(); } - ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader(); - request.setResponseBodyReader(reader); - if (creds != null) + catch (IOException ioe) { - request.setAuthenticator(new Authenticator() { - public Credentials getCredentials(String realm, int attempts) + if (connection.useCount > 0) + { + // Connection re-use failed: Try a new connection. + try + { + connection.close(); + } + catch (IOException _) + { + // Ignore. + } + connection = null; + retry = true; + continue; + } + else { - return (attempts < 2) ? creds : null; + // First time the connection was used: Hard failure. + throw ioe; } - }); } - response = request.dispatch(); + if (response.getCodeClass() == 3 && getInstanceFollowRedirects()) { // Follow redirect @@ -307,7 +331,8 @@ public class HTTPURLConnection } else { - responseSink = new ByteArrayInputStream(reader.toByteArray ()); + responseSink = response.getBody(); + if (response.getCode() == 404) { errorSink = responseSink; @@ -328,27 +353,14 @@ public class HTTPURLConnection HTTPConnection connection; if (keepAlive) { - StringBuffer buf = new StringBuffer(secure ? "https://" : "http://"); - buf.append(Thread.currentThread().hashCode()); - buf.append('@'); - buf.append(host); - buf.append(':'); - buf.append(port); - String key = buf.toString(); + Object key = HTTPConnection.getPoolKey(host, port, secure); synchronized (connectionPool) { - connection = (HTTPConnection) connectionPool.get(key); + connection = (HTTPConnection) connectionPool.remove(key); if (connection == null) { connection = new HTTPConnection(host, port, secure); - // Good housekeeping - if (connectionPool.size() == maxConnections) - { - // maxConnections must always be >= 1 - Object lru = connectionPool.keySet().iterator().next(); - connectionPool.remove(lru); - } - connectionPool.put(key, connection); + connection.setPool(connectionPool); } } } @@ -502,9 +514,9 @@ public class HTTPURLConnection return null; } } - Map headers = response.getHeaders(); - Map ret = new LinkedHashMap(); - ret.put("", Collections.singletonList(getStatusLine(response))); + Headers headers = response.getHeaders(); + LinkedHashMap ret = new LinkedHashMap(); + ret.put(null, Collections.singletonList(getStatusLine(response))); for (Iterator i = headers.entrySet().iterator(); i.hasNext(); ) { Map.Entry entry = (Map.Entry) i.next(); @@ -512,7 +524,7 @@ public class HTTPURLConnection String value = (String) entry.getValue(); ret.put(key, Collections.singletonList(value)); } - return ret; + return Collections.unmodifiableMap(ret); } String getStatusLine(Response response) diff --git a/libjava/classpath/gnu/java/net/protocol/http/Headers.java b/libjava/classpath/gnu/java/net/protocol/http/Headers.java index 847ebef..9306fc4 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/Headers.java +++ b/libjava/classpath/gnu/java/net/protocol/http/Headers.java @@ -60,7 +60,7 @@ import java.util.Set; * @author Chris Burdess (dog@gnu.org) */ public class Headers - implements Map + extends LinkedHashMap { static final DateFormat dateFormat = new HTTPDateFormat(); @@ -143,36 +143,18 @@ public class Headers } - private LinkedHashMap headers; - public Headers() { - headers = new LinkedHashMap(); - } - - public int size() - { - return headers.size(); - } - - public boolean isEmpty() - { - return headers.isEmpty(); } public boolean containsKey(Object key) { - return headers.containsKey(new Header((String) key)); - } - - public boolean containsValue(Object value) - { - return headers.containsValue(value); + return super.containsKey(new Header((String) key)); } public Object get(Object key) { - return headers.get(new Header((String) key)); + return super.get(new Header((String) key)); } /** @@ -180,7 +162,7 @@ public class Headers */ public String getValue(String header) { - return (String) headers.get(new Header(header)); + return (String) super.get(new Header(header)); } /** @@ -205,6 +187,27 @@ public class Headers } /** + * Returns the value of the specified header as a long, or -1 if the + * header is not present or cannot be parsed as a long. + */ + public long getLongValue(String header) + { + String val = getValue(header); + if (val == null) + { + return -1; + } + try + { + return Long.parseLong(val); + } + catch (NumberFormatException e) + { + } + return -1; + } + + /** * Returns the value of the specified header as a date, * or null if the header is not present or not a date. */ @@ -227,12 +230,12 @@ public class Headers public Object put(Object key, Object value) { - return headers.put(new Header((String) key), value); + return super.put(new Header((String) key), value); } public Object remove(Object key) { - return headers.remove(new Header((String) key)); + return super.remove(new Header((String) key)); } public void putAll(Map t) @@ -241,18 +244,13 @@ public class Headers { String key = (String) i.next(); String value = (String) t.get(key); - headers.put(new Header(key), value); + put(key, value); } } - public void clear() - { - headers.clear(); - } - public Set keySet() { - Set keys = headers.keySet(); + Set keys = super.keySet(); Set ret = new LinkedHashSet(); for (Iterator i = keys.iterator(); i.hasNext(); ) { @@ -261,14 +259,9 @@ public class Headers return ret; } - public Collection values() - { - return headers.values(); - } - public Set entrySet() { - Set entries = headers.entrySet(); + Set entries = super.entrySet(); Set ret = new LinkedHashSet(); for (Iterator i = entries.iterator(); i.hasNext(); ) { @@ -278,16 +271,6 @@ public class Headers return ret; } - public boolean equals(Object other) - { - return headers.equals(other); - } - - public int hashCode() - { - return headers.hashCode(); - } - /** * Parse the specified input stream, adding headers to this collection. */ @@ -298,7 +281,7 @@ public class Headers (LineInputStream) in : new LineInputStream(in); String name = null; - StringBuffer value = new StringBuffer(); + StringBuilder value = new StringBuilder(); while (true) { String line = lin.readLine(); @@ -354,14 +337,14 @@ public class Headers private void addValue(String name, String value) { Header key = new Header(name); - String old = (String) headers.get(key); + String old = (String) super.get(key); if (old == null) { - headers.put(key, value); + super.put(key, value); } else { - headers.put(key, old + ", " + value); + super.put(key, old + ", " + value); } } diff --git a/libjava/classpath/gnu/java/net/protocol/http/LimitedLengthInputStream.java b/libjava/classpath/gnu/java/net/protocol/http/LimitedLengthInputStream.java new file mode 100644 index 0000000..16cf56a --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/LimitedLengthInputStream.java @@ -0,0 +1,220 @@ +/* LimitedLengthInputStream.java -- + Copyright (C) 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 gnu.java.net.protocol.http; + +import java.io.IOException; +import java.io.InputStream; + +/** + * InputStream that limits the total number of bytes that can be read + * from an underlying stream. In addition to limiting the number of + * bytes read, close() is not propagated to the underlying stream. + * + * @author David Daney (ddaney@avtrex.com) + */ +class LimitedLengthInputStream + extends InputStream +{ + private long remainingLen; + private boolean restrictLen; + private HTTPConnection connection; + private boolean eof; + private InputStream in; + private boolean doClose; + + + private void handleClose() + throws IOException + { + eof = true; + if (doClose) + { + in.close(); + } + else + { + connection.release(); + } + in = null; + connection = null; + } + + /** + * Constructor. + * + * @param in the underlying stream + * + * @param maxLen the maximum number of bytes to read + * + * @param restrictLen if true the number of bytes that can be read + * from this stream will be limited to maxLen, otherwise the number + * of bytes is not restricted. + * + * @param con the HTTPConnection associated with this stream + * + * @param doClose if true con will be closed when finished reading, + * else it will be placed back in the connection pool. + * + */ + LimitedLengthInputStream(InputStream in, + long maxLen, + boolean restrictLen, + HTTPConnection con, + boolean doClose) + throws IOException + + { + this.in = in; + this.remainingLen = maxLen; + this.restrictLen = restrictLen; + this.connection = con; + this.doClose = doClose; + + if (restrictLen) + { + if (maxLen < 0) + throw new IllegalArgumentException(); + else if (maxLen == 0) + handleClose(); // Nothing to do, release the connection. + } + } + + public synchronized int read() + throws IOException + { + if (eof) + return -1; // EOF + + int r; + + if (restrictLen) + { + r = in.read(); + if (-1 != r) + remainingLen--; + + if (0 == remainingLen) + handleClose(); + } + else + { + r = in.read(); + if (r == -1) + handleClose(); + } + + return r; + } + + public int read(byte[] buffer) + throws IOException + { + return read(buffer, 0, buffer.length); + } + + public synchronized int read(byte[] buffer, int offset, int length) + throws IOException + { + if (eof) + return -1; // EOF + + if (restrictLen && length > remainingLen) + length = (int) remainingLen; + + int r = in.read(buffer, offset, length); + + if (-1 == r) + handleClose(); + + if (restrictLen && r > 0) + { + remainingLen -= r; + if (0 == remainingLen) + handleClose(); + } + return r; + } + + public synchronized long skip(long n) + throws IOException + { + + if (eof) + return 0; + + if (restrictLen && n > remainingLen) + n = remainingLen; + + long r = in.skip(n); + + if (restrictLen) + { + remainingLen -= r; + if (0 == remainingLen) + handleClose(); + } + return r; + } + + public synchronized int available() + throws IOException + { + if (eof) + return 0; + + int a = in.available(); + if (restrictLen && a > remainingLen) + a = (int)remainingLen; + return a; + } + + public synchronized void close() + throws IOException + { + if (eof) + return; + + // If we get to here, the stream was not fully read. Just throw + // it away. + + doClose = true; + + handleClose(); + } +} diff --git a/libjava/classpath/gnu/java/net/protocol/http/Request.java b/libjava/classpath/gnu/java/net/protocol/http/Request.java index 21205e6..b9441b3 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/Request.java +++ b/libjava/classpath/gnu/java/net/protocol/http/Request.java @@ -1,5 +1,5 @@ /* Request.java -- - Copyright (C) 2004 Free Software Foundation, Inc. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,7 +40,6 @@ package gnu.java.net.protocol.http; import gnu.java.net.BASE64; import gnu.java.net.LineInputStream; -import gnu.java.net.protocol.http.event.RequestEvent; import java.io.IOException; import java.io.InputStream; @@ -100,11 +99,6 @@ public class Request protected int requestBodyNegotiationThreshold; /** - * The response body reader. - */ - protected ResponseBodyReader responseBodyReader; - - /** * Map of response header handlers. */ protected Map responseHeaderHandlers; @@ -236,16 +230,6 @@ public class Request } /** - * Sets the response body reader. - * @param responseBodyReader the handler to receive notifications of - * response body content - */ - public void setResponseBodyReader(ResponseBodyReader responseBodyReader) - { - this.responseBodyReader = responseBodyReader; - } - - /** * Sets a callback handler to be invoked for the specified header name. * @param name the header name * @param handler the handler to receive the value for the header @@ -324,13 +308,10 @@ public class Request do { retry = false; - // Send request - connection.fireRequestEvent(RequestEvent.REQUEST_SENDING, this); // Get socket output and input streams OutputStream out = connection.getOutputStream(); - LineInputStream in = - new LineInputStream(connection.getInputStream()); + // Request line String requestUri = path; if (connection.isUsingProxy() && @@ -369,28 +350,42 @@ public class Request count += len; } while (len > -1 && count < contentLength); - out.write(CRLF.getBytes(US_ASCII)); } out.flush(); - // Sent event - connection.fireRequestEvent(RequestEvent.REQUEST_SENT, this); // Get response - response = readResponse(in); - int sc = response.getCode(); - if (sc == 401 && authenticator != null) - { - if (authenticate(response, attempts++)) - { - retry = true; - } - } - else if (sc == 100 && expectingContinue) - { - requestHeaders.remove("Expect"); - setHeader("Content-Length", Integer.toString(contentLength)); - expectingContinue = false; - retry = true; - } + while(true) + { + response = readResponse(connection.getInputStream()); + int sc = response.getCode(); + if (sc == 401 && authenticator != null) + { + if (authenticate(response, attempts++)) + { + retry = true; + } + } + else if (sc == 100) + { + if (expectingContinue) + { + requestHeaders.remove("Expect"); + setHeader("Content-Length", + Integer.toString(contentLength)); + expectingContinue = false; + retry = true; + } + else + { + // A conforming server can send an unsoliceted + // Continue response but *should* not (RFC 2616 + // sec 8.2.3). Ignore the bogus Continue + // response and get the real response that + // should follow + continue; + } + } + break; + } } while (retry); } @@ -402,14 +397,16 @@ public class Request return response; } - Response readResponse(LineInputStream in) + Response readResponse(InputStream in) throws IOException { String line; int len; // Read response status line - line = in.readLine(); + LineInputStream lis = new LineInputStream(in); + + line = lis.readLine(); if (line == null) { throw new ProtocolException("Peer closed connection"); @@ -438,30 +435,25 @@ public class Request String message = line.substring(end + 1, len - 1); // Read response headers Headers responseHeaders = new Headers(); - responseHeaders.parse(in); + responseHeaders.parse(lis); notifyHeaderHandlers(responseHeaders); - // Construct response - int codeClass = code / 100; - Response ret = new Response(majorVersion, minorVersion, code, - codeClass, message, responseHeaders); + InputStream body = null; + switch (code) { + case 100: case 204: case 205: case 304: break; default: - // Does response body reader want body? - boolean notify = (responseBodyReader != null); - if (notify) - { - if (!responseBodyReader.accept(this, ret)) - { - notify = false; - } - } - readResponseBody(ret, in, notify); + body = createResponseBodyStream(responseHeaders, majorVersion, + minorVersion, in); } + + // Construct response + Response ret = new Response(majorVersion, minorVersion, code, + message, responseHeaders, body); return ret; } @@ -487,25 +479,40 @@ public class Request } } - void readResponseBody(Response response, InputStream in, - boolean notify) + private InputStream createResponseBodyStream(Headers responseHeaders, + int majorVersion, + int minorVersion, + InputStream in) throws IOException { - byte[] buffer = new byte[4096]; - int contentLength = -1; + long contentLength = -1; Headers trailer = null; - String transferCoding = response.getHeader("Transfer-Encoding"); + // Persistent connections are the default in HTTP/1.1 + boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) || + "close".equalsIgnoreCase(responseHeaders.getValue("Connection")) || + (connection.majorVersion == 1 && connection.minorVersion == 0) || + (majorVersion == 1 && minorVersion == 0); + + String transferCoding = responseHeaders.getValue("Transfer-Encoding"); if ("chunked".equalsIgnoreCase(transferCoding)) { - trailer = new Headers(); - in = new ChunkedInputStream(in, trailer); + in = new LimitedLengthInputStream(in, -1, false, connection, doClose); + + in = new ChunkedInputStream(in, responseHeaders); } else { - contentLength = response.getIntHeader("Content-Length"); + contentLength = responseHeaders.getLongValue("Content-Length"); + + if (contentLength < 0) + doClose = true; // No Content-Length, must close. + + in = new LimitedLengthInputStream(in, contentLength, + contentLength >= 0, + connection, doClose); } - String contentCoding = response.getHeader("Content-Encoding"); + String contentCoding = responseHeaders.getValue("Content-Encoding"); if (contentCoding != null && !"identity".equals(contentCoding)) { if ("gzip".equals(contentCoding)) @@ -522,51 +529,7 @@ public class Request contentCoding); } } - - // Persistent connections are the default in HTTP/1.1 - boolean doClose = "close".equalsIgnoreCase(getHeader("Connection")) || - "close".equalsIgnoreCase(response.getHeader("Connection")) || - (connection.majorVersion == 1 && connection.minorVersion == 0) || - (response.majorVersion == 1 && response.minorVersion == 0); - - int count = contentLength; - int len = (count > -1) ? count : buffer.length; - len = (len > buffer.length) ? buffer.length : len; - while (len > -1) - { - len = in.read(buffer, 0, len); - if (len < 0) - { - // EOF - connection.closeConnection(); - break; - } - if (notify) - { - responseBodyReader.read(buffer, 0, len); - } - if (count > -1) - { - count -= len; - if (count < 1) - { - if (doClose) - { - connection.closeConnection(); - } - break; - } - } - } - if (notify) - { - responseBodyReader.close(); - } - if (trailer != null) - { - response.getHeaders().putAll(trailer); - notifyHeaderHandlers(trailer); - } + return in; } boolean authenticate(Response response, int attempts) @@ -686,7 +649,7 @@ public class Request { int len = text.length(); String key = null; - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); Properties ret = new Properties(); boolean inQuote = false; for (int i = 0; i < len; i++) @@ -739,7 +702,7 @@ public class Request { int nc = connection.getNonceCount(nonce); String hex = Integer.toHexString(nc); - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); for (int i = 8 - hex.length(); i > 0; i--) { buf.append('0'); @@ -810,7 +773,7 @@ public class Request int len = text.length(); String attr = null; - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); boolean inQuote = false; for (int i = 0; i <= len; i++) { diff --git a/libjava/classpath/gnu/java/net/protocol/http/Response.java b/libjava/classpath/gnu/java/net/protocol/http/Response.java index 29dc28b..58d7454 100644 --- a/libjava/classpath/gnu/java/net/protocol/http/Response.java +++ b/libjava/classpath/gnu/java/net/protocol/http/Response.java @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.java.net.protocol.http; +import java.io.InputStream; import java.util.Date; /** @@ -64,19 +65,6 @@ public class Response protected final int code; /** - * The class of the response. This is the most significant digit of the - * status code. - *
- *
1xx
Informational response
- *
2xx
Success
- *
3xx
Redirection
- *
4xx
Client error
- *
5xx
Server error
- *
- */ - protected final int codeClass; - - /** * Human-readable text of the response. */ protected final String message; @@ -87,18 +75,22 @@ public class Response protected final Headers headers; /** + * An InputStream that returns the body of the response. + */ + protected final InputStream body; + + /** * Constructs a new response with the specified parameters. */ protected Response(int majorVersion, int minorVersion, int code, - int codeClass, String message, - Headers headers) + String message, Headers headers, InputStream body) { this.majorVersion = majorVersion; this.minorVersion = minorVersion; this.code = code; - this.codeClass = codeClass; this.message = message; this.headers = headers; + this.body = body; } /** @@ -129,12 +121,19 @@ public class Response } /** - * Returns the class of the response. - * @see #codeClass + * Returns the class of the response. This is the most significant + * digit of the status code. + *
+ *
1xx
Informational response
+ *
2xx
Success
+ *
3xx
Redirection
+ *
4xx
Client error
+ *
5xx
Server error
+ *
*/ public int getCodeClass() { - return codeClass; + return code / 100; } /** @@ -173,6 +172,15 @@ public class Response } /** + * Returns the header value for the specified name as a long. + * @param name the header name + */ + public long getLongHeader(String name) + { + return headers.getLongValue(name); + } + + /** * Returns the header value for the specified name as a date. * @param name the header name */ @@ -181,5 +189,14 @@ public class Response return headers.getDateValue(name); } + /** + * Returns an InputStream that returns the body of the response. + * + * @return the body of the response + */ + public InputStream getBody() + { + return body; + } } diff --git a/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java b/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java deleted file mode 100644 index 49e1b37..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/ResponseBodyReader.java +++ /dev/null @@ -1,70 +0,0 @@ -/* ResponseBodyReader.java -- - Copyright (C) 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 gnu.java.net.protocol.http; - -/** - * Callback interface for receiving notification of response body content. - * - * @author Chris Burdess (dog@gnu.org) - */ -public interface ResponseBodyReader -{ - - /** - * Indicate whether this reader is interested in the specified response. - * If it returns false, it will not receive body content notifications for - * that response. - */ - boolean accept(Request request, Response response); - - /** - * Receive notification of body content. - * @param buffer the content buffer - * @param offset the offset within the buffer that content starts - * @param length the length of the content - */ - void read(byte[] buffer, int offset, int length); - - /** - * Notifies the reader that the end of the content was reached. - */ - void close(); - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java deleted file mode 100644 index 3f6f545..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionEvent.java +++ /dev/null @@ -1,81 +0,0 @@ -/* ConnectionEvent.java -- - Copyright (C) 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 gnu.java.net.protocol.http.event; - -import java.util.EventObject; - -/** - * A connection event. - * - * @author Chris Burdess (dog@gnu.org) - */ -public class ConnectionEvent - extends EventObject -{ - - /** - * The connection closed event type. - */ - public static final int CONNECTION_CLOSED = 0; - - /** - * The type of this event. - */ - protected int type; - - /** - * Constructs a connection event with the specified source and type. - */ - public ConnectionEvent(Object source, int type) - { - super(source); - this.type = type; - } - - /** - * Returns the type of this event. - * @see #type - */ - public int getType() - { - return type; - } - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java b/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java deleted file mode 100644 index 073e89d..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/event/ConnectionListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* ConnectionListener.java -- - Copyright (C) 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 gnu.java.net.protocol.http.event; - -import java.util.EventListener; - -/** - * A connection listener. - * - * @author Chris Burdess (dog@gnu.org) - */ -public interface ConnectionListener - extends EventListener -{ - - /** - * Callback invoked when the associated connection is closed. - */ - void connectionClosed(ConnectionEvent event); - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java b/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java deleted file mode 100644 index 281c621..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/event/RequestEvent.java +++ /dev/null @@ -1,107 +0,0 @@ -/* RequestEvent.java -- - Copyright (C) 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 gnu.java.net.protocol.http.event; - -import gnu.java.net.protocol.http.Request; - -import java.util.EventObject; - -/** - * A request event. - * - * @author Chris Burdess (dog@gnu.org) - */ -public class RequestEvent - extends EventObject -{ - - /** - * The request created event type. - */ - public static final int REQUEST_CREATED = 0; - - /** - * The request sending event type. - */ - public static final int REQUEST_SENDING = 1; - - /** - * The request sent event type. - */ - public static final int REQUEST_SENT = 2; - - /** - * The type of this event. - */ - protected int type; - - /** - * The request associated with this event. - */ - protected Request request; - - /** - * Constructs a request event with the specified source, type, and request. - */ - public RequestEvent(Object source, int type, Request request) - { - super(source); - this.type = type; - this.request = request; - } - - /** - * Returns the type of this event. - * @see #type - */ - public int getType() - { - return type; - } - - /** - * Returns the request associated with this event. - */ - public Request getRequest() - { - return request; - } - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java b/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java deleted file mode 100644 index c880fbc..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/event/RequestListener.java +++ /dev/null @@ -1,70 +0,0 @@ -/* RequestListener.java -- - Copyright (C) 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 gnu.java.net.protocol.http.event; - -import java.util.EventListener; - -/** - * A request listener. - * - * @author Chris Burdess (dog@gnu.org) - */ -public interface RequestListener - extends EventListener -{ - - /** - * Callback invoked when a request is created from the associated - * connection. - */ - void requestCreated(RequestEvent event); - - /** - * Callback invoked when the request has been initialised with all data - * and before sending this data to the server. - */ - void requestSending(RequestEvent event); - - /** - * Callback invoked after all request data has been sent to the server. - */ - void requestSent(RequestEvent event); - -} - diff --git a/libjava/classpath/gnu/java/net/protocol/http/event/package.html b/libjava/classpath/gnu/java/net/protocol/http/event/package.html deleted file mode 100644 index 6aed0fc..0000000 --- a/libjava/classpath/gnu/java/net/protocol/http/event/package.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - -GNU Classpath - gnu.java.net.protocol.http.event - - -

- - - diff --git a/libjava/classpath/gnu/java/net/protocol/jar/Connection.java b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java index bd7a80d..e8548742 100644 --- a/libjava/classpath/gnu/java/net/protocol/jar/Connection.java +++ b/libjava/classpath/gnu/java/net/protocol/jar/Connection.java @@ -69,13 +69,17 @@ public final class Connection extends JarURLConnection private static Hashtable cache = new Hashtable(); private static final int READBUFSIZE = 4*1024; - public static synchronized JarFile get (URL url) throws IOException + public static synchronized JarFile get (URL url, boolean useCaches) + throws IOException { - JarFile jf = (JarFile) cache.get (url); + JarFile jf; + if (useCaches) + { + jf = (JarFile) cache.get (url); + if (jf != null) + return jf; + } - if (jf != null) - return jf; - if ("file".equals (url.getProtocol())) { File f = new File (url.getFile()); @@ -100,9 +104,10 @@ public final class Connection extends JarURLConnection jf = new JarFile (f, true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE); } - - cache.put (url, jf); - + + if (useCaches) + cache.put (url, jf); + return jf; } } @@ -120,7 +125,7 @@ public final class Connection extends JarURLConnection return; jar_url = getJarFileURL(); - jar_file = JarFileCache.get (jar_url); + jar_file = JarFileCache.get (jar_url, useCaches); String entry_name = getEntryName(); if (entry_name != null diff --git a/libjava/classpath/gnu/java/nio/SocketChannelImpl.java b/libjava/classpath/gnu/java/nio/SocketChannelImpl.java index 9fb71c1..fcddbd6 100644 --- a/libjava/classpath/gnu/java/nio/SocketChannelImpl.java +++ b/libjava/classpath/gnu/java/nio/SocketChannelImpl.java @@ -258,7 +258,7 @@ public final class SocketChannelImpl extends SocketChannel } else { - dst.put (data, offset, len); + dst.put (data, offset, readBytes); } return readBytes; diff --git a/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java index 0ee5d3f..466f3dd 100644 --- a/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java +++ b/libjava/classpath/gnu/java/nio/channels/FileChannelImpl.java @@ -175,7 +175,8 @@ public final class FileChannelImpl extends FileChannel */ protected void finalize() throws IOException { - this.close(); + if (fd != -1) + close(); } public int read (ByteBuffer dst) throws IOException diff --git a/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java index e3927d9..fa1dbc4 100644 --- a/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java +++ b/libjava/classpath/gnu/java/nio/charset/UTF_16Decoder.java @@ -54,6 +54,8 @@ final class UTF_16Decoder extends CharsetDecoder static final int BIG_ENDIAN = 0; static final int LITTLE_ENDIAN = 1; static final int UNKNOWN_ENDIAN = 2; + static final int MAYBE_BIG_ENDIAN = 3; + static final int MAYBE_LITTLE_ENDIAN = 4; private static final char BYTE_ORDER_MARK = 0xFEFF; private static final char REVERSED_BYTE_ORDER_MARK = 0xFFFE; @@ -81,26 +83,37 @@ final class UTF_16Decoder extends CharsetDecoder byte b2 = in.get (); // handle byte order mark - if (byteOrder == UNKNOWN_ENDIAN) + if (byteOrder == UNKNOWN_ENDIAN || + byteOrder == MAYBE_BIG_ENDIAN || + byteOrder == MAYBE_LITTLE_ENDIAN) { char c = (char) (((b1 & 0xFF) << 8) | (b2 & 0xFF)); if (c == BYTE_ORDER_MARK) { + if (byteOrder == MAYBE_LITTLE_ENDIAN) + { + return CoderResult.malformedForLength (2); + } byteOrder = BIG_ENDIAN; inPos += 2; continue; } else if (c == REVERSED_BYTE_ORDER_MARK) { + if (byteOrder == MAYBE_BIG_ENDIAN) + { + return CoderResult.malformedForLength (2); + } byteOrder = LITTLE_ENDIAN; inPos += 2; continue; } else { - // assume big endian, do not consume bytes, + // assume big or little endian, do not consume bytes, // continue with normal processing - byteOrder = BIG_ENDIAN; + byteOrder = (byteOrder == MAYBE_LITTLE_ENDIAN ? + LITTLE_ENDIAN : BIG_ENDIAN); } } diff --git a/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java b/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java index d354e04..63f2855 100644 --- a/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java +++ b/libjava/classpath/gnu/java/nio/charset/UnicodeLittle.java @@ -64,7 +64,7 @@ final class UnicodeLittle extends Charset public CharsetDecoder newDecoder () { - return new UTF_16Decoder (this, UTF_16Decoder.UNKNOWN_ENDIAN); + return new UTF_16Decoder (this, UTF_16Decoder.MAYBE_LITTLE_ENDIAN); } public CharsetEncoder newEncoder () diff --git a/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java b/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java index 58eaa85..873e9ec 100644 --- a/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java +++ b/libjava/classpath/gnu/java/nio/charset/iconv/IconvProvider.java @@ -62,7 +62,11 @@ public final class IconvProvider extends CharsetProvider } } - private IconvProvider() + // Declaring the construtor public may violate the use of singleton. + // But it must be public so that an instance of this class can be + // created by Class.newInstance(), which is the case when this provider is + // defined in META-INF/services/java.nio.charset.spi.CharsetProvider. + public IconvProvider() { IconvMetaData.setup(); } diff --git a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java index b1e086a..9f18d12 100644 --- a/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java +++ b/libjava/classpath/gnu/java/rmi/dgc/DGCImpl_Stub.java @@ -81,7 +81,7 @@ public final class DGCImpl_Stub public void clean(java.rmi.server.ObjID[] $param_0, long $param_1, java.rmi.dgc.VMID $param_2, boolean $param_3) throws java.rmi.RemoteException { try { if (useNewInvoke) { - ref.invoke(this, $method_clean_0, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2, new java.lang.Boolean($param_3)}, -5803803475088455571L); + ref.invoke(this, $method_clean_0, new java.lang.Object[] {$param_0, new java.lang.Long($param_1), $param_2, Boolean.valueOf($param_3)}, -5803803475088455571L); } else { java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, 0, interfaceHash); diff --git a/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java b/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java new file mode 100644 index 0000000..2e1e780 --- /dev/null +++ b/libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java @@ -0,0 +1,350 @@ +/* RMIClassLoaderImpl.java -- FIXME: briefly describe file purpose + Copyright (C) 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 gnu.java.rmi.server; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.rmi.server.RMIClassLoaderSpi; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Map; +import java.util.StringTokenizer; + +/** + * The default implementation of {@link java.rmi.server.RMIClassLoaderSpi}. + * + * @author Roman Kennke (kennke@aicas.com) + */ +public class RMIClassLoaderImpl extends RMIClassLoaderSpi +{ + private static class MyClassLoader extends URLClassLoader + { + // Package-private to avoid a trampoline constructor. + MyClassLoader (URL[] urls, ClassLoader parent, String annotation) + { + super (urls, parent); + this.annotation = annotation; + } + + private MyClassLoader (URL[] urls, ClassLoader parent) + { + super (urls, parent); + this.annotation = urlToAnnotation (urls); + } + + public static String urlToAnnotation (URL[] urls) + { + if (urls.length == 0) + return null; + + StringBuffer annotation = new StringBuffer (64 * urls.length); + + for (int i = 0; i < urls.length; i++) + { + annotation.append (urls [i].toExternalForm()); + annotation.append (' '); + } + + return annotation.toString(); + } + + public final String getClassAnnotation() + { + return annotation; + } + + private final String annotation; + } + + /** + * This class is used to identify a cached classloader by its codebase and + * the context classloader that is its parent. + */ + private static class CacheKey + { + private String mCodeBase; + private ClassLoader mContextClassLoader; + + public CacheKey (String theCodebase, ClassLoader theContextClassLoader) + { + mCodeBase = theCodebase; + mContextClassLoader = theContextClassLoader; + } + + /** + * @return true if the codebase and the context classloader are equal + */ + public boolean equals (Object theOther) + { + if (theOther instanceof CacheKey) + { + CacheKey key = (CacheKey) theOther; + + return (equals (this.mCodeBase,key.mCodeBase) + && equals (this.mContextClassLoader, key.mContextClassLoader)); + } + return false; + } + + /** + * Test if the two objects are equal or both null. + * @param theOne + * @param theOther + * @return + */ + private boolean equals (Object theOne, Object theOther) + { + return theOne != null ? theOne.equals (theOther) : theOther == null; + } + + /** + * @return hashCode + */ + public int hashCode() + { + return ((mCodeBase != null ? mCodeBase.hashCode() : 0) + ^(mContextClassLoader != null ? mContextClassLoader.hashCode() : -1)); + } + + public String toString() + { + return "[" + mCodeBase + "," + mContextClassLoader + "]"; + } + + } + + private static RMIClassLoaderImpl instance = null; + + private static Map cacheLoaders; //map annotations to loaders + private static Map cacheAnnotations; //map loaders to annotations + //class loader for defaultAnnotation + private static MyClassLoader defaultClassLoader; + + //defaultAnnotation is got from system property + // "java.rmi.server.defaultAnnotation" + private static String defaultAnnotation; + + //URL object for defaultAnnotation + private static URL defaultCodebase; + + static + { + // 89 is a nice prime number for Hashtable initial capacity + cacheLoaders = new Hashtable (89); + cacheAnnotations = new Hashtable (89); + + defaultAnnotation = System.getProperty ("java.rmi.server.defaultAnnotation"); + + try + { + if (defaultAnnotation != null) + defaultCodebase = new URL (defaultAnnotation); + } + catch (Exception _) + { + defaultCodebase = null; + } + + if (defaultCodebase != null) + { + defaultClassLoader = new MyClassLoader (new URL[] { defaultCodebase }, null, + defaultAnnotation); + cacheLoaders.put (new CacheKey (defaultAnnotation, + Thread.currentThread().getContextClassLoader()), + defaultClassLoader); + } + } + + /** + * This is a singleton class and may only be instantiated once from within + * the {@link #getInstance} method. + */ + private RMIClassLoaderImpl() + { + } + + /** + * Returns an instance of RMIClassLoaderImpl. + * + * @return an instance of RMIClassLoaderImpl + */ + public static RMIClassLoaderSpi getInstance() + { + if (instance == null) + instance = new RMIClassLoaderImpl(); + return instance; + } + + public Class loadClass(String codeBase, String name, + ClassLoader defaultLoader) + throws MalformedURLException, ClassNotFoundException + { + ClassLoader loader; + if (defaultLoader == null) + loader = Thread.currentThread().getContextClassLoader(); + else + loader = defaultLoader; + + //try context class loader first + try + { + return Class.forName(name, false, loader); + } + catch (ClassNotFoundException e) + { + // class not found in the local classpath + } + + if (codeBase.length() == 0) //=="" + { + loader = defaultClassLoader; + } + else + { + loader = getClassLoader(codeBase); + } + + if (loader == null) + { + //do not throw NullPointerException + throw new ClassNotFoundException ("Could not find class (" + name + + ") at codebase (" + codeBase + ")"); + } + + return Class.forName(name, false, loader); + } + + public Class loadProxyClass(String codeBase, String[] interfaces, + ClassLoader defaultLoader) + throws MalformedURLException, ClassNotFoundException + { + // FIXME: Implement this. + return null; + } + + /** + * Gets a classloader for the given codebase and with the current + * context classloader as parent. + * + * @param codebase + * + * @return a classloader for the given codebase + * + * @throws MalformedURLException if the codebase contains a malformed URL + */ + public ClassLoader getClassLoader(String codebase) + throws MalformedURLException + { + ClassLoader loader; + CacheKey loaderKey = new CacheKey + (codebase, Thread.currentThread().getContextClassLoader()); + loader = (ClassLoader) cacheLoaders.get (loaderKey); + + if (loader == null) + { + //create an entry in cacheLoaders mapping a loader to codebases. + // codebases are separated by " " + StringTokenizer tok = new StringTokenizer (codebase, " "); + ArrayList urls = new ArrayList(); + + while (tok.hasMoreTokens()) + urls.add (new URL(tok.nextToken())); + + loader = new MyClassLoader((URL[]) urls.toArray(new URL [urls.size()]), + Thread.currentThread().getContextClassLoader(), + codebase); + cacheLoaders.put (loaderKey, loader); + } + + return loader; + } + + /** + * Returns a string representation of the network location where a remote + * endpoint can get the class-definition of the given class. + * + * @param cl + * + * @return a space seperated list of URLs where the class-definition + * of cl may be found + */ + public String getClassAnnotation(Class cl) + { + ClassLoader loader = cl.getClassLoader(); + + if (loader == null + || loader == ClassLoader.getSystemClassLoader()) + { + return System.getProperty ("java.rmi.server.codebase"); + } + + if (loader instanceof MyClassLoader) + { + return ((MyClassLoader) loader).getClassAnnotation(); + } + + String s = (String) cacheAnnotations.get (loader); + + if (s != null) + return s; + + if (loader instanceof URLClassLoader) + { + URL[] urls = ((URLClassLoader) loader).getURLs(); + + if (urls.length == 0) + return null; + + StringBuffer annotation = new StringBuffer (64 * urls.length); + + for (int i = 0; i < urls.length; i++) + { + annotation.append (urls [i].toExternalForm()); + annotation.append (' '); + } + + s = annotation.toString(); + cacheAnnotations.put (loader, s); + return s; + } + + return System.getProperty ("java.rmi.server.codebase"); + } +} diff --git a/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java index 888b30b..587d57f 100644 --- a/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java +++ b/libjava/classpath/gnu/java/rmi/server/RMIObjectInputStream.java @@ -102,7 +102,7 @@ protected Class resolveProxyClass(String intfs[]) protected Object readValue(Class valueClass) throws IOException, ClassNotFoundException { if(valueClass.isPrimitive()){ if(valueClass == Boolean.TYPE) - return new Boolean(readBoolean()); + return Boolean.valueOf(readBoolean()); if(valueClass == Byte.TYPE) return new Byte(readByte()); if(valueClass == Character.TYPE) diff --git a/libjava/classpath/gnu/java/rmi/server/UnicastServer.java b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java index 065ef8c..a8da725 100644 --- a/libjava/classpath/gnu/java/rmi/server/UnicastServer.java +++ b/libjava/classpath/gnu/java/rmi/server/UnicastServer.java @@ -51,13 +51,16 @@ import java.rmi.RemoteException; import java.rmi.ServerError; import java.rmi.server.ObjID; import java.rmi.server.UID; +import java.util.Collections; +import java.util.Map; import java.util.Hashtable; +import java.util.IdentityHashMap; public class UnicastServer implements ProtocolConstants { static private Hashtable objects = new Hashtable(); //mapping OBJID to server ref -static private Hashtable refcache = new Hashtable(); //mapping obj itself to server ref +static private Map refcache = Collections.synchronizedMap(new IdentityHashMap()); //mapping obj itself to server ref static private DGCImpl dgc; public static void exportObject(UnicastServerRef obj) { diff --git a/libjava/classpath/gnu/java/security/PolicyFile.java b/libjava/classpath/gnu/java/security/PolicyFile.java index c6a3061..3064f04 100644 --- a/libjava/classpath/gnu/java/security/PolicyFile.java +++ b/libjava/classpath/gnu/java/security/PolicyFile.java @@ -533,7 +533,7 @@ public final class PolicyFile extends Policy if (clazz == null) { currentPerms.add(new UnresolvedPermission(className, - null, null, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + null, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]))); continue; } try @@ -555,7 +555,7 @@ public final class PolicyFile extends Policy if (clazz == null) { currentPerms.add(new UnresolvedPermission(className, - target, null, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + target, null, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]))); continue; } try @@ -598,7 +598,7 @@ public final class PolicyFile extends Policy if (clazz == null) { currentPerms.add(new UnresolvedPermission(className, - target, action, (Certificate[]) currentCerts.toArray(new Certificate[0]))); + target, action, (Certificate[]) currentCerts.toArray(new Certificate[currentCerts.size()]))); continue; } else diff --git a/libjava/classpath/gnu/java/security/der/BitString.java b/libjava/classpath/gnu/java/security/der/BitString.java index b88b145..02b1c03 100644 --- a/libjava/classpath/gnu/java/security/der/BitString.java +++ b/libjava/classpath/gnu/java/security/der/BitString.java @@ -286,6 +286,19 @@ public class BitString implements Cloneable, Comparable return 0; // not reached. } + public int hashCode() + { + int result = 0; + for (int i = 0; i < bytes.length - 1; ++i) + result = result * 31 + bytes[i]; + if (bytes.length > 0) + { + int lastByte = bytes[bytes.length - 1] & ~ ((1 << ignoredBits) - 1); + result = result * 31 + lastByte; + } + return result; + } + public boolean equals(Object o) { if (!(o instanceof BitString)) diff --git a/libjava/classpath/gnu/java/security/der/DERReader.java b/libjava/classpath/gnu/java/security/der/DERReader.java index cb07f14..09ec1e2 100644 --- a/libjava/classpath/gnu/java/security/der/DERReader.java +++ b/libjava/classpath/gnu/java/security/der/DERReader.java @@ -389,7 +389,7 @@ public class DERReader implements DER Integer.parseInt(str.substring( 4, 6)), // day Integer.parseInt(str.substring( 6, 8)), // hour Integer.parseInt(str.substring( 8, 10))); // minute - if (date.length() == 12); + if (date.length() == 12) calendar.set(Calendar.SECOND, Integer.parseInt(str.substring(10, 12))); } diff --git a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java new file mode 100644 index 0000000..591fc68 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java @@ -0,0 +1,123 @@ +/* DiffieHellmanKeyFactoryImpl.java -- + Copyright (C) 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 gnu.java.security.provider; + +import gnu.javax.crypto.GnuDHPrivateKey; + +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; + +import javax.crypto.spec.DHParameterSpec; +import javax.crypto.spec.DHPrivateKeySpec; +import javax.crypto.spec.DHPublicKeySpec; + +import javax.crypto.interfaces.DHPrivateKey; +import javax.crypto.interfaces.DHPublicKey; + +public class DiffieHellmanKeyFactoryImpl extends KeyFactorySpi +{ + protected PrivateKey engineGeneratePrivate (final KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof DHPrivateKeySpec) + { + DHPrivateKeySpec dh = (DHPrivateKeySpec) spec; + return new GnuDHPrivateKey (dh.getX (), + new DHParameterSpec (dh.getP (), dh.getG ())); + } + throw new InvalidKeySpecException (); + } + + protected PublicKey engineGeneratePublic (final KeySpec spec) + throws InvalidKeySpecException + { + if (spec instanceof DHPublicKeySpec) + { + DHPublicKeySpec dh = (DHPublicKeySpec) spec; + return new GnuDHPublicKey (new DHParameterSpec (dh.getP (), dh.getG ()), + dh.getY(), null); + } + throw new InvalidKeySpecException (); + } + + protected KeySpec engineGetKeySpec (final Key key, final Class specClass) + throws InvalidKeySpecException + { + if (key instanceof DHPrivateKey) + { + if (DHPrivateKeySpec.class.isAssignableFrom (specClass)) + { + DHParameterSpec params = ((DHPrivateKey) key).getParams (); + return new DHPrivateKeySpec (((DHPrivateKey) key).getX (), + params.getP (), params.getG ()); + } + } + if (key instanceof DHPublicKey) + { + if (DHPublicKeySpec.class.isAssignableFrom (specClass)) + { + DHParameterSpec params = ((DHPublicKey) key).getParams (); + return new DHPublicKeySpec (((DHPublicKey) key).getY (), + params.getP (), params.getG ()); + } + } + throw new InvalidKeySpecException (); + } + + protected Key engineTranslateKey (final Key key) + throws InvalidKeyException + { + if (key instanceof DHPrivateKey) + { + return new GnuDHPrivateKey (((DHPrivateKey) key).getX (), + ((DHPrivateKey) key).getParams ()); + } + if (key instanceof DHPublicKey) + { + return new GnuDHPublicKey (((DHPublicKey) key).getParams (), + ((DHPublicKey) key).getY (), null); + } + throw new InvalidKeyException (); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java new file mode 100644 index 0000000..1b68d27 --- /dev/null +++ b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java @@ -0,0 +1,86 @@ +/* DiffieHellmanKeyPairGeneratorImpl.java -- + Copyright (C) 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 gnu.java.security.provider; + +import gnu.javax.crypto.GnuDHPrivateKey; + +import java.math.BigInteger; + +import java.security.KeyPair; +import java.security.KeyPairGeneratorSpi; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.spec.DHParameterSpec; + +public class DiffieHellmanKeyPairGeneratorImpl extends KeyPairGeneratorSpi +{ + private SecureRandom random; + private DHParameterSpec params; + + public KeyPair generateKeyPair () + { + if (params == null || random == null) + throw new IllegalStateException ("not initialized"); + byte[] buf = new byte[(params.getP ().bitLength() >>> 3)]; + random.nextBytes (buf); + BigInteger x = new BigInteger (1, buf); + BigInteger y = params.getG ().modPow (x, params.getP ()); + GnuDHPublicKey pub = new GnuDHPublicKey (params, y, null); + GnuDHPrivateKey priv = new GnuDHPrivateKey (x, params); + + return new KeyPair (pub, priv); + } + + public void initialize (final int keysize, final SecureRandom random) + { + throw new UnsupportedOperationException ("key generation without parameters not supported"); + } + + public void initialize (final AlgorithmParameterSpec params, + final SecureRandom random) + { + if (!(params instanceof DHParameterSpec)) + throw new IllegalArgumentException ("expecting Diffie-Hellman parameters"); + this.params = (DHParameterSpec) params; + this.random = random; + if (this.random == null) + this.random = new SecureRandom (); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/Gnu.java b/libjava/classpath/gnu/java/security/provider/Gnu.java index 849f63c..e553bbc 100644 --- a/libjava/classpath/gnu/java/security/provider/Gnu.java +++ b/libjava/classpath/gnu/java/security/provider/Gnu.java @@ -46,7 +46,7 @@ public final class Gnu extends Provider { public Gnu() { - super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores"); + super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores, Diffie-Hellman key agreement and key pair generator"); AccessController.doPrivileged (new PrivilegedAction() { @@ -100,10 +100,12 @@ public final class Gnu extends Provider // Key Pair Generator put("KeyPairGenerator.DSA", gnu.java.security.provider.DSAKeyPairGenerator.class.getName()); + put("KeyPairGenerator.DiffieHellman", DiffieHellmanKeyPairGeneratorImpl.class.getName ()); put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA"); put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA"); put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA"); + put("Alg.Alias.KeyPairGenerator.DH", "DiffieHellman"); // Key Factory put("KeyFactory.DSA", @@ -122,6 +124,9 @@ public final class Gnu extends Provider put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); + put("KeyFactory.DiffieHellman", DiffieHellmanKeyFactoryImpl.class.getName()); + put("Alg.Alias.KeyFactory.DH", "DiffieHellman"); + // Message Digests put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName()); put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName()); @@ -161,6 +166,14 @@ public final class Gnu extends Provider // CertStore put("CertStore.Collection", CollectionCertStoreImpl.class.getName()); + // KeyAgreement + put("KeyAgreement.DiffieHellman", gnu.javax.crypto.DiffieHellmanImpl.class.getName()); + put("Alg.Alias.KeyAgreement.DH", "DiffieHellman"); + + // Cipher + put("Cipher.RSAES-PKCS1-v1_5", gnu.javax.crypto.RSACipherImpl.class.getName()); + put("Alg.Alias.Cipher.RSA", "RSAES-PKCS1-v1_5"); + return null; } }); diff --git a/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java b/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java index 00f7a6e..d8f5c61 100644 --- a/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java +++ b/libjava/classpath/gnu/java/security/x509/ext/BasicConstraints.java @@ -112,7 +112,7 @@ public class BasicConstraints extends Extension.Value if (encoded == null) { List bc = new ArrayList (2); - bc.add (new DERValue (DER.BOOLEAN, new Boolean (ca))); + bc.add (new DERValue (DER.BOOLEAN, Boolean.valueOf (ca))); if (pathLenConstraint >= 0) bc.add (new DERValue (DER.INTEGER, BigInteger.valueOf ((long) pathLenConstraint))); diff --git a/libjava/classpath/gnu/java/security/x509/ext/Extension.java b/libjava/classpath/gnu/java/security/x509/ext/Extension.java index 5ca9ac3..97097a2 100644 --- a/libjava/classpath/gnu/java/security/x509/ext/Extension.java +++ b/libjava/classpath/gnu/java/security/x509/ext/Extension.java @@ -232,7 +232,7 @@ public class Extension { List ext = new ArrayList (3); ext.add (new DERValue (DER.OBJECT_IDENTIFIER, oid)); - ext.add (new DERValue (DER.BOOLEAN, new Boolean (critical))); + ext.add (new DERValue (DER.BOOLEAN, Boolean.valueOf (critical))); ext.add (new DERValue (DER.OCTET_STRING, value.getEncoded())); return new DERValue (DER.CONSTRUCTED|DER.SEQUENCE, ext); } @@ -274,6 +274,14 @@ public class Extension return (byte[]) encoded; } + public int hashCode() + { + int result = 0; + for (int i = 0; i < encoded.length; ++i) + result = result * 31 + encoded[i]; + return result; + } + public boolean equals(Object o) { if (!(o instanceof Value)) diff --git a/libjava/classpath/gnu/java/text/BaseBreakIterator.java b/libjava/classpath/gnu/java/text/BaseBreakIterator.java index c28a208..4afd8ae 100644 --- a/libjava/classpath/gnu/java/text/BaseBreakIterator.java +++ b/libjava/classpath/gnu/java/text/BaseBreakIterator.java @@ -68,12 +68,15 @@ public abstract class BaseBreakIterator extends BreakIterator return iter.getBeginIndex(); } + /** + * Return the first boundary after pos. + * This has the side effect of setting the index of the + * CharacterIterator. + */ public int following (int pos) { - int save = iter.getIndex(); iter.setIndex(pos); int r = next (); - iter.setIndex(save); return r; } -- cgit v1.1