diff options
Diffstat (limited to 'gnu/java')
-rw-r--r-- | gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java | 12 | ||||
-rw-r--r-- | gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java | 6 | ||||
-rw-r--r-- | gnu/java/awt/peer/GLightweightPeer.java | 221 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/BufferedImageGraphics.java | 9 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/CairoGraphics2D.java | 10 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/CairoSurface.java | 74 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/ComponentGraphics.java | 52 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java | 8 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkChoicePeer.java | 101 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkComponentPeer.java | 4 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkMainThread.java | 97 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkToolkit.java | 30 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/GtkWindowPeer.java | 6 | ||||
-rw-r--r-- | gnu/java/lang/management/BeanImpl.java | 444 | ||||
-rw-r--r-- | gnu/java/net/protocol/http/Request.java | 15 |
15 files changed, 857 insertions, 232 deletions
diff --git a/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java b/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java index 4f9229822..b68fa1058 100644 --- a/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java +++ b/gnu/java/awt/dnd/peer/gtk/GtkDragSourceContextPeer.java @@ -61,11 +61,13 @@ public class GtkDragSourceContextPeer private ComponentPeer peer; private Cursor cursor; private DragSourceContext context; + public static Component target; native void nativeStartDrag(Image i, int x, int y, int action, String target); native void connectSignals(ComponentPeer comp); native void create(ComponentPeer comp); native void nativeSetCursor(int cursor); + native void setTarget(GtkDropTargetContextPeer target); public GtkDragSourceContextPeer(DragGestureEvent e) { @@ -76,10 +78,18 @@ public class GtkDragSourceContextPeer create(peer); connectSignals(peer); cursor = comp.getCursor(); + + // FIXME: Where do we set the target? + + if ((target != null)) + setTarget(new GtkDropTargetContextPeer(target)); } ComponentPeer getComponentPeer(Component c) { + if (c == null) + return null; + Component curr = c; while (curr.getPeer() instanceof LightweightPeer) curr = curr.getParent(); @@ -93,7 +103,7 @@ public class GtkDragSourceContextPeer throws InvalidDnDOperationException { this.context = context; - + if (p == null) p = new Point(); diff --git a/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java b/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java index 50cd95d41..f24b3f39b 100644 --- a/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java +++ b/gnu/java/awt/dnd/peer/gtk/GtkDropTargetContextPeer.java @@ -50,10 +50,10 @@ public class GtkDropTargetContextPeer extends GtkGenericPeer implements DropTargetContextPeer { - - public GtkDropTargetContextPeer() + + public GtkDropTargetContextPeer(Object obj) { - super(null); + super(obj); } public void setTargetActions(int actions) diff --git a/gnu/java/awt/peer/GLightweightPeer.java b/gnu/java/awt/peer/GLightweightPeer.java index 88733b92f..3029502ff 100644 --- a/gnu/java/awt/peer/GLightweightPeer.java +++ b/gnu/java/awt/peer/GLightweightPeer.java @@ -54,25 +54,14 @@ import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import java.awt.event.PaintEvent; import java.awt.image.ColorModel; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.image.VolatileImage; -import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; import java.awt.peer.LightweightPeer; -/* - * Another possible implementation strategy for lightweight peers is - * to make GLightweightPeer a placeholder class that implements - * LightweightPeer. Then the Component and Container classes could - * identify a peer as lightweight and handle it specially. The - * current approach is probably more clear but less efficient. - */ - /** * A stub class that implements the ComponentPeer and ContainerPeer * interfaces using callbacks into the Component and Container @@ -85,47 +74,48 @@ import java.awt.peer.LightweightPeer; public class GLightweightPeer implements LightweightPeer, ContainerPeer { - private Component comp; - - private Insets containerInsets; - - public GLightweightPeer(Component comp) + public GLightweightPeer() { - this.comp = comp; + // Nothing to do here. } // -------- java.awt.peer.ContainerPeer implementation: public Insets insets() { - return getInsets (); + // Nothing to do here for lightweights. + return null; } public Insets getInsets() { - if (containerInsets == null) - containerInsets = new Insets (0,0,0,0); - return containerInsets; + // Nothing to do here for lightweights. + return null; } public void beginValidate() { + // Nothing to do here for lightweights. } public void endValidate() { + // Nothing to do here for lightweights. } public void beginLayout() { + // Nothing to do here for lightweights. } public void endLayout() { + // Nothing to do here for lightweights. } public boolean isPaintPending() { + // Nothing to do here for lightweights. return false; } @@ -133,122 +123,162 @@ public class GLightweightPeer public int checkImage(Image img, int width, int height, ImageObserver o) { - return comp.getToolkit().checkImage(img, width, height, o); + // Nothing to do here for lightweights. + return -1; } public Image createImage(ImageProducer prod) { - return comp.getToolkit().createImage(prod); + // Nothing to do here for lightweights. + return null; } /* This method is not called. */ public Image createImage(int width, int height) { + // Nothing to do here for lightweights. return null; } - public void disable() {} + public void disable() + { + // Nothing to do here for lightweights. + } - public void dispose() {} + public void dispose() + { + // Nothing to do here for lightweights. + } - public void enable() {} + public void enable() + { + // Nothing to do here for lightweights. + } public GraphicsConfiguration getGraphicsConfiguration() { + // Nothing to do here for lightweights. return null; } public FontMetrics getFontMetrics(Font f) { - return comp.getToolkit().getFontMetrics(f); + // Nothing to do here for lightweights. + return null; } /* Returning null here tells the Component object that called us to * use its parent's Graphics. */ public Graphics getGraphics() { + // Nothing to do here for lightweights. return null; } public Point getLocationOnScreen() { - Point parentLocation = comp.getParent().getLocationOnScreen(); - return new Point (parentLocation.x + comp.getX(), - parentLocation.y + comp.getY()); + // Nothing to do here for lightweights. + return null; } public Dimension getMinimumSize() { - return new Dimension(comp.getWidth(), comp.getHeight()); + return minimumSize(); } - /* A lightweight component's preferred size is equivalent to its - * Component width and height values. */ public Dimension getPreferredSize() { - return new Dimension(comp.getWidth(), comp.getHeight()); + return preferredSize(); } /* Returning null here tells the Component object that called us to * use its parent's Toolkit. */ public Toolkit getToolkit() { + // Nothing to do here for lightweights. return null; } - public void handleEvent(AWTEvent e) {} + public void handleEvent(AWTEvent e) + { + // Nothing to do here for lightweights. + } - public void hide() {} + public void hide() + { + // Nothing to do here for lightweights. + } public boolean isFocusable() { + // Nothing to do here for lightweights. return false; } public boolean isFocusTraversable() { + // Nothing to do here for lightweights. return false; } public Dimension minimumSize() { - return getMinimumSize(); + return new Dimension(0, 0); } public Dimension preferredSize() { - return getPreferredSize(); + return new Dimension(0, 0); } - public void paint(Graphics graphics) {} + public void paint(Graphics graphics) + { + // Nothing to do here for lightweights. + } public boolean prepareImage(Image img, int width, int height, ImageObserver o) { - return comp.getToolkit().prepareImage(img, width, height, o); + // Nothing to do here for lightweights. + return false; } - public void print(Graphics graphics) {} + public void print(Graphics graphics) + { + // Nothing to do here for lightweights. + } public void repaint(long tm, int x, int y, int width, int height) { - Component p = comp.getParent(); - if (p != null) - p.repaint(tm, x + comp.getX(), y + comp.getY(), width, height); + // Nothing to do here for lightweights. } - public void requestFocus() {} + public void requestFocus() + { + // Nothing to do here for lightweights. + } - public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x) + public boolean requestFocus(Component source, boolean bool1, boolean bool2, + long x) { + // Nothing to do here for lightweights. return false; } - public void reshape(int x, int y, int width, int height) {} + public void reshape(int x, int y, int width, int height) + { + // Nothing to do here for lightweights. + } - public void setBackground(Color color) {} + public void setBackground(Color color) + { + // Nothing to do here for lightweights. + } - public void setBounds(int x, int y, int width, int height) {} + public void setBounds(int x, int y, int width, int height) + { + // Nothing to do here for lightweights. + } /** * Sets the cursor on the heavy-weight parent peer. @@ -256,110 +286,141 @@ public class GLightweightPeer */ public void setCursor(Cursor cursor) { - Component p = comp.getParent(); - while (p != null && p.isLightweight()) - p = p.getParent(); - - if (p != null) - { - // Don't actually change the cursor of the component - // otherwise other childs inherit this cursor. - ComponentPeer peer = p.getPeer(); - if (peer != null) - peer.setCursor(cursor); - } + // Nothing to do here for lightweights. } - public void setEnabled(boolean enabled) {} + public void setEnabled(boolean enabled) + { + // Nothing to do here for lightweights. + } - public void setEventMask(long eventMask) {} + public void setEventMask(long eventMask) + { + // Nothing to do here for lightweights. + } - public void setFont(Font font) {} + public void setFont(Font font) + { + // Nothing to do here for lightweights. + } - public void setForeground(Color color) {} + public void setForeground(Color color) + { + // Nothing to do here for lightweights. + } - public void setVisible(boolean visible) {} + public void setVisible(boolean visible) + { + // Nothing to do here for lightweights. + } - public void show() {} + public void show() + { + // Nothing to do here for lightweights. + } - public ColorModel getColorModel () + public ColorModel getColorModel() { - return comp.getColorModel (); + // Nothing to do here for lightweights. + return null; } public boolean isObscured() { + // Nothing to do here for lightweights. return false; } public boolean canDetermineObscurity() { + // Nothing to do here for lightweights. return false; } - public void coalescePaintEvent(PaintEvent e) { } + public void coalescePaintEvent(PaintEvent e) + { + // Nothing to do here for lightweights. + } - public void updateCursorImmediately() { } + public void updateCursorImmediately() + { + // Nothing to do here for lightweights. + } public VolatileImage createVolatileImage(int width, int height) { + // Nothing to do here for lightweights. return null; } public boolean handlesWheelScrolling() { + // Nothing to do here for lightweights. return false; } public void createBuffers(int x, BufferCapabilities capabilities) - throws AWTException { } + throws AWTException + { + // Nothing to do here for lightweights. + } public Image getBackBuffer() { + // Nothing to do here for lightweights. return null; } - public void flip(BufferCapabilities.FlipContents contents) { } + public void flip(BufferCapabilities.FlipContents contents) + { + // Nothing to do here for lightweights. + } - public void destroyBuffers() { } + public void destroyBuffers() + { + // Nothing to do here for lightweights. + } public boolean isRestackSupported() { + // Nothing to do here for lightweights. return false; } public void cancelPendingPaint(int x, int y, int width, int height) { - + // Nothing to do here for lightweights. } public void restack() { - + // Nothing to do here for lightweights. } public Rectangle getBounds() { + // Nothing to do here for lightweights. return null; } public void reparent(ContainerPeer parent) { - + // Nothing to do here for lightweights. } public void setBounds(int x, int y, int z, int width, int height) { - + // Nothing to do here for lightweights. } public boolean isReparentSupported() { - return false; + // Nothing to do here for lightweights. + return true; } public void layout() { - + // Nothing to do here for lightweights. } } diff --git a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java index 6a74eabc5..5412cbea9 100644 --- a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java +++ b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java @@ -48,6 +48,7 @@ import java.awt.font.GlyphVector; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.awt.image.Raster; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.awt.image.ColorModel; @@ -128,17 +129,17 @@ public class BufferedImageGraphics extends CairoGraphics2D cairo_t = surface.newCairoContext(); - DataBuffer db = bi.getRaster().getDataBuffer(); + Raster raster = bi.getRaster(); int[] pixels; // get pixels - if(db instanceof CairoSurface) - pixels = ((CairoSurface)db).getPixels(imageWidth * imageHeight); + if(raster instanceof CairoSurface) + pixels = ((CairoSurface)raster).getPixels(imageWidth * imageHeight); else { if( hasFastCM ) { - pixels = ((DataBufferInt)db).getData(); + pixels = ((DataBufferInt)raster.getDataBuffer()).getData(); if( !hasAlpha ) for(int i = 0; i < pixels.length; i++) pixels[i] &= 0xFFFFFFFF; diff --git a/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java index b665f562e..8fe04fe77 100644 --- a/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -1269,7 +1269,7 @@ public abstract class CairoGraphics2D extends Graphics2D } BufferedImage b = (BufferedImage) img; - DataBuffer db; + Raster raster; double[] i2u = new double[6]; int width = b.getWidth(); int height = b.getHeight(); @@ -1278,9 +1278,9 @@ public abstract class CairoGraphics2D extends Graphics2D // use the cached CairoSurface that BIG is drawing onto if( BufferedImageGraphics.bufferedImages.get( b ) != null ) - db = (DataBuffer)BufferedImageGraphics.bufferedImages.get( b ); + raster = (Raster)BufferedImageGraphics.bufferedImages.get( b ); else - db = b.getRaster().getDataBuffer(); + raster = b.getRaster(); invertedXform.getMatrix(i2u); @@ -1288,9 +1288,9 @@ public abstract class CairoGraphics2D extends Graphics2D if (comp instanceof AlphaComposite) alpha = ((AlphaComposite) comp).getAlpha(); - if(db instanceof CairoSurface) + if(raster instanceof CairoSurface) { - ((CairoSurface)db).drawSurface(nativePointer, i2u, alpha); + ((CairoSurface)raster).drawSurface(nativePointer, i2u, alpha); updateColor(); return true; } diff --git a/gnu/java/awt/peer/gtk/CairoSurface.java b/gnu/java/awt/peer/gtk/CairoSurface.java index 78bc1e02d..3bf9a9ccf 100644 --- a/gnu/java/awt/peer/gtk/CairoSurface.java +++ b/gnu/java/awt/peer/gtk/CairoSurface.java @@ -46,6 +46,7 @@ import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; +import java.awt.image.SinglePixelPackedSampleModel; import java.nio.ByteOrder; import java.util.Hashtable; @@ -54,7 +55,7 @@ import java.util.Hashtable; * * @author Sven de Marothy */ -public class CairoSurface extends DataBuffer +public class CairoSurface extends WritableRaster { int width = -1, height = -1; @@ -68,7 +69,6 @@ public class CairoSurface extends DataBuffer */ long bufferPointer; - static ColorModel nativeModel = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, @@ -138,18 +138,22 @@ public class CairoSurface extends DataBuffer */ public CairoSurface(int width, int height) { - super(DataBuffer.TYPE_INT, width * height); + super( new SinglePixelPackedSampleModel + (DataBuffer.TYPE_INT, width, height, + new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }), + null, new Point(0, 0) ); if(width <= 0 || height <= 0) throw new IllegalArgumentException("Image must be at least 1x1 pixels."); - + this.width = width; this.height = height; - create(width, height, width); if(surfacePointer == 0 || bufferPointer == 0) throw new Error("Could not allocate bitmap."); + + dataBuffer = new CairoDataBuffer(); } /** @@ -158,18 +162,7 @@ public class CairoSurface extends DataBuffer */ CairoSurface(GtkImage image) { - super(DataBuffer.TYPE_INT, image.width * image.height); - - if(image.width <= 0 || image.height <= 0) - throw new IllegalArgumentException("Image must be at least 1x1 pixels."); - - width = image.width; - height = image.height; - - create(width, height, width); - - if(surfacePointer == 0 || bufferPointer == 0) - throw new Error("Could not allocate bitmap."); + this(image.width, image.height); // Copy the pixel data from the GtkImage. int[] data = image.getPixels(); @@ -260,32 +253,35 @@ public class CairoSurface extends DataBuffer */ public static BufferedImage getBufferedImage(CairoSurface surface) { - WritableRaster raster = Raster.createPackedRaster - (surface, surface.width, surface.height, surface.width, - new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, - new Point(0,0)); - - return new BufferedImage(nativeModel, raster, true, new Hashtable()); + return new BufferedImage(nativeModel, surface, true, new Hashtable()); } - /** - * DataBank.getElem implementation - */ - public int getElem(int bank, int i) + private class CairoDataBuffer extends DataBuffer { - if(bank != 0 || i < 0 || i >= width*height) - throw new IndexOutOfBoundsException(i+" size: "+width*height); - return nativeGetElem(bufferPointer, i); - } + public CairoDataBuffer() + { + super(DataBuffer.TYPE_INT, width * height); + } + + /** + * DataBuffer.getElem implementation + */ + public int getElem(int bank, int i) + { + if(bank != 0 || i < 0 || i >= width * height) + throw new IndexOutOfBoundsException(i+" size: "+width * height); + return nativeGetElem(bufferPointer, i); + } - /** - * DataBank.setElem implementation - */ - public void setElem(int bank, int i, int val) - { - if(bank != 0 || i < 0 || i >= width*height) - throw new IndexOutOfBoundsException(i+" size: "+width*height); - nativeSetElem(bufferPointer, i, val); + /** + * DataBuffer.setElem implementation + */ + public void setElem(int bank, int i, int val) + { + if(bank != 0 || i < 0 || i >= width*height) + throw new IndexOutOfBoundsException(i+" size: "+width * height); + nativeSetElem(bufferPointer, i, val); + } } /** diff --git a/gnu/java/awt/peer/gtk/ComponentGraphics.java b/gnu/java/awt/peer/gtk/ComponentGraphics.java index ffa78e9c9..d9d173118 100644 --- a/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -71,32 +71,6 @@ public class ComponentGraphics extends CairoGraphics2D private static ThreadLocal hasLock = new ThreadLocal(); private static Integer ONE = Integer.valueOf(1); - private void lock() - { - Integer i = (Integer) hasLock.get(); - if (i == null) - { - start_gdk_drawing(); - hasLock.set(ONE); - } - else - hasLock.set(Integer.valueOf(i.intValue() + 1)); - } - - private void unlock() - { - Integer i = (Integer) hasLock.get(); - if (i == null) - throw new IllegalStateException(); - if (i == ONE) - { - hasLock.set(null); - end_gdk_drawing(); - } - else - hasLock.set(Integer.valueOf(i.intValue() - 1)); - } - ComponentGraphics() { } @@ -128,6 +102,32 @@ public class ComponentGraphics extends CairoGraphics2D */ private native long initState(GtkComponentPeer component); + private void lock() + { + Integer i = (Integer) hasLock.get(); + if (i == null) + { + start_gdk_drawing(); + hasLock.set(ONE); + } + else + hasLock.set(Integer.valueOf(i.intValue() + 1)); + } + + private void unlock() + { + Integer i = (Integer) hasLock.get(); + if (i == null) + throw new IllegalStateException(); + if (i == ONE) + { + hasLock.set(null); + end_gdk_drawing(); + } + else + hasLock.set(Integer.valueOf(i.intValue() - 1)); + } + /** * Destroys the component surface and calls dispose on the cairo * graphics2d to destroy any super class resources. diff --git a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index e095c7dad..db725b697 100644 --- a/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -44,7 +44,7 @@ import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; import java.awt.image.BufferedImage; -import java.awt.image.DataBuffer; +import java.awt.image.Raster; import java.util.Locale; public class GdkGraphicsEnvironment extends GraphicsEnvironment @@ -103,9 +103,9 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment public Graphics2D createGraphics (BufferedImage image) { - DataBuffer db = image.getRaster().getDataBuffer(); - if(db instanceof CairoSurface) - return ((CairoSurface)db).getGraphics(); + Raster raster = image.getRaster(); + if(raster instanceof CairoSurface) + return ((CairoSurface)raster).getGraphics(); return new BufferedImageGraphics( image ); } diff --git a/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/gnu/java/awt/peer/gtk/GtkChoicePeer.java index ed7dc74d2..d866cefd3 100644 --- a/gnu/java/awt/peer/gtk/GtkChoicePeer.java +++ b/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -39,12 +39,15 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Choice; +import java.awt.AWTEvent; import java.awt.event.ItemEvent; import java.awt.peer.ChoicePeer; public class GtkChoicePeer extends GtkComponentPeer implements ChoicePeer { + private int selected; + public GtkChoicePeer (Choice c) { super (c); @@ -52,75 +55,53 @@ public class GtkChoicePeer extends GtkComponentPeer int count = c.getItemCount (); if (count > 0) { - String items[] = new String[count]; for (int i = 0; i < count; i++) - items[i] = c.getItem (i); - - append (items); - } + add( c.getItem(i), i ); - int selected = c.getSelectedIndex(); - if (selected >= 0) - select(selected); + selected = c.getSelectedIndex(); + if( selected >= 0 ) + select( selected ); + } + else + selected = -1; } native void create (); - native void append (String items[]); native int nativeGetSelected (); - native void nativeAdd (String item, int index); - native void nativeRemove (int index); - native void nativeRemoveAll (); native void connectSignals (); native void selectNative (int position); + native void selectNativeUnlocked (int position); + public native void add (String item, int index); + + native void nativeRemove(int index); + + native void nativeRemoveAll(); + public void select (int position) { - if (Thread.currentThread() == GtkToolkit.mainThread) + if (Thread.currentThread() == GtkMainThread.mainThread) selectNativeUnlocked (position); else selectNative (position); } - public void add (String item, int index) + public void remove( int index ) { - int before = nativeGetSelected(); - - nativeAdd (item, index); - - /* Generate an ItemEvent if we added the first one or - if we inserted at or before the currently selected item. */ - if ((before < 0) || (before >= index)) - { - // Must set our state before notifying listeners - ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0)); - postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED); - } + // Ensure the triggering of an event when removing item zero if zero is the + // selected item, even though the selected index doesn't change. + if( index == 0 && selected == 0 ) + selected = -1; + nativeRemove( index ); } - public void remove (int index) - { - int before = nativeGetSelected(); - int after; - - nativeRemove (index); - after = nativeGetSelected(); - - /* Generate an ItemEvent if we are removing the currently selected item - and there are at least one item left. */ - if ((before == index) && (after >= 0)) - { - // Must set our state before notifying listeners - ((Choice) awtComponent).select (((Choice) awtComponent).getItem (0)); - postItemEvent (((Choice) awtComponent).getItem (0), ItemEvent.SELECTED); - } - } - - public void removeAll () + public void removeAll() { + selected = -1; // we do not want to trigger a select event here. nativeRemoveAll(); } @@ -129,8 +110,34 @@ public class GtkChoicePeer extends GtkComponentPeer add (item, position); } - protected void postChoiceItemEvent (String label, int stateChange) + /** + * Callback from the native side on an item-select event, + * which posts an event. The event is only posted if it represents an actual + * change. Selected is set to the peer's state initially, so that the + * first call to select(int) from the constructor will not trigger an event. + * (it should not) + */ + protected void postChoiceItemEvent ( int index ) + { + if( selected != index ) + { + selected = index; + postItemEvent (((Choice) awtComponent).getItem( selected ), + ItemEvent.SELECTED); + } + } + + /** + * Catches the event and calls Choice.select() if the component state + * needs updating. + */ + public void handleEvent (AWTEvent event) { - postItemEvent (label, stateChange); + super.handleEvent( event ); + if( event instanceof ItemEvent ) + if( ((ItemEvent)event).getItemSelectable() == awtComponent && + ((ItemEvent)event).getStateChange() == ItemEvent.SELECTED ) + ((Choice)awtComponent).select( selected ); } } + diff --git a/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/gnu/java/awt/peer/gtk/GtkComponentPeer.java index c11c45e20..f96033e56 100644 --- a/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -514,7 +514,7 @@ public class GtkComponentPeer extends GtkGenericPeer y = 0; } - if (Thread.currentThread() == GtkToolkit.mainThread) + if (Thread.currentThread() == GtkMainThread.mainThread) gtkWidgetSetCursorUnlocked(cursor.getType(), image, x, y); else gtkWidgetSetCursor(cursor.getType(), image, x, y); @@ -562,7 +562,7 @@ public class GtkComponentPeer extends GtkGenericPeer b = (bounds.width > 0) && (bounds.height > 0); } - if (Thread.currentThread() == GtkToolkit.mainThread) + if (Thread.currentThread() == GtkMainThread.mainThread) setVisibleNativeUnlocked (b); else setVisibleNative (b); diff --git a/gnu/java/awt/peer/gtk/GtkMainThread.java b/gnu/java/awt/peer/gtk/GtkMainThread.java new file mode 100644 index 000000000..19d3f1d0b --- /dev/null +++ b/gnu/java/awt/peer/gtk/GtkMainThread.java @@ -0,0 +1,97 @@ +/* GtkMainThread.java -- Wrapper for the GTK main thread, and some utilities. + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.awt.peer.gtk; + +public class GtkMainThread extends Thread +{ + /** Count of the number of open windows */ + private static int numberOfWindows = 0; + + /** Lock for the above */ + private static Object nWindowsLock = new Object(); + + /** The main thread instance (singleton) */ + public static GtkMainThread mainThread; + + /** Constructs a main thread */ + private GtkMainThread() + { + super("GTK main thread"); + } + + public void run () + { + GtkToolkit.gtkMain (); + } + + private static void startMainThread() + { + if( mainThread == null ) + { + mainThread = new GtkMainThread(); + mainThread.start(); + } + } + + private static void endMainThread() + { + if( mainThread != null ) + GtkToolkit.gtkQuit(); + } + + public static void createWindow() + { + synchronized( nWindowsLock ) + { + if( numberOfWindows == 0 ) + startMainThread(); + numberOfWindows++; + } + } + + public static void destroyWindow() + { + synchronized( nWindowsLock ) + { + numberOfWindows--; + if( numberOfWindows == 0 ) + endMainThread(); + } + } +}
\ No newline at end of file diff --git a/gnu/java/awt/peer/gtk/GtkToolkit.java b/gnu/java/awt/peer/gtk/GtkToolkit.java index 6aa87fc2e..3f87ca6e6 100644 --- a/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -131,37 +131,30 @@ import javax.imageio.spi.IIORegistry; public class GtkToolkit extends gnu.java.awt.ClasspathToolkit { - Hashtable containers = new Hashtable(); - static EventQueue q; - static Thread mainThread; + private static EventQueue q; static native void gtkInit(int portableNativeSync); + static native void gtkMain(); + + static native void gtkQuit(); + static { System.loadLibrary("gtkpeer"); - + int portableNativeSync; String portNatSyncProp = System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); - + if (portNatSyncProp == null) portableNativeSync = -1; // unset else if (Boolean.valueOf(portNatSyncProp).booleanValue()) portableNativeSync = 1; // true else portableNativeSync = 0; // false - + gtkInit(portableNativeSync); - - mainThread = new Thread ("GTK main thread") - { - public void run () - { - gtkMain (); - } - }; - mainThread.start (); } public GtkToolkit () @@ -169,6 +162,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit } public native void beep(); + private native void getScreenSizeDimensions(int[] xy); public int checkImage (Image image, int width, int height, @@ -462,6 +456,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit protected DialogPeer createDialog (Dialog d) { + GtkMainThread.createWindow(); return new GtkDialogPeer (d); } @@ -472,6 +467,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit protected FramePeer createFrame (Frame f) { + GtkMainThread.createWindow(); return new GtkFramePeer (f); } @@ -532,11 +528,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit protected WindowPeer createWindow (Window w) { + GtkMainThread.createWindow(); return new GtkWindowPeer (w); } public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w) { + GtkMainThread.createWindow(); return new GtkEmbeddedWindowPeer (w); } @@ -661,8 +659,6 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit GdkPixbufDecoder.registerSpis(reg); } - public static native void gtkMain(); - protected MouseInfoPeer getMouseInfoPeer() { return new GtkMouseInfoPeer(); diff --git a/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 866d9c881..1f340611e 100644 --- a/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -75,6 +75,12 @@ public class GtkWindowPeer extends GtkContainerPeer native boolean gtkWindowHasFocus(); native void realize (); + public void dispose() + { + super.dispose(); + GtkMainThread.destroyWindow(); + } + /** Returns the cached width of the AWT window component. */ int getX () { diff --git a/gnu/java/lang/management/BeanImpl.java b/gnu/java/lang/management/BeanImpl.java index 24572a25d..529ee5896 100644 --- a/gnu/java/lang/management/BeanImpl.java +++ b/gnu/java/lang/management/BeanImpl.java @@ -39,9 +39,50 @@ package gnu.java.lang.management; import java.lang.management.ManagementPermission; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.TypeVariable; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.management.AttributeNotFoundException; +import javax.management.MBeanAttributeInfo; +import javax.management.MBeanConstructorInfo; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.MBeanInfo; import javax.management.NotCompliantMBeanException; +import javax.management.ReflectionException; import javax.management.StandardMBean; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.CompositeDataSupport; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanAttributeInfoSupport; +import javax.management.openmbean.OpenMBeanConstructorInfo; +import javax.management.openmbean.OpenMBeanConstructorInfoSupport; +import javax.management.openmbean.OpenMBeanInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenMBeanOperationInfo; +import javax.management.openmbean.OpenMBeanOperationInfoSupport; +import javax.management.openmbean.OpenMBeanParameterInfo; +import javax.management.openmbean.OpenMBeanParameterInfoSupport; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import javax.management.openmbean.TabularData; +import javax.management.openmbean.TabularDataSupport; +import javax.management.openmbean.TabularType; + /** * A common superclass for bean implementations. * @@ -51,7 +92,12 @@ import javax.management.StandardMBean; public class BeanImpl extends StandardMBean { - + + /** + * Cached open bean information. + */ + private OpenMBeanInfo openInfo; + /** * Constructs a new <code>BeanImpl</code>. * @@ -67,6 +113,71 @@ public class BeanImpl super(iface); } + protected void cacheMBeanInfo(MBeanInfo info) + { + if (info == null) + return; + try + { + MBeanAttributeInfo[] oldA = info.getAttributes(); + OpenMBeanAttributeInfo[] attribs = + new OpenMBeanAttributeInfoSupport[oldA.length]; + for (int a = 0; a < oldA.length; ++a) + { + OpenMBeanParameterInfo param = translate(oldA[a].getType()); + if (param.getMinValue() == null) + { + Object[] lv; + if (param.getLegalValues() == null) + lv = null; + else + lv = param.getLegalValues().toArray(); + attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(), + oldA[a].getDescription(), + param.getOpenType(), + oldA[a].isReadable(), + oldA[a].isWritable(), + oldA[a].isIs(), + param.getDefaultValue(), + lv); + } + else + attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(), + oldA[a].getDescription(), + param.getOpenType(), + oldA[a].isReadable(), + oldA[a].isWritable(), + oldA[a].isIs(), + param.getDefaultValue(), + param.getMinValue(), + param.getMaxValue()); + } + MBeanConstructorInfo[] oldC = info.getConstructors(); + OpenMBeanConstructorInfo[] cons = new OpenMBeanConstructorInfoSupport[oldC.length]; + for (int a = 0; a < oldC.length; ++a) + cons[a] = + new OpenMBeanConstructorInfoSupport(oldC[a].getName(), + oldC[a].getDescription(), + translateSignature(oldC[a].getSignature())); + MBeanOperationInfo[] oldO = info.getOperations(); + OpenMBeanOperationInfo[] ops = new OpenMBeanOperationInfoSupport[oldO.length]; + for (int a = 0; a < oldO.length; ++a) + ops[a] = + new OpenMBeanOperationInfoSupport(oldO[a].getName(), + oldO[a].getDescription(), + translateSignature(oldO[a].getSignature()), + translate(oldO[a].getReturnType()).getOpenType(), + oldO[a].getImpact()); + openInfo = new OpenMBeanInfoSupport(info.getClassName(), info.getDescription(), + attribs, cons, ops, info.getNotifications()); + } + catch (OpenDataException e) + { + throw (InternalError) (new InternalError("A problem occurred creating the open type " + + "descriptors.").initCause(e)); + } + } + protected void checkMonitorPermissions() { SecurityManager sm = System.getSecurityManager(); @@ -81,4 +192,335 @@ public class BeanImpl sm.checkPermission(new ManagementPermission("control")); } + public Object getAttribute(String attribute) + throws AttributeNotFoundException, MBeanException, + ReflectionException + { + Object value = super.getAttribute(attribute); + if (value instanceof Enum) + return ((Enum) value).name(); + Class vClass = value.getClass(); + if (vClass.isArray()) + return value; + String cName = vClass.getName(); + String[] allowedTypes = OpenType.ALLOWED_CLASSNAMES; + for (int a = 0; a < allowedTypes.length; ++a) + if (cName.equals(allowedTypes[a])) + return value; + if (value instanceof List) + { + List l = (List) value; + Class e = null; + TypeVariable[] vars = vClass.getTypeParameters(); + for (int a = 0; a < vars.length; ++a) + if (vars[a].getName().equals("E")) + e = (Class) vars[a].getGenericDeclaration(); + if (e == null) + e = Object.class; + Object[] array = (Object[]) Array.newInstance(e, l.size()); + return l.toArray(array); + } + OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo(); + OpenMBeanAttributeInfo[] attribs = + (OpenMBeanAttributeInfo[]) info.getAttributes(); + OpenType type = null; + for (int a = 0; a < attribs.length; ++a) + if (attribs[a].getName().equals("attribute")) + type = attribs[a].getOpenType(); + if (value instanceof Map) + { + TabularType ttype = (TabularType) type; + TabularData data = new TabularDataSupport(ttype); + Iterator it = ((Map) value).entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry entry = (Map.Entry) it.next(); + try + { + data.put(new CompositeDataSupport(ttype.getRowType(), + new String[] { + "key", + "value" + }, + new Object[] { + entry.getKey(), + entry.getValue() + })); + } + catch (OpenDataException e) + { + throw (InternalError) (new InternalError("A problem occurred " + + "converting the map " + + "to a composite data " + + "structure.").initCause(e)); + } + } + return data; + } + CompositeType cType = (CompositeType) type; + Set names = cType.keySet(); + Iterator it = names.iterator(); + List values = new ArrayList(names.size()); + while (it.hasNext()) + { + String field = (String) it.next(); + Method getter = null; + try + { + getter = vClass.getMethod("get" + field, null); + } + catch (NoSuchMethodException e) + { + /* Ignored; the type tells us it's there. */ + } + try + { + values.add(getter.invoke(value, null)); + } + catch (IllegalAccessException e) + { + throw new ReflectionException(e, "Failed to retrieve " + field); + } + catch (IllegalArgumentException e) + { + throw new ReflectionException(e, "Failed to retrieve " + field); + } + catch (InvocationTargetException e) + { + throw new MBeanException((Exception) e.getCause(), + "The getter of " + field + + " threw an exception"); + } + } + try + { + return new CompositeDataSupport(cType, + (String[]) + names.toArray(new String[names.size()]), + values.toArray()); + } + catch (OpenDataException e) + { + throw (InternalError) (new InternalError("A problem occurred " + + "converting the value " + + "to a composite data " + + "structure.").initCause(e)); + } + } + + protected MBeanInfo getCachedMBeanInfo() + { + return (MBeanInfo) openInfo; + } + + public MBeanInfo getMBeanInfo() + { + super.getMBeanInfo(); + return getCachedMBeanInfo(); + } + + private OpenType getTypeFromClass(Class c) + throws OpenDataException + { + return translate(c.getName()).getOpenType(); + } + + private OpenMBeanParameterInfo[] translateSignature(MBeanParameterInfo[] oldS) + throws OpenDataException + { + OpenMBeanParameterInfo[] sig = new OpenMBeanParameterInfoSupport[oldS.length]; + for (int a = 0; a < oldS.length; ++a) + { + OpenMBeanParameterInfo param = translate(oldS[a].getType()); + if (param.getMinValue() == null) + { + Object[] lv; + if (param.getLegalValues() == null) + lv = null; + else + lv = param.getLegalValues().toArray(); + sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(), + oldS[a].getDescription(), + param.getOpenType(), + param.getDefaultValue(), + lv); + } + else + sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(), + oldS[a].getDescription(), + param.getOpenType(), + param.getDefaultValue(), + param.getMinValue(), + param.getMaxValue()); + } + return sig; + } + + private OpenMBeanParameterInfo translate(String type) + throws OpenDataException + { + if (type.equals("boolean") || type.equals(Boolean.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.BOOLEAN, + null, + new Object[] { + Boolean.TRUE, + Boolean.FALSE + }); + if (type.equals("byte") || type.equals(Byte.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.BYTE, + null, + Byte.valueOf(Byte.MIN_VALUE), + Byte.valueOf(Byte.MAX_VALUE)); + if (type.equals("char") || type.equals(Character.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.CHARACTER, + null, + Character.valueOf(Character.MIN_VALUE), + Character.valueOf(Character.MAX_VALUE)); + if (type.equals("double") || type.equals(Double.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.DOUBLE, + null, + Double.valueOf(Double.MIN_VALUE), + Double.valueOf(Double.MAX_VALUE)); + if (type.equals("float") || type.equals(Float.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.FLOAT, + null, + Float.valueOf(Float.MIN_VALUE), + Float.valueOf(Float.MAX_VALUE)); + if (type.equals("int") || type.equals(Integer.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.INTEGER, + null, + Integer.valueOf(Integer.MIN_VALUE), + Integer.valueOf(Integer.MAX_VALUE)); + if (type.equals("long") || type.equals(Long.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.LONG, + null, + Long.valueOf(Long.MIN_VALUE), + Long.valueOf(Long.MAX_VALUE)); + if (type.equals("short") || type.equals(Short.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.SHORT, + null, + Short.valueOf(Short.MIN_VALUE), + Short.valueOf(Short.MAX_VALUE)); + if (type.equals(String.class.getName())) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.STRING); + if (type.equals("void")) + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.VOID); + Class c; + try + { + c = Class.forName(type); + } + catch (ClassNotFoundException e) + { + throw new InternalError("The class for a type used in a management bean " + + "could not be loaded."); + } + if (c.isEnum()) + { + Object[] values = c.getEnumConstants(); + String[] names = new String[values.length]; + for (int a = 0; a < values.length; ++a) + names[a] = values[a].toString(); + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + SimpleType.STRING, + null, + (Object[]) names); + } + try + { + c.getMethod("from", new Class[] { CompositeData.class }); + Method[] methods = c.getMethods(); + List names = new ArrayList(); + List types = new ArrayList(); + for (int a = 0; a < methods.length; ++a) + { + String name = methods[a].getName(); + if (name.startsWith("get")) + { + names.add(name.substring(3)); + types.add(getTypeFromClass(methods[a].getReturnType())); + } + } + String[] fields = (String[]) names.toArray(); + CompositeType ctype = new CompositeType(c.getName(), c.getName(), + fields, fields, + (OpenType[]) types.toArray()); + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + ctype); + } + catch (NoSuchMethodException e) + { + /* Ignored; we expect this if this isn't a from(CompositeData) class */ + } + if (Map.class.isAssignableFrom(c)) + { + OpenType k = SimpleType.VOID; + OpenType v = SimpleType.VOID; + TypeVariable[] vars = c.getTypeParameters(); + for (int a = 0; a < vars.length; ++a) + { + if (vars[a].getName().equals("K")) + k = getTypeFromClass((Class) vars[a].getGenericDeclaration()); + if (vars[a].getName().equals("V")) + v = getTypeFromClass((Class) vars[a].getGenericDeclaration()); + } + CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(), + new String[] { "key", "value" }, + new String[] { "Map key", "Map value"}, + new OpenType[] { k, v}); + TabularType ttype = new TabularType(c.getName(), c.getName(), ctype, + new String[] { "key" }); + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + ttype); + } + if (List.class.isAssignableFrom(c)) + { + OpenType e = SimpleType.VOID; + TypeVariable[] vars = c.getTypeParameters(); + for (int a = 0; a < vars.length; ++a) + { + if (vars[a].getName().equals("E")) + e = getTypeFromClass((Class) vars[a].getGenericDeclaration()); + } + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + new ArrayType(1, e) + ); + } + if (c.isArray()) + { + int depth; + for (depth = 0; c.getName().charAt(depth) == '['; ++depth); + OpenType ot = getTypeFromClass(c.getComponentType()); + return new OpenMBeanParameterInfoSupport("TransParam", + "Translated parameter", + new ArrayType(depth, ot) + ); + } + throw new InternalError("The type used does not have an open type translation."); + } + } diff --git a/gnu/java/net/protocol/http/Request.java b/gnu/java/net/protocol/http/Request.java index e15ec4182..cd9d7ea44 100644 --- a/gnu/java/net/protocol/http/Request.java +++ b/gnu/java/net/protocol/http/Request.java @@ -419,13 +419,16 @@ public class Request switch (code) { case 100: + break; case 204: case 205: case 304: + body = createResponseBodyStream(responseHeaders, majorVersion, + minorVersion, in, false); break; default: body = createResponseBodyStream(responseHeaders, majorVersion, - minorVersion, in); + minorVersion, in, true); } // Construct response @@ -453,7 +456,8 @@ public class Request private InputStream createResponseBodyStream(Headers responseHeaders, int majorVersion, int minorVersion, - InputStream in) + InputStream in, + boolean mayHaveBody) throws IOException { long contentLength = -1; @@ -466,7 +470,12 @@ public class Request (majorVersion == 1 && minorVersion == 0); String transferCoding = responseHeaders.getValue("Transfer-Encoding"); - if ("chunked".equalsIgnoreCase(transferCoding)) + if ("HEAD".equals(method) || !mayHaveBody) + { + // Special case no body. + in = new LimitedLengthInputStream(in, 0, true, connection, doClose); + } + else if ("chunked".equalsIgnoreCase(transferCoding)) { in = new LimitedLengthInputStream(in, -1, false, connection, doClose); |