Imported GNU Classpath 0.19 + gcj-import-20051115.
* sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. From-SVN: r107049
This commit is contained in:
parent
02e549bfaa
commit
8f523f3a10
1241 changed files with 97711 additions and 25284 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ());
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <code>Image</code> instance by delegating to
|
||||
|
@ -170,31 +162,4 @@ class DummyAppletContext implements AppletContext
|
|||
{
|
||||
return Collections.EMPTY_SET.iterator();
|
||||
}
|
||||
|
||||
/** Dummy <code>AudioClip</code> implementation that does nothing but
|
||||
* preventing <code>NullPointerException</code>S being thrown in programs
|
||||
* that expect a valid <code>AudioClip</code> 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 :)";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -331,6 +330,73 @@ public class HTTPConnection
|
|||
return cookieManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
try
|
||||
{
|
||||
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);
|
||||
}
|
||||
ByteArrayResponseBodyReader reader = new ByteArrayResponseBodyReader();
|
||||
request.setResponseBodyReader(reader);
|
||||
if (creds != null)
|
||||
{
|
||||
request.setAuthenticator(new Authenticator() {
|
||||
public Credentials getCredentials(String realm, int attempts)
|
||||
request = connection.newRequest(method, file);
|
||||
if (!keepAlive)
|
||||
{
|
||||
return (attempts < 2) ? creds : null;
|
||||
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();
|
||||
}
|
||||
response = request.dispatch();
|
||||
catch (IOException ioe)
|
||||
{
|
||||
if (connection.useCount > 0)
|
||||
{
|
||||
// Connection re-use failed: Try a new connection.
|
||||
try
|
||||
{
|
||||
connection.close();
|
||||
}
|
||||
catch (IOException _)
|
||||
{
|
||||
// Ignore.
|
||||
}
|
||||
connection = null;
|
||||
retry = true;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// First time the connection was used: Hard failure.
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -204,6 +186,27 @@ public class Headers
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 <code>null</code> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -99,11 +98,6 @@ public class Request
|
|||
*/
|
||||
protected int requestBodyNegotiationThreshold;
|
||||
|
||||
/**
|
||||
* The response body reader.
|
||||
*/
|
||||
protected ResponseBodyReader responseBodyReader;
|
||||
|
||||
/**
|
||||
* Map of response header handlers.
|
||||
*/
|
||||
|
@ -235,16 +229,6 @@ public class Request
|
|||
this.requestBodyWriter = requestBodyWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ exception statement from your version. */
|
|||
|
||||
package gnu.java.net.protocol.http;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
|
@ -63,19 +64,6 @@ public class Response
|
|||
*/
|
||||
protected final int code;
|
||||
|
||||
/**
|
||||
* The class of the response. This is the most significant digit of the
|
||||
* status code.
|
||||
* <dl>
|
||||
* <dt><code>1xx</code></dt> <dd>Informational response</dd>
|
||||
* <dt><code>2xx</code></dt> <dd>Success</dd>
|
||||
* <dt><code>3xx</code></dt> <dd>Redirection</dd>
|
||||
* <dt><code>4xx</code></dt> <dd>Client error</dd>
|
||||
* <dt><code>5xx</code></dt> <dd>Server error</dd>
|
||||
* </dl>
|
||||
*/
|
||||
protected final int codeClass;
|
||||
|
||||
/**
|
||||
* Human-readable text of the response.
|
||||
*/
|
||||
|
@ -86,19 +74,23 @@ 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.
|
||||
* <dl>
|
||||
* <dt><code>1xx</code></dt> <dd>Informational response</dd>
|
||||
* <dt><code>2xx</code></dt> <dd>Success</dd>
|
||||
* <dt><code>3xx</code></dt> <dd>Redirection</dd>
|
||||
* <dt><code>4xx</code></dt> <dd>Client error</dd>
|
||||
* <dt><code>5xx</code></dt> <dd>Server error</dd>
|
||||
* </dl>
|
||||
*/
|
||||
public int getCodeClass()
|
||||
{
|
||||
return codeClass;
|
||||
return code / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,6 +171,15 @@ public class Response
|
|||
return headers.getIntValue(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<!-- package.html - describes classes in gnu.java.net.protocol.http.event package.
|
||||
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. -->
|
||||
|
||||
<html>
|
||||
<head><title>GNU Classpath - gnu.java.net.protocol.http.event</title></head>
|
||||
|
||||
<body>
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
|
|
|
@ -258,7 +258,7 @@ public final class SocketChannelImpl extends SocketChannel
|
|||
}
|
||||
else
|
||||
{
|
||||
dst.put (data, offset, len);
|
||||
dst.put (data, offset, readBytes);
|
||||
}
|
||||
|
||||
return readBytes;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
350
libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java
Normal file
350
libjava/classpath/gnu/java/rmi/server/RMIClassLoaderImpl.java
Normal file
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* FocusManager.java -- Provide Swing FocusManager API compatibility
|
||||
/* DiffieHellmanKeyPairGeneratorImpl.java --
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
@ -35,18 +35,52 @@ 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
|
||||
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 ();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -68,12 +68,15 @@ public abstract class BaseBreakIterator extends BreakIterator
|
|||
return iter.getBeginIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first boundary after <code>pos</code>.
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue